]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
Add pre_reload splitter to detect fp min/max pattern.
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2023 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12 ;;
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
21 ;;
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
24 ;;
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;; otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;; delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
66
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
69 UNSPEC_GOT
70 UNSPEC_GOTOFF
71 UNSPEC_GOTPCREL
72 UNSPEC_GOTTPOFF
73 UNSPEC_TPOFF
74 UNSPEC_NTPOFF
75 UNSPEC_DTPOFF
76 UNSPEC_GOTNTPOFF
77 UNSPEC_INDNTPOFF
78 UNSPEC_PLTOFF
79 UNSPEC_MACHOPIC_OFFSET
80 UNSPEC_PCREL
81 UNSPEC_SIZEOF
82
83 ;; Prologue support
84 UNSPEC_STACK_ALLOC
85 UNSPEC_SET_GOT
86 UNSPEC_SET_RIP
87 UNSPEC_SET_GOT_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
89 UNSPEC_PROBE_STACK
90
91 ;; TLS support
92 UNSPEC_TP
93 UNSPEC_TLS_GD
94 UNSPEC_TLS_LD_BASE
95 UNSPEC_TLSDESC
96 UNSPEC_TLS_IE_SUN
97
98 ;; Other random patterns
99 UNSPEC_SCAS
100 UNSPEC_FNSTSW
101 UNSPEC_SAHF
102 UNSPEC_NOTRAP
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_REP
106 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_TRUNC_NOOP
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_PAUSE
110 UNSPEC_LEA_ADDR
111 UNSPEC_XBEGIN_ABORT
112 UNSPEC_STOS
113 UNSPEC_PEEPSIB
114 UNSPEC_INSN_FALSE_DEP
115 UNSPEC_SBB
116 UNSPEC_CC_NE
117 UNSPEC_STC
118
119 ;; For SSE/MMX support:
120 UNSPEC_FIX_NOTRUNC
121 UNSPEC_MASKMOV
122 UNSPEC_MOVCC_MASK
123 UNSPEC_MOVMSK
124 UNSPEC_INSERTPS
125 UNSPEC_BLENDV
126 UNSPEC_PSHUFB
127 UNSPEC_XOP_PERMUTE
128 UNSPEC_RCP
129 UNSPEC_RSQRT
130 UNSPEC_PSADBW
131
132 ;; Different from generic us_truncate RTX
133 ;; as it does unsigned saturation of signed source.
134 UNSPEC_US_TRUNCATE
135
136 ;; For AVX/AVX512F support
137 UNSPEC_SCALEF
138 UNSPEC_PCMP
139 UNSPEC_CVTBFSF
140
141 ;; Generic math support
142 UNSPEC_IEEE_MIN ; not commutative
143 UNSPEC_IEEE_MAX ; not commutative
144
145 ;; x87 Floating point
146 UNSPEC_SIN
147 UNSPEC_COS
148 UNSPEC_FPATAN
149 UNSPEC_FYL2X
150 UNSPEC_FYL2XP1
151 UNSPEC_FRNDINT
152 UNSPEC_FIST
153 UNSPEC_F2XM1
154 UNSPEC_TAN
155 UNSPEC_FXAM
156
157 ;; x87 Rounding
158 UNSPEC_FRNDINT_ROUNDEVEN
159 UNSPEC_FRNDINT_FLOOR
160 UNSPEC_FRNDINT_CEIL
161 UNSPEC_FRNDINT_TRUNC
162 UNSPEC_FIST_FLOOR
163 UNSPEC_FIST_CEIL
164
165 ;; x87 Double output FP
166 UNSPEC_SINCOS_COS
167 UNSPEC_SINCOS_SIN
168 UNSPEC_XTRACT_FRACT
169 UNSPEC_XTRACT_EXP
170 UNSPEC_FSCALE_FRACT
171 UNSPEC_FSCALE_EXP
172 UNSPEC_FPREM_F
173 UNSPEC_FPREM_U
174 UNSPEC_FPREM1_F
175 UNSPEC_FPREM1_U
176
177 UNSPEC_C2_FLAG
178 UNSPEC_FXAM_MEM
179
180 ;; SSP patterns
181 UNSPEC_SP_SET
182 UNSPEC_SP_TEST
183
184 ;; For ROUND support
185 UNSPEC_ROUND
186
187 ;; For CRC32 support
188 UNSPEC_CRC32
189
190 ;; For LZCNT suppoprt
191 UNSPEC_LZCNT
192
193 ;; For BMI support
194 UNSPEC_TZCNT
195 UNSPEC_BEXTR
196
197 ;; For BMI2 support
198 UNSPEC_PDEP
199 UNSPEC_PEXT
200
201 ;; IRET support
202 UNSPEC_INTERRUPT_RETURN
203
204 ;; For MOVDIRI and MOVDIR64B support
205 UNSPEC_MOVDIRI
206 UNSPEC_MOVDIR64B
207
208 ;; For insn_callee_abi:
209 UNSPEC_CALLEE_ABI
210
211 ])
212
213 (define_c_enum "unspecv" [
214 UNSPECV_UD2
215 UNSPECV_BLOCKAGE
216 UNSPECV_STACK_PROBE
217 UNSPECV_PROBE_STACK_RANGE
218 UNSPECV_ALIGN
219 UNSPECV_PROLOGUE_USE
220 UNSPECV_SPLIT_STACK_RETURN
221 UNSPECV_CLD
222 UNSPECV_NOPS
223 UNSPECV_RDTSC
224 UNSPECV_RDTSCP
225 UNSPECV_RDPMC
226 UNSPECV_LLWP_INTRINSIC
227 UNSPECV_SLWP_INTRINSIC
228 UNSPECV_LWPVAL_INTRINSIC
229 UNSPECV_LWPINS_INTRINSIC
230 UNSPECV_RDFSBASE
231 UNSPECV_RDGSBASE
232 UNSPECV_WRFSBASE
233 UNSPECV_WRGSBASE
234 UNSPECV_FXSAVE
235 UNSPECV_FXRSTOR
236 UNSPECV_FXSAVE64
237 UNSPECV_FXRSTOR64
238 UNSPECV_XSAVE
239 UNSPECV_XRSTOR
240 UNSPECV_XSAVE64
241 UNSPECV_XRSTOR64
242 UNSPECV_XSAVEOPT
243 UNSPECV_XSAVEOPT64
244 UNSPECV_XSAVES
245 UNSPECV_XRSTORS
246 UNSPECV_XSAVES64
247 UNSPECV_XRSTORS64
248 UNSPECV_XSAVEC
249 UNSPECV_XSAVEC64
250 UNSPECV_XGETBV
251 UNSPECV_XSETBV
252 UNSPECV_WBINVD
253 UNSPECV_WBNOINVD
254
255 ;; For atomic compound assignments.
256 UNSPECV_FNSTENV
257 UNSPECV_FLDENV
258 UNSPECV_FNSTSW
259 UNSPECV_FNCLEX
260
261 ;; For RDRAND support
262 UNSPECV_RDRAND
263
264 ;; For RDSEED support
265 UNSPECV_RDSEED
266
267 ;; For RTM support
268 UNSPECV_XBEGIN
269 UNSPECV_XEND
270 UNSPECV_XABORT
271 UNSPECV_XTEST
272
273 UNSPECV_NLGR
274
275 ;; For CLWB support
276 UNSPECV_CLWB
277
278 ;; For CLFLUSHOPT support
279 UNSPECV_CLFLUSHOPT
280
281 ;; For MONITORX and MWAITX support
282 UNSPECV_MONITORX
283 UNSPECV_MWAITX
284
285 ;; For CLZERO support
286 UNSPECV_CLZERO
287
288 ;; For RDPKRU and WRPKRU support
289 UNSPECV_PKU
290
291 ;; For RDPID support
292 UNSPECV_RDPID
293
294 ;; For CET support
295 UNSPECV_NOP_ENDBR
296 UNSPECV_NOP_RDSSP
297 UNSPECV_INCSSP
298 UNSPECV_SAVEPREVSSP
299 UNSPECV_RSTORSSP
300 UNSPECV_WRSS
301 UNSPECV_WRUSS
302 UNSPECV_SETSSBSY
303 UNSPECV_CLRSSBSY
304
305 ;; For TSXLDTRK support
306 UNSPECV_XSUSLDTRK
307 UNSPECV_XRESLDTRK
308
309 ;; For WAITPKG support
310 UNSPECV_UMWAIT
311 UNSPECV_UMONITOR
312 UNSPECV_TPAUSE
313
314 ;; For UINTR support
315 UNSPECV_CLUI
316 UNSPECV_STUI
317 UNSPECV_TESTUI
318 UNSPECV_SENDUIPI
319
320 ;; For CLDEMOTE support
321 UNSPECV_CLDEMOTE
322
323 ;; For Speculation Barrier support
324 UNSPECV_SPECULATION_BARRIER
325
326 UNSPECV_PTWRITE
327
328 ;; For ENQCMD and ENQCMDS support
329 UNSPECV_ENQCMD
330 UNSPECV_ENQCMDS
331
332 ;; For SERIALIZE support
333 UNSPECV_SERIALIZE
334
335 ;; For patchable area support
336 UNSPECV_PATCHABLE_AREA
337
338 ;; For HRESET support
339 UNSPECV_HRESET
340
341 ;; For PREFETCHI support
342 UNSPECV_PREFETCHI
343 ])
344
345 ;; Constants to represent rounding modes in the ROUND instruction
346 (define_constants
347 [(ROUND_ROUNDEVEN 0x0)
348 (ROUND_FLOOR 0x1)
349 (ROUND_CEIL 0x2)
350 (ROUND_TRUNC 0x3)
351 (ROUND_MXCSR 0x4)
352 (ROUND_NO_EXC 0x8)
353 ])
354
355 ;; Constants to represent AVX512F embeded rounding
356 (define_constants
357 [(ROUND_NEAREST_INT 0)
358 (ROUND_NEG_INF 1)
359 (ROUND_POS_INF 2)
360 (ROUND_ZERO 3)
361 (NO_ROUND 4)
362 (ROUND_SAE 8)
363 ])
364
365 ;; Constants to represent pcomtrue/pcomfalse variants
366 (define_constants
367 [(PCOM_FALSE 0)
368 (PCOM_TRUE 1)
369 (COM_FALSE_S 2)
370 (COM_FALSE_P 3)
371 (COM_TRUE_S 4)
372 (COM_TRUE_P 5)
373 ])
374
375 ;; Constants used in the XOP pperm instruction
376 (define_constants
377 [(PPERM_SRC 0x00) /* copy source */
378 (PPERM_INVERT 0x20) /* invert source */
379 (PPERM_REVERSE 0x40) /* bit reverse source */
380 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
381 (PPERM_ZERO 0x80) /* all 0's */
382 (PPERM_ONES 0xa0) /* all 1's */
383 (PPERM_SIGN 0xc0) /* propagate sign bit */
384 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
385 (PPERM_SRC1 0x00) /* use first source byte */
386 (PPERM_SRC2 0x10) /* use second source byte */
387 ])
388
389 ;; Registers by name.
390 (define_constants
391 [(AX_REG 0)
392 (DX_REG 1)
393 (CX_REG 2)
394 (BX_REG 3)
395 (SI_REG 4)
396 (DI_REG 5)
397 (BP_REG 6)
398 (SP_REG 7)
399 (ST0_REG 8)
400 (ST1_REG 9)
401 (ST2_REG 10)
402 (ST3_REG 11)
403 (ST4_REG 12)
404 (ST5_REG 13)
405 (ST6_REG 14)
406 (ST7_REG 15)
407 (ARGP_REG 16)
408 (FLAGS_REG 17)
409 (FPSR_REG 18)
410 (FRAME_REG 19)
411 (XMM0_REG 20)
412 (XMM1_REG 21)
413 (XMM2_REG 22)
414 (XMM3_REG 23)
415 (XMM4_REG 24)
416 (XMM5_REG 25)
417 (XMM6_REG 26)
418 (XMM7_REG 27)
419 (MM0_REG 28)
420 (MM1_REG 29)
421 (MM2_REG 30)
422 (MM3_REG 31)
423 (MM4_REG 32)
424 (MM5_REG 33)
425 (MM6_REG 34)
426 (MM7_REG 35)
427 (R8_REG 36)
428 (R9_REG 37)
429 (R10_REG 38)
430 (R11_REG 39)
431 (R12_REG 40)
432 (R13_REG 41)
433 (R14_REG 42)
434 (R15_REG 43)
435 (XMM8_REG 44)
436 (XMM9_REG 45)
437 (XMM10_REG 46)
438 (XMM11_REG 47)
439 (XMM12_REG 48)
440 (XMM13_REG 49)
441 (XMM14_REG 50)
442 (XMM15_REG 51)
443 (XMM16_REG 52)
444 (XMM17_REG 53)
445 (XMM18_REG 54)
446 (XMM19_REG 55)
447 (XMM20_REG 56)
448 (XMM21_REG 57)
449 (XMM22_REG 58)
450 (XMM23_REG 59)
451 (XMM24_REG 60)
452 (XMM25_REG 61)
453 (XMM26_REG 62)
454 (XMM27_REG 63)
455 (XMM28_REG 64)
456 (XMM29_REG 65)
457 (XMM30_REG 66)
458 (XMM31_REG 67)
459 (MASK0_REG 68)
460 (MASK1_REG 69)
461 (MASK2_REG 70)
462 (MASK3_REG 71)
463 (MASK4_REG 72)
464 (MASK5_REG 73)
465 (MASK6_REG 74)
466 (MASK7_REG 75)
467 (FIRST_PSEUDO_REG 76)
468 ])
469
470 ;; Insn callee abi index.
471 (define_constants
472 [(ABI_DEFAULT 0)
473 (ABI_VZEROUPPER 1)
474 (ABI_UNKNOWN 2)])
475
476 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
477 ;; from i386.cc.
478
479 ;; In C guard expressions, put expressions which may be compile-time
480 ;; constants first. This allows for better optimization. For
481 ;; example, write "TARGET_64BIT && reload_completed", not
482 ;; "reload_completed && TARGET_64BIT".
483
484 \f
485 ;; Processor type.
486 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
487 atom,slm,glm,haswell,generic,lujiazui,amdfam10,bdver1,
488 bdver2,bdver3,bdver4,btver2,znver1,znver2,znver3,znver4"
489 (const (symbol_ref "ix86_schedule")))
490
491 ;; A basic instruction type. Refinements due to arguments to be
492 ;; provided in other attributes.
493 (define_attr "type"
494 "other,multi,
495 alu,alu1,negnot,imov,imovx,lea,
496 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
497 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
498 push,pop,call,callv,leave,
499 str,bitmanip,
500 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
501 fxch,fistp,fisttp,frndint,
502 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
503 ssemul,sseimul,ssediv,sselog,sselog1,
504 sseishft,sseishft1,ssecmp,ssecomi,
505 ssecvt,ssecvt1,sseicvt,sseins,
506 sseshuf,sseshuf1,ssemuladd,sse4arg,
507 lwp,mskmov,msklog,
508 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
509 (const_string "other"))
510
511 ;; Main data type used by the insn
512 (define_attr "mode"
513 "unknown,none,QI,HI,SI,DI,TI,OI,XI,HF,BF,SF,DF,XF,TF,V32HF,V16HF,V8HF,
514 V16SF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,V8DF,V4HF,V4BF,V2HF,V2BF"
515 (const_string "unknown"))
516
517 ;; The CPU unit operations uses.
518 (define_attr "unit" "integer,i387,sse,mmx,unknown"
519 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
520 fxch,fistp,fisttp,frndint")
521 (const_string "i387")
522 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
523 ssemul,sseimul,ssediv,sselog,sselog1,
524 sseishft,sseishft1,ssecmp,ssecomi,
525 ssecvt,ssecvt1,sseicvt,sseins,
526 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
527 (const_string "sse")
528 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
529 (const_string "mmx")
530 (eq_attr "type" "other")
531 (const_string "unknown")]
532 (const_string "integer")))
533
534 ;; The (bounding maximum) length of an instruction immediate.
535 (define_attr "length_immediate" ""
536 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
537 bitmanip,imulx,msklog,mskmov")
538 (const_int 0)
539 (eq_attr "unit" "i387,sse,mmx")
540 (const_int 0)
541 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
542 rotate,rotatex,rotate1,imul,icmp,push,pop")
543 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
544 (eq_attr "type" "imov,test")
545 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
546 (eq_attr "type" "call")
547 (if_then_else (match_operand 0 "constant_call_address_operand")
548 (const_int 4)
549 (const_int 0))
550 (eq_attr "type" "callv")
551 (if_then_else (match_operand 1 "constant_call_address_operand")
552 (const_int 4)
553 (const_int 0))
554 ;; We don't know the size before shorten_branches. Expect
555 ;; the instruction to fit for better scheduling.
556 (eq_attr "type" "ibr")
557 (const_int 1)
558 ]
559 (symbol_ref "/* Update immediate_length and other attributes! */
560 gcc_unreachable (),1")))
561
562 ;; The (bounding maximum) length of an instruction address.
563 (define_attr "length_address" ""
564 (cond [(eq_attr "type" "str,other,multi,fxch")
565 (const_int 0)
566 (and (eq_attr "type" "call")
567 (match_operand 0 "constant_call_address_operand"))
568 (const_int 0)
569 (and (eq_attr "type" "callv")
570 (match_operand 1 "constant_call_address_operand"))
571 (const_int 0)
572 ]
573 (symbol_ref "ix86_attr_length_address_default (insn)")))
574
575 ;; Set when length prefix is used.
576 (define_attr "prefix_data16" ""
577 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
578 (const_int 0)
579 (eq_attr "mode" "HI")
580 (const_int 1)
581 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
582 (const_int 1)
583 ]
584 (const_int 0)))
585
586 ;; Set when string REP prefix is used.
587 (define_attr "prefix_rep" ""
588 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
589 (const_int 0)
590 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
591 (const_int 1)
592 ]
593 (const_int 0)))
594
595 ;; Set when 0f opcode prefix is used.
596 (define_attr "prefix_0f" ""
597 (if_then_else
598 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
599 (eq_attr "unit" "sse,mmx"))
600 (const_int 1)
601 (const_int 0)))
602
603 ;; Set when REX opcode prefix is used.
604 (define_attr "prefix_rex" ""
605 (cond [(not (match_test "TARGET_64BIT"))
606 (const_int 0)
607 (and (eq_attr "mode" "DI")
608 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
609 (eq_attr "unit" "!mmx")))
610 (const_int 1)
611 (and (eq_attr "mode" "QI")
612 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
613 (const_int 1)
614 (match_test "x86_extended_reg_mentioned_p (insn)")
615 (const_int 1)
616 (and (eq_attr "type" "imovx")
617 (match_operand:QI 1 "ext_QIreg_operand"))
618 (const_int 1)
619 ]
620 (const_int 0)))
621
622 ;; There are also additional prefixes in 3DNOW, SSSE3.
623 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
624 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
625 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
626 (define_attr "prefix_extra" ""
627 (cond [(eq_attr "type" "ssemuladd,sse4arg")
628 (const_int 2)
629 (eq_attr "type" "sseiadd1,ssecvt1")
630 (const_int 1)
631 ]
632 (const_int 0)))
633
634 ;; Prefix used: original, VEX or maybe VEX.
635 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
636 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
637 (const_string "vex")
638 (eq_attr "mode" "XI,V16SF,V8DF")
639 (const_string "evex")
640 ]
641 (const_string "orig")))
642
643 ;; VEX W bit is used.
644 (define_attr "prefix_vex_w" "" (const_int 0))
645
646 ;; The length of VEX prefix
647 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
648 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
649 ;; still prefix_0f 1, with prefix_extra 1.
650 (define_attr "length_vex" ""
651 (if_then_else (and (eq_attr "prefix_0f" "1")
652 (eq_attr "prefix_extra" "0"))
653 (if_then_else (eq_attr "prefix_vex_w" "1")
654 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
655 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
656 (if_then_else (eq_attr "prefix_vex_w" "1")
657 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
658 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
659
660 ;; 4-bytes evex prefix and 1 byte opcode.
661 (define_attr "length_evex" "" (const_int 5))
662
663 ;; Set when modrm byte is used.
664 (define_attr "modrm" ""
665 (cond [(eq_attr "type" "str,leave")
666 (const_int 0)
667 (eq_attr "unit" "i387")
668 (const_int 0)
669 (and (eq_attr "type" "incdec")
670 (and (not (match_test "TARGET_64BIT"))
671 (ior (match_operand:SI 1 "register_operand")
672 (match_operand:HI 1 "register_operand"))))
673 (const_int 0)
674 (and (eq_attr "type" "push")
675 (not (match_operand 1 "memory_operand")))
676 (const_int 0)
677 (and (eq_attr "type" "pop")
678 (not (match_operand 0 "memory_operand")))
679 (const_int 0)
680 (and (eq_attr "type" "imov")
681 (and (not (eq_attr "mode" "DI"))
682 (ior (and (match_operand 0 "register_operand")
683 (match_operand 1 "immediate_operand"))
684 (ior (and (match_operand 0 "ax_reg_operand")
685 (match_operand 1 "memory_displacement_only_operand"))
686 (and (match_operand 0 "memory_displacement_only_operand")
687 (match_operand 1 "ax_reg_operand"))))))
688 (const_int 0)
689 (and (eq_attr "type" "call")
690 (match_operand 0 "constant_call_address_operand"))
691 (const_int 0)
692 (and (eq_attr "type" "callv")
693 (match_operand 1 "constant_call_address_operand"))
694 (const_int 0)
695 (and (eq_attr "type" "alu,alu1,icmp,test")
696 (match_operand 0 "ax_reg_operand"))
697 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
698 ]
699 (const_int 1)))
700
701 ;; The (bounding maximum) length of an instruction in bytes.
702 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
703 ;; Later we may want to split them and compute proper length as for
704 ;; other insns.
705 (define_attr "length" ""
706 (cond [(eq_attr "type" "other,multi,fistp,frndint")
707 (const_int 16)
708 (eq_attr "type" "fcmp")
709 (const_int 4)
710 (eq_attr "unit" "i387")
711 (plus (const_int 2)
712 (plus (attr "prefix_data16")
713 (attr "length_address")))
714 (ior (eq_attr "prefix" "evex")
715 (and (ior (eq_attr "prefix" "maybe_evex")
716 (eq_attr "prefix" "maybe_vex"))
717 (match_test "TARGET_AVX512F")))
718 (plus (attr "length_evex")
719 (plus (attr "length_immediate")
720 (plus (attr "modrm")
721 (attr "length_address"))))
722 (ior (eq_attr "prefix" "vex")
723 (and (ior (eq_attr "prefix" "maybe_vex")
724 (eq_attr "prefix" "maybe_evex"))
725 (match_test "TARGET_AVX")))
726 (plus (attr "length_vex")
727 (plus (attr "length_immediate")
728 (plus (attr "modrm")
729 (attr "length_address"))))]
730 (plus (plus (attr "modrm")
731 (plus (attr "prefix_0f")
732 (plus (attr "prefix_rex")
733 (plus (attr "prefix_extra")
734 (const_int 1)))))
735 (plus (attr "prefix_rep")
736 (plus (attr "prefix_data16")
737 (plus (attr "length_immediate")
738 (attr "length_address")))))))
739
740 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
741 ;; `store' if there is a simple memory reference therein, or `unknown'
742 ;; if the instruction is complex.
743
744 (define_attr "memory" "none,load,store,both,unknown"
745 (cond [(eq_attr "type" "other,multi,str,lwp")
746 (const_string "unknown")
747 (eq_attr "type" "lea,fcmov,fpspc")
748 (const_string "none")
749 (eq_attr "type" "fistp,leave")
750 (const_string "both")
751 (eq_attr "type" "frndint")
752 (const_string "load")
753 (eq_attr "type" "push")
754 (if_then_else (match_operand 1 "memory_operand")
755 (const_string "both")
756 (const_string "store"))
757 (eq_attr "type" "pop")
758 (if_then_else (match_operand 0 "memory_operand")
759 (const_string "both")
760 (const_string "load"))
761 (eq_attr "type" "setcc")
762 (if_then_else (match_operand 0 "memory_operand")
763 (const_string "store")
764 (const_string "none"))
765 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
766 (if_then_else (ior (match_operand 0 "memory_operand")
767 (match_operand 1 "memory_operand"))
768 (const_string "load")
769 (const_string "none"))
770 (eq_attr "type" "ibr")
771 (if_then_else (match_operand 0 "memory_operand")
772 (const_string "load")
773 (const_string "none"))
774 (eq_attr "type" "call")
775 (if_then_else (match_operand 0 "constant_call_address_operand")
776 (const_string "none")
777 (const_string "load"))
778 (eq_attr "type" "callv")
779 (if_then_else (match_operand 1 "constant_call_address_operand")
780 (const_string "none")
781 (const_string "load"))
782 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
783 (match_operand 1 "memory_operand"))
784 (const_string "both")
785 (and (match_operand 0 "memory_operand")
786 (match_operand 1 "memory_operand"))
787 (const_string "both")
788 (match_operand 0 "memory_operand")
789 (const_string "store")
790 (match_operand 1 "memory_operand")
791 (const_string "load")
792 (and (eq_attr "type"
793 "!alu1,negnot,ishift1,rotate1,
794 imov,imovx,icmp,test,bitmanip,
795 fmov,fcmp,fsgn,
796 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
797 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
798 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
799 (match_operand 2 "memory_operand"))
800 (const_string "load")
801 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
802 (match_operand 3 "memory_operand"))
803 (const_string "load")
804 ]
805 (const_string "none")))
806
807 ;; Indicates if an instruction has both an immediate and a displacement.
808
809 (define_attr "imm_disp" "false,true,unknown"
810 (cond [(eq_attr "type" "other,multi")
811 (const_string "unknown")
812 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
813 (and (match_operand 0 "memory_displacement_operand")
814 (match_operand 1 "immediate_operand")))
815 (const_string "true")
816 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
817 (and (match_operand 0 "memory_displacement_operand")
818 (match_operand 2 "immediate_operand")))
819 (const_string "true")
820 ]
821 (const_string "false")))
822
823 ;; Indicates if an FP operation has an integer source.
824
825 (define_attr "fp_int_src" "false,true"
826 (const_string "false"))
827
828 ;; Defines rounding mode of an FP operation.
829
830 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
831 (const_string "any"))
832
833 ;; Define attribute to indicate AVX insns with partial XMM register update.
834 (define_attr "avx_partial_xmm_update" "false,true"
835 (const_string "false"))
836
837 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
838 (define_attr "use_carry" "0,1" (const_string "0"))
839
840 ;; Define attribute to indicate unaligned ssemov insns
841 (define_attr "movu" "0,1" (const_string "0"))
842
843 ;; Used to control the "enabled" attribute on a per-instruction basis.
844 (define_attr "isa" "base,x64,nox64,x64_sse2,x64_sse4,x64_sse4_noavx,
845 x64_avx,x64_avx512bw,x64_avx512dq,aes,
846 sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
847 avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
848 avx512bw,noavx512bw,avx512dq,noavx512dq,fma_or_avx512vl,
849 avx512vl,noavx512vl,avxvnni,avx512vnnivl,avx512fp16,avxifma,
850 avx512ifmavl,avxneconvert,avx512bf16vl,vpclmulqdqvl"
851 (const_string "base"))
852
853 ;; Define instruction set of MMX instructions
854 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
855 (const_string "base"))
856
857 (define_attr "enabled" ""
858 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
859 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
860 (eq_attr "isa" "x64_sse2")
861 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
862 (eq_attr "isa" "x64_sse4")
863 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
864 (eq_attr "isa" "x64_sse4_noavx")
865 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
866 (eq_attr "isa" "x64_avx")
867 (symbol_ref "TARGET_64BIT && TARGET_AVX")
868 (eq_attr "isa" "x64_avx512bw")
869 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
870 (eq_attr "isa" "x64_avx512dq")
871 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
872 (eq_attr "isa" "aes") (symbol_ref "TARGET_AES")
873 (eq_attr "isa" "sse_noavx")
874 (symbol_ref "TARGET_SSE && !TARGET_AVX")
875 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
876 (eq_attr "isa" "sse2_noavx")
877 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
878 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
879 (eq_attr "isa" "sse3_noavx")
880 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
881 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
882 (eq_attr "isa" "sse4_noavx")
883 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
884 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
885 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
886 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
887 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
888 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
889 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
890 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
891 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
892 (eq_attr "isa" "fma_or_avx512vl")
893 (symbol_ref "TARGET_FMA || TARGET_AVX512VL")
894 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
895 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
896 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
897 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
898 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
899 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
900 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
901 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
902 (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
903 (eq_attr "isa" "avx512vnnivl")
904 (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
905 (eq_attr "isa" "avx512fp16")
906 (symbol_ref "TARGET_AVX512FP16")
907 (eq_attr "isa" "avxifma") (symbol_ref "TARGET_AVXIFMA")
908 (eq_attr "isa" "avx512ifmavl")
909 (symbol_ref "TARGET_AVX512IFMA && TARGET_AVX512VL")
910 (eq_attr "isa" "avxneconvert") (symbol_ref "TARGET_AVXNECONVERT")
911 (eq_attr "isa" "avx512bf16vl")
912 (symbol_ref "TARGET_AVX512BF16 && TARGET_AVX512VL")
913 (eq_attr "isa" "vpclmulqdqvl")
914 (symbol_ref "TARGET_VPCLMULQDQ && TARGET_AVX512VL")
915
916 (eq_attr "mmx_isa" "native")
917 (symbol_ref "!TARGET_MMX_WITH_SSE")
918 (eq_attr "mmx_isa" "sse")
919 (symbol_ref "TARGET_MMX_WITH_SSE")
920 (eq_attr "mmx_isa" "sse_noavx")
921 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
922 (eq_attr "mmx_isa" "avx")
923 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
924 ]
925 (const_int 1)))
926
927 (define_attr "preferred_for_size" "" (const_int 1))
928 (define_attr "preferred_for_speed" "" (const_int 1))
929
930 ;; Describe a user's asm statement.
931 (define_asm_attributes
932 [(set_attr "length" "128")
933 (set_attr "type" "multi")])
934
935 (define_code_iterator plusminus [plus minus])
936 (define_code_iterator plusminusmultdiv [plus minus mult div])
937
938 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
939
940 ;; Base name for insn mnemonic.
941 (define_code_attr plusminus_mnemonic
942 [(plus "add") (ss_plus "adds") (us_plus "addus")
943 (minus "sub") (ss_minus "subs") (us_minus "subus")])
944
945 (define_code_iterator multdiv [mult div])
946
947 (define_code_attr multdiv_mnemonic
948 [(mult "mul") (div "div")])
949
950 ;; Mark commutative operators as such in constraints.
951 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
952 (minus "") (ss_minus "") (us_minus "")
953 (mult "%") (div "")])
954
955 ;; Mapping of max and min
956 (define_code_iterator maxmin [smax smin umax umin])
957
958 ;; Mapping of signed max and min
959 (define_code_iterator smaxmin [smax smin])
960
961 ;; Mapping of unsigned max and min
962 (define_code_iterator umaxmin [umax umin])
963
964 ;; Base name for integer and FP insn mnemonic
965 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
966 (umax "maxu") (umin "minu")])
967 (define_code_attr maxmin_float [(smax "max") (smin "min")])
968
969 (define_int_iterator IEEE_MAXMIN
970 [UNSPEC_IEEE_MAX
971 UNSPEC_IEEE_MIN])
972
973 (define_int_attr ieee_maxmin
974 [(UNSPEC_IEEE_MAX "max")
975 (UNSPEC_IEEE_MIN "min")])
976
977 ;; Mapping of logic operators
978 (define_code_iterator any_logic [and ior xor])
979 (define_code_iterator any_or [ior xor])
980 (define_code_iterator fpint_logic [and xor])
981
982 ;; Base name for insn mnemonic.
983 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
984
985 ;; Mapping of logic-shift operators
986 (define_code_iterator any_lshift [ashift lshiftrt])
987
988 ;; Mapping of shift-right operators
989 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
990
991 ;; Mapping of all shift operators
992 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
993
994 ;; Base name for insn mnemonic.
995 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
996 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
997
998 ;; Mapping of rotate operators
999 (define_code_iterator any_rotate [rotate rotatert])
1000
1001 ;; Base name for insn mnemonic.
1002 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
1003
1004 ;; Mapping of abs neg operators
1005 (define_code_iterator absneg [abs neg])
1006
1007 ;; Mapping of abs neg operators to logic operation
1008 (define_code_attr absneg_op [(abs "and") (neg "xor")])
1009
1010 ;; Base name for x87 insn mnemonic.
1011 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
1012
1013 ;; Mapping of extend operators
1014 (define_code_iterator any_extend [sign_extend zero_extend])
1015
1016 ;; Mapping of highpart multiply operators
1017 (define_code_iterator any_mul_highpart [smul_highpart umul_highpart])
1018
1019 ;; Prefix for insn menmonic.
1020 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
1021 (smul_highpart "i") (umul_highpart "")
1022 (div "i") (udiv "")])
1023 ;; Prefix for define_insn
1024 (define_code_attr s [(sign_extend "s") (zero_extend "u")
1025 (smul_highpart "s") (umul_highpart "u")])
1026 (define_code_attr u [(sign_extend "") (zero_extend "u")
1027 (div "") (udiv "u")])
1028 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
1029 (div "false") (udiv "true")])
1030
1031 ;; Used in signed and unsigned truncations.
1032 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
1033 ;; Instruction suffix for truncations.
1034 (define_code_attr trunsuffix
1035 [(ss_truncate "s") (truncate "") (us_truncate "us")])
1036
1037 ;; Instruction suffix for SSE sign and zero extensions.
1038 (define_code_attr extsuffix [(sign_extend "sx") (zero_extend "zx")])
1039
1040 ;; Used in signed and unsigned fix.
1041 (define_code_iterator any_fix [fix unsigned_fix])
1042 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
1043 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
1044 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1045
1046 ;; Used in signed and unsigned float.
1047 (define_code_iterator any_float [float unsigned_float])
1048 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1049 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1050 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1051
1052 ;; Base name for expression
1053 (define_code_attr insn
1054 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1055 (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1056 (sign_extend "extend") (zero_extend "zero_extend")
1057 (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1058 (rotate "rotl") (rotatert "rotr")
1059 (mult "mul") (div "div")])
1060
1061 ;; All integer modes.
1062 (define_mode_iterator SWI1248x [QI HI SI DI])
1063
1064 ;; All integer modes without QImode.
1065 (define_mode_iterator SWI248x [HI SI DI])
1066
1067 ;; All integer modes without QImode and HImode.
1068 (define_mode_iterator SWI48x [SI DI])
1069
1070 ;; All integer modes without SImode and DImode.
1071 (define_mode_iterator SWI12 [QI HI])
1072
1073 ;; All integer modes without DImode.
1074 (define_mode_iterator SWI124 [QI HI SI])
1075
1076 ;; All integer modes without QImode and DImode.
1077 (define_mode_iterator SWI24 [HI SI])
1078
1079 ;; Single word integer modes.
1080 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1081
1082 ;; Single word integer modes without QImode.
1083 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1084
1085 ;; Single word integer modes without QImode and HImode.
1086 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1087
1088 ;; All math-dependant single and double word integer modes.
1089 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1090 (HI "TARGET_HIMODE_MATH")
1091 SI DI (TI "TARGET_64BIT")])
1092
1093 ;; Math-dependant single word integer modes.
1094 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1095 (HI "TARGET_HIMODE_MATH")
1096 SI (DI "TARGET_64BIT")])
1097
1098 ;; Math-dependant integer modes without DImode.
1099 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1100 (HI "TARGET_HIMODE_MATH")
1101 SI])
1102
1103 ;; Math-dependant integer modes with DImode.
1104 (define_mode_iterator SWIM1248x
1105 [(QI "TARGET_QIMODE_MATH")
1106 (HI "TARGET_HIMODE_MATH")
1107 SI DI])
1108
1109 ;; Math-dependant single word integer modes without QImode.
1110 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1111 SI (DI "TARGET_64BIT")])
1112
1113 ;; Double word integer modes.
1114 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1115 (TI "TARGET_64BIT")])
1116
1117 ;; SWI and DWI together.
1118 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1119
1120 ;; SWI48 and DWI together.
1121 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1122
1123 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1124 ;; compile time constant, it is faster to use <MODE_SIZE> than
1125 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1126 ;; command line options just use GET_MODE_SIZE macro.
1127 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8")
1128 (TI "16") (HF "2") (BF "2") (SF "4") (DF "8")
1129 (XF "GET_MODE_SIZE (XFmode)")
1130 (V16QI "16") (V32QI "32") (V64QI "64")
1131 (V8HI "16") (V16HI "32") (V32HI "64")
1132 (V4SI "16") (V8SI "32") (V16SI "64")
1133 (V2DI "16") (V4DI "32") (V8DI "64")
1134 (V1TI "16") (V2TI "32") (V4TI "64")
1135 (V2DF "16") (V4DF "32") (V8DF "64")
1136 (V4SF "16") (V8SF "32") (V16SF "64")
1137 (V8HF "16") (V16HF "32") (V32HF "64")
1138 (V4HF "8") (V2HF "4")
1139 (V8BF "16") (V16BF "32") (V32BF "64")
1140 (V4BF "8") (V2BF "4")])
1141
1142 ;; Double word integer modes as mode attribute.
1143 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1144 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1145
1146 ;; Half sized integer modes.
1147 (define_mode_attr HALF [(TI "DI") (DI "SI")])
1148 (define_mode_attr half [(TI "di") (DI "si")])
1149
1150 ;; LEA mode corresponding to an integer mode
1151 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1152
1153 ;; Half mode for double word integer modes.
1154 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1155 (DI "TARGET_64BIT")])
1156
1157 ;; Instruction suffix for integer modes.
1158 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1159
1160 ;; Instruction suffix for masks.
1161 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1162
1163 ;; Pointer size prefix for integer modes (Intel asm dialect)
1164 (define_mode_attr iptrsize [(QI "BYTE")
1165 (HI "WORD")
1166 (SI "DWORD")
1167 (DI "QWORD")])
1168
1169 ;; Register class for integer modes.
1170 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1171
1172 ;; Immediate operand constraint for integer modes.
1173 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1174
1175 ;; General operand constraint for word modes.
1176 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1177
1178 ;; Memory operand constraint for word modes.
1179 (define_mode_attr m [(QI "m") (HI "m") (SI "BM") (DI "BM")])
1180
1181 ;; Immediate operand constraint for double integer modes.
1182 (define_mode_attr di [(SI "nF") (DI "Wd")])
1183
1184 ;; Immediate operand constraint for shifts.
1185 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1186 (define_mode_attr KS [(QI "Wb") (HI "Ww") (SI "I") (DI "J")])
1187
1188 ;; Print register name in the specified mode.
1189 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1190
1191 ;; General operand predicate for integer modes.
1192 (define_mode_attr general_operand
1193 [(QI "general_operand")
1194 (HI "general_operand")
1195 (SI "x86_64_general_operand")
1196 (DI "x86_64_general_operand")
1197 (TI "x86_64_general_operand")])
1198
1199 ;; General operand predicate for integer modes, where for TImode
1200 ;; we need both words of the operand to be general operands.
1201 (define_mode_attr general_hilo_operand
1202 [(QI "general_operand")
1203 (HI "general_operand")
1204 (SI "x86_64_general_operand")
1205 (DI "x86_64_general_operand")
1206 (TI "x86_64_hilo_general_operand")])
1207
1208 ;; General sign extend operand predicate for integer modes,
1209 ;; which disallows VOIDmode operands and thus it is suitable
1210 ;; for use inside sign_extend.
1211 (define_mode_attr general_sext_operand
1212 [(QI "sext_operand")
1213 (HI "sext_operand")
1214 (SI "x86_64_sext_operand")
1215 (DI "x86_64_sext_operand")])
1216
1217 ;; General sign/zero extend operand predicate for integer modes.
1218 (define_mode_attr general_szext_operand
1219 [(QI "general_operand")
1220 (HI "general_operand")
1221 (SI "x86_64_szext_general_operand")
1222 (DI "x86_64_szext_general_operand")
1223 (TI "x86_64_hilo_general_operand")])
1224
1225 (define_mode_attr nonmemory_szext_operand
1226 [(QI "nonmemory_operand")
1227 (HI "nonmemory_operand")
1228 (SI "x86_64_szext_nonmemory_operand")
1229 (DI "x86_64_szext_nonmemory_operand")])
1230
1231 ;; Immediate operand predicate for integer modes.
1232 (define_mode_attr immediate_operand
1233 [(QI "immediate_operand")
1234 (HI "immediate_operand")
1235 (SI "x86_64_immediate_operand")
1236 (DI "x86_64_immediate_operand")])
1237
1238 ;; Nonmemory operand predicate for integer modes.
1239 (define_mode_attr nonmemory_operand
1240 [(QI "nonmemory_operand")
1241 (HI "nonmemory_operand")
1242 (SI "x86_64_nonmemory_operand")
1243 (DI "x86_64_nonmemory_operand")])
1244
1245 ;; Operand predicate for shifts.
1246 (define_mode_attr shift_operand
1247 [(QI "nonimmediate_operand")
1248 (HI "nonimmediate_operand")
1249 (SI "nonimmediate_operand")
1250 (DI "shiftdi_operand")
1251 (TI "register_operand")])
1252
1253 ;; Operand predicate for shift argument.
1254 (define_mode_attr shift_immediate_operand
1255 [(QI "const_1_to_31_operand")
1256 (HI "const_1_to_31_operand")
1257 (SI "const_1_to_31_operand")
1258 (DI "const_1_to_63_operand")])
1259
1260 ;; Input operand predicate for arithmetic left shifts.
1261 (define_mode_attr ashl_input_operand
1262 [(QI "nonimmediate_operand")
1263 (HI "nonimmediate_operand")
1264 (SI "nonimmediate_operand")
1265 (DI "ashldi_input_operand")
1266 (TI "reg_or_pm1_operand")])
1267
1268 ;; SSE and x87 SFmode and DFmode floating point modes
1269 (define_mode_iterator MODEF [SF DF])
1270
1271 ;; SSE floating point modes
1272 (define_mode_iterator MODEFH [(HF "TARGET_AVX512FP16") SF DF])
1273
1274 ;; All x87 floating point modes
1275 (define_mode_iterator X87MODEF [SF DF XF])
1276
1277 ;; All x87 floating point modes plus HFmode
1278 (define_mode_iterator X87MODEFH [HF SF DF XF BF])
1279
1280 ;; All SSE floating point modes
1281 (define_mode_iterator SSEMODEF [HF SF DF TF])
1282 (define_mode_attr ssevecmodef [(HF "V8HF") (SF "V4SF") (DF "V2DF") (TF "TF")])
1283
1284 ;; SSE instruction suffix for various modes
1285 (define_mode_attr ssemodesuffix
1286 [(HF "sh") (SF "ss") (DF "sd")
1287 (V32HF "ph") (V16SF "ps") (V8DF "pd")
1288 (V16HF "ph") (V16BF "bf") (V8SF "ps") (V4DF "pd")
1289 (V8HF "ph") (V8BF "bf") (V4SF "ps") (V2DF "pd")
1290 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1291 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1292 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1293
1294 ;; SSE vector suffix for floating point modes
1295 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1296
1297 ;; SSE vector mode corresponding to a scalar mode
1298 (define_mode_attr ssevecmode
1299 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (HF "V8HF") (BF "V8BF") (SF "V4SF") (DF "V2DF")])
1300 (define_mode_attr ssevecmodelower
1301 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1302
1303 ;; AVX512F vector mode corresponding to a scalar mode
1304 (define_mode_attr avx512fvecmode
1305 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1306
1307 ;; Instruction suffix for REX 64bit operators.
1308 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1309 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1310
1311 ;; This mode iterator allows :P to be used for patterns that operate on
1312 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1313 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1314
1315 ;; This mode iterator allows :W to be used for patterns that operate on
1316 ;; word_mode sized quantities.
1317 (define_mode_iterator W
1318 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1319
1320 ;; This mode iterator allows :PTR to be used for patterns that operate on
1321 ;; ptr_mode sized quantities.
1322 (define_mode_iterator PTR
1323 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1324 \f
1325 ;; Scheduling descriptions
1326
1327 (include "pentium.md")
1328 (include "ppro.md")
1329 (include "k6.md")
1330 (include "athlon.md")
1331 (include "bdver1.md")
1332 (include "bdver3.md")
1333 (include "btver2.md")
1334 (include "znver.md")
1335 (include "znver4.md")
1336 (include "geode.md")
1337 (include "atom.md")
1338 (include "slm.md")
1339 (include "glm.md")
1340 (include "core2.md")
1341 (include "haswell.md")
1342 (include "lujiazui.md")
1343
1344 \f
1345 ;; Operand and operator predicates and constraints
1346
1347 (include "predicates.md")
1348 (include "constraints.md")
1349
1350 \f
1351 ;; Compare and branch/compare and store instructions.
1352
1353 (define_expand "cbranch<mode>4"
1354 [(set (reg:CC FLAGS_REG)
1355 (compare:CC (match_operand:SWIM1248x 1 "nonimmediate_operand")
1356 (match_operand:SWIM1248x 2 "<general_operand>")))
1357 (set (pc) (if_then_else
1358 (match_operator 0 "ordered_comparison_operator"
1359 [(reg:CC FLAGS_REG) (const_int 0)])
1360 (label_ref (match_operand 3))
1361 (pc)))]
1362 ""
1363 {
1364 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1365 operands[1] = force_reg (<MODE>mode, operands[1]);
1366 ix86_expand_branch (GET_CODE (operands[0]),
1367 operands[1], operands[2], operands[3]);
1368 DONE;
1369 })
1370
1371 (define_expand "cbranchti4"
1372 [(set (reg:CC FLAGS_REG)
1373 (compare:CC (match_operand:TI 1 "nonimmediate_operand")
1374 (match_operand:TI 2 "ix86_timode_comparison_operand")))
1375 (set (pc) (if_then_else
1376 (match_operator 0 "ix86_timode_comparison_operator"
1377 [(reg:CC FLAGS_REG) (const_int 0)])
1378 (label_ref (match_operand 3))
1379 (pc)))]
1380 "TARGET_64BIT || TARGET_SSE4_1"
1381 {
1382 ix86_expand_branch (GET_CODE (operands[0]),
1383 operands[1], operands[2], operands[3]);
1384 DONE;
1385 })
1386
1387 (define_expand "cbranchoi4"
1388 [(set (reg:CC FLAGS_REG)
1389 (compare:CC (match_operand:OI 1 "nonimmediate_operand")
1390 (match_operand:OI 2 "nonimmediate_operand")))
1391 (set (pc) (if_then_else
1392 (match_operator 0 "bt_comparison_operator"
1393 [(reg:CC FLAGS_REG) (const_int 0)])
1394 (label_ref (match_operand 3))
1395 (pc)))]
1396 "TARGET_AVX"
1397 {
1398 ix86_expand_branch (GET_CODE (operands[0]),
1399 operands[1], operands[2], operands[3]);
1400 DONE;
1401 })
1402
1403 (define_expand "cstore<mode>4"
1404 [(set (reg:CC FLAGS_REG)
1405 (compare:CC (match_operand:SDWIM 2 "nonimmediate_operand")
1406 (match_operand:SDWIM 3 "<general_operand>")))
1407 (set (match_operand:QI 0 "register_operand")
1408 (match_operator 1 "ordered_comparison_operator"
1409 [(reg:CC FLAGS_REG) (const_int 0)]))]
1410 ""
1411 {
1412 if (<MODE>mode == (TARGET_64BIT ? TImode : DImode))
1413 {
1414 if (GET_CODE (operands[1]) != EQ
1415 && GET_CODE (operands[1]) != NE)
1416 FAIL;
1417 }
1418 else if (MEM_P (operands[2]) && MEM_P (operands[3]))
1419 operands[2] = force_reg (<MODE>mode, operands[2]);
1420 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1421 operands[2], operands[3]);
1422 DONE;
1423 })
1424
1425 (define_expand "@cmp<mode>_1"
1426 [(set (reg:CC FLAGS_REG)
1427 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1428 (match_operand:SWI48 1 "<general_operand>")))])
1429
1430 (define_mode_iterator SWI1248_AVX512BWDQ_64
1431 [(QI "TARGET_AVX512DQ") HI
1432 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1433
1434 (define_insn "*cmp<mode>_ccz_1"
1435 [(set (reg FLAGS_REG)
1436 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1437 "nonimmediate_operand" "<r>,?m<r>,$k")
1438 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1439 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1440 "@
1441 test{<imodesuffix>}\t%0, %0
1442 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1443 kortest<mskmodesuffix>\t%0, %0"
1444 [(set_attr "type" "test,icmp,msklog")
1445 (set_attr "length_immediate" "0,1,*")
1446 (set_attr "prefix" "*,*,vex")
1447 (set_attr "mode" "<MODE>")])
1448
1449 (define_insn "*cmp<mode>_ccno_1"
1450 [(set (reg FLAGS_REG)
1451 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1452 (match_operand:SWI 1 "const0_operand")))]
1453 "ix86_match_ccmode (insn, CCNOmode)"
1454 "@
1455 test{<imodesuffix>}\t%0, %0
1456 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1457 [(set_attr "type" "test,icmp")
1458 (set_attr "length_immediate" "0,1")
1459 (set_attr "mode" "<MODE>")])
1460
1461 (define_insn "*cmp<mode>_1"
1462 [(set (reg FLAGS_REG)
1463 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1464 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
1465 "ix86_match_ccmode (insn, CCmode)"
1466 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1467 [(set_attr "type" "icmp")
1468 (set_attr "mode" "<MODE>")])
1469
1470 (define_insn "*cmp<mode>_minus_1"
1471 [(set (reg FLAGS_REG)
1472 (compare
1473 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1474 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
1475 (const_int 0)))]
1476 "ix86_match_ccmode (insn, CCGOCmode)"
1477 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1478 [(set_attr "type" "icmp")
1479 (set_attr "mode" "<MODE>")])
1480
1481 (define_insn "*cmpqi_ext<mode>_1_mem_rex64"
1482 [(set (reg FLAGS_REG)
1483 (compare
1484 (match_operand:QI 0 "norex_memory_operand" "Bn")
1485 (subreg:QI
1486 (match_operator:SWI248 2 "extract_operator"
1487 [(match_operand 1 "int248_register_operand" "Q")
1488 (const_int 8)
1489 (const_int 8)]) 0)))]
1490 "TARGET_64BIT && reload_completed
1491 && ix86_match_ccmode (insn, CCmode)"
1492 "cmp{b}\t{%h1, %0|%0, %h1}"
1493 [(set_attr "type" "icmp")
1494 (set_attr "mode" "QI")])
1495
1496 (define_insn "*cmpqi_ext<mode>_1"
1497 [(set (reg FLAGS_REG)
1498 (compare
1499 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1500 (subreg:QI
1501 (match_operator:SWI248 2 "extract_operator"
1502 [(match_operand 1 "int248_register_operand" "Q,Q")
1503 (const_int 8)
1504 (const_int 8)]) 0)))]
1505 "ix86_match_ccmode (insn, CCmode)"
1506 "cmp{b}\t{%h1, %0|%0, %h1}"
1507 [(set_attr "isa" "*,nox64")
1508 (set_attr "type" "icmp")
1509 (set_attr "mode" "QI")])
1510
1511 (define_peephole2
1512 [(set (match_operand:QI 0 "register_operand")
1513 (match_operand:QI 1 "norex_memory_operand"))
1514 (set (match_operand 3 "flags_reg_operand")
1515 (match_operator 4 "compare_operator"
1516 [(match_dup 0)
1517 (subreg:QI
1518 (match_operator:SWI248 5 "extract_operator"
1519 [(match_operand 2 "int248_register_operand")
1520 (const_int 8)
1521 (const_int 8)]) 0)]))]
1522 "TARGET_64BIT
1523 && peep2_reg_dead_p (2, operands[0])"
1524 [(set (match_dup 3)
1525 (match_op_dup 4
1526 [(match_dup 1)
1527 (subreg:QI
1528 (match_op_dup 5
1529 [(match_dup 2)
1530 (const_int 8)
1531 (const_int 8)]) 0)]))])
1532
1533 (define_insn "*cmpqi_ext<mode>_2"
1534 [(set (reg FLAGS_REG)
1535 (compare
1536 (subreg:QI
1537 (match_operator:SWI248 2 "extract_operator"
1538 [(match_operand 0 "int248_register_operand" "Q")
1539 (const_int 8)
1540 (const_int 8)]) 0)
1541 (match_operand:QI 1 "const0_operand")))]
1542 "ix86_match_ccmode (insn, CCNOmode)"
1543 "test{b}\t%h0, %h0"
1544 [(set_attr "type" "test")
1545 (set_attr "length_immediate" "0")
1546 (set_attr "mode" "QI")])
1547
1548 (define_expand "cmpqi_ext_3"
1549 [(set (reg:CC FLAGS_REG)
1550 (compare:CC
1551 (subreg:QI
1552 (zero_extract:HI
1553 (match_operand:HI 0 "register_operand")
1554 (const_int 8)
1555 (const_int 8)) 0)
1556 (match_operand:QI 1 "const_int_operand")))])
1557
1558 (define_insn "*cmpqi_ext<mode>_3_mem_rex64"
1559 [(set (reg FLAGS_REG)
1560 (compare
1561 (subreg:QI
1562 (match_operator:SWI248 2 "extract_operator"
1563 [(match_operand 0 "int248_register_operand" "Q")
1564 (const_int 8)
1565 (const_int 8)]) 0)
1566 (match_operand:QI 1 "norex_memory_operand" "Bn")))]
1567 "TARGET_64BIT && reload_completed
1568 && ix86_match_ccmode (insn, CCmode)"
1569 "cmp{b}\t{%1, %h0|%h0, %1}"
1570 [(set_attr "type" "icmp")
1571 (set_attr "mode" "QI")])
1572
1573 (define_insn "*cmpqi_ext<mode>_3"
1574 [(set (reg FLAGS_REG)
1575 (compare
1576 (subreg:QI
1577 (match_operator:SWI248 2 "extract_operator"
1578 [(match_operand 0 "int248_register_operand" "Q,Q")
1579 (const_int 8)
1580 (const_int 8)]) 0)
1581 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1582 "ix86_match_ccmode (insn, CCmode)"
1583 "cmp{b}\t{%1, %h0|%h0, %1}"
1584 [(set_attr "isa" "*,nox64")
1585 (set_attr "type" "icmp")
1586 (set_attr "mode" "QI")])
1587
1588 (define_peephole2
1589 [(set (match_operand:QI 0 "register_operand")
1590 (match_operand:QI 1 "norex_memory_operand"))
1591 (set (match_operand 3 "flags_reg_operand")
1592 (match_operator 4 "compare_operator"
1593 [(subreg:QI
1594 (match_operator:SWI248 5 "extract_operator"
1595 [(match_operand 2 "int248_register_operand")
1596 (const_int 8)
1597 (const_int 8)]) 0)
1598 (match_dup 0)]))]
1599 "TARGET_64BIT
1600 && peep2_reg_dead_p (2, operands[0])"
1601 [(set (match_dup 3)
1602 (match_op_dup 4
1603 [(subreg:QI
1604 (match_op_dup 5
1605 [(match_dup 2)
1606 (const_int 8)
1607 (const_int 8)]) 0)
1608 (match_dup 1)]))])
1609
1610 (define_insn "*cmpqi_ext<mode>_4"
1611 [(set (reg FLAGS_REG)
1612 (compare
1613 (subreg:QI
1614 (match_operator:SWI248 2 "extract_operator"
1615 [(match_operand 0 "int248_register_operand" "Q")
1616 (const_int 8)
1617 (const_int 8)]) 0)
1618 (subreg:QI
1619 (match_operator:SWI248 3 "extract_operator"
1620 [(match_operand 1 "int248_register_operand" "Q")
1621 (const_int 8)
1622 (const_int 8)]) 0)))]
1623 "ix86_match_ccmode (insn, CCmode)"
1624 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1625 [(set_attr "type" "icmp")
1626 (set_attr "mode" "QI")])
1627
1628 (define_insn_and_split "*cmp<dwi>_doubleword"
1629 [(set (reg:CCZ FLAGS_REG)
1630 (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
1631 (match_operand:<DWI> 1 "general_operand")))]
1632 "ix86_pre_reload_split ()"
1633 "#"
1634 "&& 1"
1635 [(parallel [(set (reg:CCZ FLAGS_REG)
1636 (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
1637 (const_int 0)))
1638 (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]
1639 {
1640 split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);
1641 /* Placing the SUBREG pieces in pseudos helps reload. */
1642 for (int i = 0; i < 4; i++)
1643 if (SUBREG_P (operands[i]))
1644 operands[i] = force_reg (<MODE>mode, operands[i]);
1645
1646 operands[4] = gen_reg_rtx (<MODE>mode);
1647
1648 /* Special case comparisons against -1. */
1649 if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
1650 {
1651 emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
1652 emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
1653 DONE;
1654 }
1655
1656 if (operands[1] == const0_rtx)
1657 emit_move_insn (operands[4], operands[0]);
1658 else if (operands[0] == const0_rtx)
1659 emit_move_insn (operands[4], operands[1]);
1660 else if (operands[1] == constm1_rtx)
1661 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[0]));
1662 else if (operands[0] == constm1_rtx)
1663 emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
1664 else
1665 {
1666 if (CONST_SCALAR_INT_P (operands[1])
1667 && !x86_64_immediate_operand (operands[1], <MODE>mode))
1668 operands[1] = force_reg (<MODE>mode, operands[1]);
1669 emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
1670 }
1671
1672 if (operands[3] == const0_rtx)
1673 operands[5] = operands[2];
1674 else if (operands[2] == const0_rtx)
1675 operands[5] = operands[3];
1676 else
1677 {
1678 operands[5] = gen_reg_rtx (<MODE>mode);
1679 if (operands[3] == constm1_rtx)
1680 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[2]));
1681 else if (operands[2] == constm1_rtx)
1682 emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
1683 else
1684 {
1685 if (CONST_SCALAR_INT_P (operands[3])
1686 && !x86_64_immediate_operand (operands[3], <MODE>mode))
1687 operands[3] = force_reg (<MODE>mode, operands[3]);
1688 emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
1689 }
1690 }
1691 })
1692
1693 ;; These implement float point compares.
1694 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1695 ;; which would allow mix and match FP modes on the compares. Which is what
1696 ;; the old patterns did, but with many more of them.
1697
1698 (define_expand "cbranchxf4"
1699 [(set (reg:CC FLAGS_REG)
1700 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1701 (match_operand:XF 2 "nonmemory_operand")))
1702 (set (pc) (if_then_else
1703 (match_operator 0 "ix86_fp_comparison_operator"
1704 [(reg:CC FLAGS_REG)
1705 (const_int 0)])
1706 (label_ref (match_operand 3))
1707 (pc)))]
1708 "TARGET_80387"
1709 {
1710 ix86_expand_branch (GET_CODE (operands[0]),
1711 operands[1], operands[2], operands[3]);
1712 DONE;
1713 })
1714
1715 (define_expand "cstorexf4"
1716 [(set (reg:CC FLAGS_REG)
1717 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1718 (match_operand:XF 3 "nonmemory_operand")))
1719 (set (match_operand:QI 0 "register_operand")
1720 (match_operator 1 "ix86_fp_comparison_operator"
1721 [(reg:CC FLAGS_REG)
1722 (const_int 0)]))]
1723 "TARGET_80387"
1724 {
1725 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1726 operands[2], operands[3]);
1727 DONE;
1728 })
1729
1730 (define_expand "cbranchhf4"
1731 [(set (reg:CC FLAGS_REG)
1732 (compare:CC (match_operand:HF 1 "cmp_fp_expander_operand")
1733 (match_operand:HF 2 "cmp_fp_expander_operand")))
1734 (set (pc) (if_then_else
1735 (match_operator 0 "ix86_fp_comparison_operator"
1736 [(reg:CC FLAGS_REG)
1737 (const_int 0)])
1738 (label_ref (match_operand 3))
1739 (pc)))]
1740 "TARGET_AVX512FP16"
1741 {
1742 ix86_expand_branch (GET_CODE (operands[0]),
1743 operands[1], operands[2], operands[3]);
1744 DONE;
1745 })
1746
1747 (define_expand "cbranch<mode>4"
1748 [(set (reg:CC FLAGS_REG)
1749 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1750 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1751 (set (pc) (if_then_else
1752 (match_operator 0 "ix86_fp_comparison_operator"
1753 [(reg:CC FLAGS_REG)
1754 (const_int 0)])
1755 (label_ref (match_operand 3))
1756 (pc)))]
1757 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1758 {
1759 ix86_expand_branch (GET_CODE (operands[0]),
1760 operands[1], operands[2], operands[3]);
1761 DONE;
1762 })
1763
1764 (define_expand "cbranchbf4"
1765 [(set (reg:CC FLAGS_REG)
1766 (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand")
1767 (match_operand:BF 2 "cmp_fp_expander_operand")))
1768 (set (pc) (if_then_else
1769 (match_operator 0 "comparison_operator"
1770 [(reg:CC FLAGS_REG)
1771 (const_int 0)])
1772 (label_ref (match_operand 3))
1773 (pc)))]
1774 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1775 {
1776 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[1]);
1777 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1778 do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0,
1779 SFmode, NULL_RTX, NULL,
1780 as_a <rtx_code_label *> (operands[3]),
1781 /* Unfortunately this isn't propagated. */
1782 profile_probability::even ());
1783 DONE;
1784 })
1785
1786 (define_expand "cstorehf4"
1787 [(set (reg:CC FLAGS_REG)
1788 (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand")
1789 (match_operand:HF 3 "cmp_fp_expander_operand")))
1790 (set (match_operand:QI 0 "register_operand")
1791 (match_operator 1 "ix86_fp_comparison_operator"
1792 [(reg:CC FLAGS_REG)
1793 (const_int 0)]))]
1794 "TARGET_AVX512FP16"
1795 {
1796 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1797 operands[2], operands[3]);
1798 DONE;
1799 })
1800
1801 (define_expand "cstorebf4"
1802 [(set (reg:CC FLAGS_REG)
1803 (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand")
1804 (match_operand:BF 3 "cmp_fp_expander_operand")))
1805 (set (match_operand:QI 0 "register_operand")
1806 (match_operator 1 "comparison_operator"
1807 [(reg:CC FLAGS_REG)
1808 (const_int 0)]))]
1809 "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
1810 {
1811 rtx op1 = ix86_expand_fast_convert_bf_to_sf (operands[2]);
1812 rtx op2 = ix86_expand_fast_convert_bf_to_sf (operands[3]);
1813 rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]),
1814 op1, op2, SFmode, 0, 1);
1815 if (!rtx_equal_p (res, operands[0]))
1816 emit_move_insn (operands[0], res);
1817 DONE;
1818 })
1819
1820 (define_expand "cstore<mode>4"
1821 [(set (reg:CC FLAGS_REG)
1822 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1823 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1824 (set (match_operand:QI 0 "register_operand")
1825 (match_operator 1 "ix86_fp_comparison_operator"
1826 [(reg:CC FLAGS_REG)
1827 (const_int 0)]))]
1828 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1829 {
1830 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1831 operands[2], operands[3]);
1832 DONE;
1833 })
1834
1835 (define_expand "cbranchcc4"
1836 [(set (pc) (if_then_else
1837 (match_operator 0 "comparison_operator"
1838 [(match_operand 1 "flags_reg_operand")
1839 (match_operand 2 "const0_operand")])
1840 (label_ref (match_operand 3))
1841 (pc)))]
1842 ""
1843 {
1844 ix86_expand_branch (GET_CODE (operands[0]),
1845 operands[1], operands[2], operands[3]);
1846 DONE;
1847 })
1848
1849 (define_expand "cstorecc4"
1850 [(set (match_operand:QI 0 "register_operand")
1851 (match_operator 1 "comparison_operator"
1852 [(match_operand 2 "flags_reg_operand")
1853 (match_operand 3 "const0_operand")]))]
1854 ""
1855 {
1856 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1857 operands[2], operands[3]);
1858 DONE;
1859 })
1860
1861 ;; FP compares, step 1:
1862 ;; Set the FP condition codes and move fpsr to ax.
1863
1864 ;; We may not use "#" to split and emit these
1865 ;; due to reg-stack pops killing fpsr.
1866
1867 (define_insn "*cmpxf_i387"
1868 [(set (match_operand:HI 0 "register_operand" "=a")
1869 (unspec:HI
1870 [(compare:CCFP
1871 (match_operand:XF 1 "register_operand" "f")
1872 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1873 UNSPEC_FNSTSW))]
1874 "TARGET_80387"
1875 "* return output_fp_compare (insn, operands, false, false);"
1876 [(set_attr "type" "multi")
1877 (set_attr "unit" "i387")
1878 (set_attr "mode" "XF")])
1879
1880 (define_insn "*cmp<mode>_i387"
1881 [(set (match_operand:HI 0 "register_operand" "=a")
1882 (unspec:HI
1883 [(compare:CCFP
1884 (match_operand:MODEF 1 "register_operand" "f")
1885 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1886 UNSPEC_FNSTSW))]
1887 "TARGET_80387"
1888 "* return output_fp_compare (insn, operands, false, false);"
1889 [(set_attr "type" "multi")
1890 (set_attr "unit" "i387")
1891 (set_attr "mode" "<MODE>")])
1892
1893 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1894 [(set (match_operand:HI 0 "register_operand" "=a")
1895 (unspec:HI
1896 [(compare:CCFP
1897 (match_operand:X87MODEF 1 "register_operand" "f")
1898 (float:X87MODEF
1899 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1900 UNSPEC_FNSTSW))]
1901 "TARGET_80387
1902 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1903 || optimize_function_for_size_p (cfun))"
1904 "* return output_fp_compare (insn, operands, false, false);"
1905 [(set_attr "type" "multi")
1906 (set_attr "unit" "i387")
1907 (set_attr "fp_int_src" "true")
1908 (set_attr "mode" "<SWI24:MODE>")])
1909
1910 (define_insn "*cmpu<mode>_i387"
1911 [(set (match_operand:HI 0 "register_operand" "=a")
1912 (unspec:HI
1913 [(unspec:CCFP
1914 [(compare:CCFP
1915 (match_operand:X87MODEF 1 "register_operand" "f")
1916 (match_operand:X87MODEF 2 "register_operand" "f"))]
1917 UNSPEC_NOTRAP)]
1918 UNSPEC_FNSTSW))]
1919 "TARGET_80387"
1920 "* return output_fp_compare (insn, operands, false, true);"
1921 [(set_attr "type" "multi")
1922 (set_attr "unit" "i387")
1923 (set_attr "mode" "<MODE>")])
1924
1925 ;; FP compares, step 2:
1926 ;; Get ax into flags, general case.
1927
1928 (define_insn "x86_sahf_1"
1929 [(set (reg:CC FLAGS_REG)
1930 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1931 UNSPEC_SAHF))]
1932 "TARGET_SAHF"
1933 {
1934 #ifndef HAVE_AS_IX86_SAHF
1935 if (TARGET_64BIT)
1936 return ASM_BYTE "0x9e";
1937 else
1938 #endif
1939 return "sahf";
1940 }
1941 [(set_attr "length" "1")
1942 (set_attr "athlon_decode" "vector")
1943 (set_attr "amdfam10_decode" "direct")
1944 (set_attr "bdver1_decode" "direct")
1945 (set_attr "mode" "SI")])
1946
1947 ;; Pentium Pro can do both steps in one go.
1948 ;; (these instructions set flags directly)
1949
1950 (define_subst_attr "unord" "unord_subst" "" "u")
1951 (define_subst_attr "unordered" "unord_subst" "false" "true")
1952
1953 (define_subst "unord_subst"
1954 [(set (match_operand:CCFP 0)
1955 (match_operand:CCFP 1))]
1956 ""
1957 [(set (match_dup 0)
1958 (unspec:CCFP
1959 [(match_dup 1)]
1960 UNSPEC_NOTRAP))])
1961
1962 (define_insn "*cmpi<unord>xf_i387"
1963 [(set (reg:CCFP FLAGS_REG)
1964 (compare:CCFP
1965 (match_operand:XF 0 "register_operand" "f")
1966 (match_operand:XF 1 "register_operand" "f")))]
1967 "TARGET_80387 && TARGET_CMOVE"
1968 "* return output_fp_compare (insn, operands, true, <unordered>);"
1969 [(set_attr "type" "fcmp")
1970 (set_attr "mode" "XF")
1971 (set_attr "athlon_decode" "vector")
1972 (set_attr "amdfam10_decode" "direct")
1973 (set_attr "bdver1_decode" "double")
1974 (set_attr "znver1_decode" "double")])
1975
1976 (define_insn "*cmpi<unord><MODEF:mode>"
1977 [(set (reg:CCFP FLAGS_REG)
1978 (compare:CCFP
1979 (match_operand:MODEF 0 "register_operand" "f,v")
1980 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1981 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1982 || (TARGET_80387 && TARGET_CMOVE)"
1983 "@
1984 * return output_fp_compare (insn, operands, true, <unordered>);
1985 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1986 [(set_attr "type" "fcmp,ssecomi")
1987 (set_attr "prefix" "orig,maybe_vex")
1988 (set_attr "mode" "<MODEF:MODE>")
1989 (set_attr "prefix_rep" "*,0")
1990 (set (attr "prefix_data16")
1991 (cond [(eq_attr "alternative" "0")
1992 (const_string "*")
1993 (eq_attr "mode" "DF")
1994 (const_string "1")
1995 ]
1996 (const_string "0")))
1997 (set_attr "athlon_decode" "vector")
1998 (set_attr "amdfam10_decode" "direct")
1999 (set_attr "bdver1_decode" "double")
2000 (set_attr "znver1_decode" "double")
2001 (set (attr "enabled")
2002 (if_then_else
2003 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
2004 (if_then_else
2005 (eq_attr "alternative" "0")
2006 (symbol_ref "TARGET_MIX_SSE_I387")
2007 (symbol_ref "true"))
2008 (if_then_else
2009 (eq_attr "alternative" "0")
2010 (symbol_ref "true")
2011 (symbol_ref "false"))))])
2012
2013 (define_insn "*cmpi<unord>hf"
2014 [(set (reg:CCFP FLAGS_REG)
2015 (compare:CCFP
2016 (match_operand:HF 0 "register_operand" "v")
2017 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
2018 "TARGET_AVX512FP16"
2019 "v<unord>comish\t{%1, %0|%0, %1}"
2020 [(set_attr "type" "ssecomi")
2021 (set_attr "prefix" "evex")
2022 (set_attr "mode" "HF")])
2023
2024 ;; Set carry flag.
2025 (define_insn "x86_stc"
2026 [(set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2027 ""
2028 "stc"
2029 [(set_attr "length" "1")
2030 (set_attr "length_immediate" "0")
2031 (set_attr "modrm" "0")])
2032
2033 ;; On Pentium 4, set the carry flag using mov $1,%al;addb $-1,%al.
2034 (define_peephole2
2035 [(match_scratch:QI 0 "r")
2036 (set (reg:CCC FLAGS_REG) (unspec:CCC [(const_int 0)] UNSPEC_STC))]
2037 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2038 [(set (match_dup 0) (const_int 1))
2039 (parallel
2040 [(set (reg:CCC FLAGS_REG)
2041 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2042 (match_dup 0)))
2043 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2044
2045 ;; Complement carry flag.
2046 (define_insn "*x86_cmc"
2047 [(set (reg:CCC FLAGS_REG)
2048 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2049 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2050 ""
2051 "cmc"
2052 [(set_attr "length" "1")
2053 (set_attr "length_immediate" "0")
2054 (set_attr "use_carry" "1")
2055 (set_attr "modrm" "0")])
2056
2057 ;; On Pentium 4, cmc is replaced with setnc %al;addb $-1,%al.
2058 (define_peephole2
2059 [(match_scratch:QI 0 "r")
2060 (set (reg:CCC FLAGS_REG)
2061 (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
2062 (geu:QI (reg:CCC FLAGS_REG) (const_int 0))))]
2063 "TARGET_SLOW_STC && !optimize_insn_for_size_p ()"
2064 [(set (match_dup 0) (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
2065 (parallel
2066 [(set (reg:CCC FLAGS_REG)
2067 (compare:CCC (plus:QI (match_dup 0) (const_int -1))
2068 (match_dup 0)))
2069 (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))])])
2070 \f
2071 ;; Push/pop instructions.
2072
2073 (define_insn_and_split "*pushv1ti2"
2074 [(set (match_operand:V1TI 0 "push_operand" "=<")
2075 (match_operand:V1TI 1 "register_operand" "v"))]
2076 "TARGET_64BIT && TARGET_STV"
2077 "#"
2078 "&& reload_completed"
2079 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2080 (set (match_dup 0) (match_dup 1))]
2081 {
2082 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
2083 /* Preserve memory attributes. */
2084 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2085 }
2086 [(set_attr "type" "multi")
2087 (set_attr "mode" "TI")])
2088
2089 (define_insn "*push<mode>2"
2090 [(set (match_operand:DWI 0 "push_operand" "=<,<")
2091 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
2092 ""
2093 "#"
2094 [(set_attr "type" "multi")
2095 (set_attr "mode" "<MODE>")])
2096
2097 (define_split
2098 [(set (match_operand:DWI 0 "push_operand")
2099 (match_operand:DWI 1 "general_gr_operand"))]
2100 "reload_completed"
2101 [(const_int 0)]
2102 "ix86_split_long_move (operands); DONE;")
2103
2104 (define_insn "*pushdi2_rex64"
2105 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
2106 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
2107 "TARGET_64BIT"
2108 "@
2109 push{q}\t%1
2110 #
2111 #"
2112 [(set_attr "type" "push,multi,multi")
2113 (set_attr "mode" "DI")])
2114
2115 ;; Convert impossible pushes of immediate to existing instructions.
2116 ;; First try to get scratch register and go through it. In case this
2117 ;; fails, push sign extended lower part first and then overwrite
2118 ;; upper part by 32bit move.
2119
2120 (define_peephole2
2121 [(match_scratch:DI 2 "r")
2122 (set (match_operand:DI 0 "push_operand")
2123 (match_operand:DI 1 "immediate_operand"))]
2124 "TARGET_64BIT
2125 && !symbolic_operand (operands[1], DImode)
2126 && !x86_64_immediate_operand (operands[1], DImode)"
2127 [(set (match_dup 2) (match_dup 1))
2128 (set (match_dup 0) (match_dup 2))])
2129
2130 (define_split
2131 [(set (match_operand:DI 0 "push_operand")
2132 (match_operand:DI 1 "immediate_operand"))]
2133 "TARGET_64BIT && epilogue_completed
2134 && !symbolic_operand (operands[1], DImode)
2135 && !x86_64_immediate_operand (operands[1], DImode)"
2136 [(set (match_dup 0) (match_dup 1))
2137 (set (match_dup 2) (match_dup 3))]
2138 {
2139 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
2140
2141 operands[1] = gen_lowpart (DImode, operands[2]);
2142 operands[2] = gen_rtx_MEM (SImode,
2143 plus_constant (Pmode, stack_pointer_rtx, 4));
2144 })
2145
2146 ;; For TARGET_64BIT we always round up to 8 bytes.
2147 (define_insn "*pushsi2_rex64"
2148 [(set (match_operand:SI 0 "push_operand" "=X,X")
2149 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
2150 "TARGET_64BIT"
2151 "@
2152 push{q}\t%q1
2153 #"
2154 [(set_attr "type" "push,multi")
2155 (set_attr "mode" "DI")])
2156
2157 (define_insn "*pushsi2"
2158 [(set (match_operand:SI 0 "push_operand" "=<,<")
2159 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
2160 "!TARGET_64BIT"
2161 "@
2162 push{l}\t%1
2163 #"
2164 [(set_attr "type" "push,multi")
2165 (set_attr "mode" "SI")])
2166
2167 (define_split
2168 [(set (match_operand:SWI48DWI 0 "push_operand")
2169 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
2170 "TARGET_SSE && reload_completed"
2171 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2172 (set (match_dup 0) (match_dup 1))]
2173 {
2174 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
2175 /* Preserve memory attributes. */
2176 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2177 })
2178
2179 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2180 ;; "push a byte/word". But actually we use push{l,q}, which has
2181 ;; the effect of rounding the amount pushed up to a word.
2182
2183 (define_insn "*push<mode>2"
2184 [(set (match_operand:SWI12 0 "push_operand" "=X")
2185 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
2186 ""
2187 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
2188 [(set_attr "type" "push")
2189 (set (attr "mode")
2190 (if_then_else (match_test "TARGET_64BIT")
2191 (const_string "DI")
2192 (const_string "SI")))])
2193
2194 (define_insn "*push<mode>2_prologue"
2195 [(set (match_operand:W 0 "push_operand" "=<")
2196 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
2197 (clobber (mem:BLK (scratch)))]
2198 ""
2199 "push{<imodesuffix>}\t%1"
2200 [(set_attr "type" "push")
2201 (set_attr "mode" "<MODE>")])
2202
2203 (define_insn "*pop<mode>1"
2204 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2205 (match_operand:W 1 "pop_operand" ">"))]
2206 ""
2207 "pop{<imodesuffix>}\t%0"
2208 [(set_attr "type" "pop")
2209 (set_attr "mode" "<MODE>")])
2210
2211 (define_insn "*pop<mode>1_epilogue"
2212 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
2213 (match_operand:W 1 "pop_operand" ">"))
2214 (clobber (mem:BLK (scratch)))]
2215 ""
2216 "pop{<imodesuffix>}\t%0"
2217 [(set_attr "type" "pop")
2218 (set_attr "mode" "<MODE>")])
2219
2220 (define_insn "*pushfl<mode>2"
2221 [(set (match_operand:W 0 "push_operand" "=<")
2222 (match_operand:W 1 "flags_reg_operand"))]
2223 ""
2224 "pushf{<imodesuffix>}"
2225 [(set_attr "type" "push")
2226 (set_attr "mode" "<MODE>")])
2227
2228 (define_insn "*popfl<mode>1"
2229 [(set (match_operand:W 0 "flags_reg_operand")
2230 (match_operand:W 1 "pop_operand" ">"))]
2231 ""
2232 "popf{<imodesuffix>}"
2233 [(set_attr "type" "pop")
2234 (set_attr "mode" "<MODE>")])
2235
2236 \f
2237 ;; Reload patterns to support multi-word load/store
2238 ;; with non-offsetable address.
2239 (define_expand "reload_noff_store"
2240 [(parallel [(match_operand 0 "memory_operand" "=m")
2241 (match_operand 1 "register_operand" "r")
2242 (match_operand:DI 2 "register_operand" "=&r")])]
2243 "TARGET_64BIT"
2244 {
2245 rtx mem = operands[0];
2246 rtx addr = XEXP (mem, 0);
2247
2248 emit_move_insn (operands[2], addr);
2249 mem = replace_equiv_address_nv (mem, operands[2]);
2250
2251 emit_insn (gen_rtx_SET (mem, operands[1]));
2252 DONE;
2253 })
2254
2255 (define_expand "reload_noff_load"
2256 [(parallel [(match_operand 0 "register_operand" "=r")
2257 (match_operand 1 "memory_operand" "m")
2258 (match_operand:DI 2 "register_operand" "=r")])]
2259 "TARGET_64BIT"
2260 {
2261 rtx mem = operands[1];
2262 rtx addr = XEXP (mem, 0);
2263
2264 emit_move_insn (operands[2], addr);
2265 mem = replace_equiv_address_nv (mem, operands[2]);
2266
2267 emit_insn (gen_rtx_SET (operands[0], mem));
2268 DONE;
2269 })
2270
2271 ;; Move instructions.
2272
2273 (define_expand "movxi"
2274 [(set (match_operand:XI 0 "nonimmediate_operand")
2275 (match_operand:XI 1 "general_operand"))]
2276 "TARGET_AVX512F"
2277 "ix86_expand_vector_move (XImode, operands); DONE;")
2278
2279 (define_expand "movoi"
2280 [(set (match_operand:OI 0 "nonimmediate_operand")
2281 (match_operand:OI 1 "general_operand"))]
2282 "TARGET_AVX"
2283 "ix86_expand_vector_move (OImode, operands); DONE;")
2284
2285 (define_expand "movti"
2286 [(set (match_operand:TI 0 "nonimmediate_operand")
2287 (match_operand:TI 1 "general_operand"))]
2288 "TARGET_64BIT || TARGET_SSE"
2289 {
2290 if (TARGET_64BIT)
2291 ix86_expand_move (TImode, operands);
2292 else
2293 ix86_expand_vector_move (TImode, operands);
2294 DONE;
2295 })
2296
2297 ;; This expands to what emit_move_complex would generate if we didn't
2298 ;; have a movti pattern. Having this avoids problems with reload on
2299 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2300 ;; to have around all the time.
2301 (define_expand "movcdi"
2302 [(set (match_operand:CDI 0 "nonimmediate_operand")
2303 (match_operand:CDI 1 "general_operand"))]
2304 ""
2305 {
2306 if (push_operand (operands[0], CDImode))
2307 emit_move_complex_push (CDImode, operands[0], operands[1]);
2308 else
2309 emit_move_complex_parts (operands[0], operands[1]);
2310 DONE;
2311 })
2312
2313 (define_expand "mov<mode>"
2314 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2315 (match_operand:SWI1248x 1 "general_operand"))]
2316 ""
2317 "ix86_expand_move (<MODE>mode, operands); DONE;")
2318
2319 (define_insn "*mov<mode>_xor"
2320 [(set (match_operand:SWI48 0 "register_operand" "=r")
2321 (match_operand:SWI48 1 "const0_operand"))
2322 (clobber (reg:CC FLAGS_REG))]
2323 "reload_completed"
2324 "xor{l}\t%k0, %k0"
2325 [(set_attr "type" "alu1")
2326 (set_attr "mode" "SI")
2327 (set_attr "length_immediate" "0")])
2328
2329 (define_insn "*mov<mode>_and"
2330 [(set (match_operand:SWI248 0 "memory_operand" "=m")
2331 (match_operand:SWI248 1 "const0_operand"))
2332 (clobber (reg:CC FLAGS_REG))]
2333 "reload_completed"
2334 "and{<imodesuffix>}\t{%1, %0|%0, %1}"
2335 [(set_attr "type" "alu1")
2336 (set_attr "mode" "<MODE>")
2337 (set_attr "length_immediate" "1")])
2338
2339 (define_insn "*mov<mode>_or"
2340 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
2341 (match_operand:SWI248 1 "constm1_operand"))
2342 (clobber (reg:CC FLAGS_REG))]
2343 "reload_completed"
2344 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2345 [(set_attr "type" "alu1")
2346 (set_attr "mode" "<MODE>")
2347 (set_attr "length_immediate" "1")])
2348
2349 (define_insn "*movxi_internal_avx512f"
2350 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2351 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2352 "TARGET_AVX512F
2353 && (register_operand (operands[0], XImode)
2354 || register_operand (operands[1], XImode))"
2355 {
2356 switch (get_attr_type (insn))
2357 {
2358 case TYPE_SSELOG1:
2359 return standard_sse_constant_opcode (insn, operands);
2360
2361 case TYPE_SSEMOV:
2362 return ix86_output_ssemov (insn, operands);
2363
2364 default:
2365 gcc_unreachable ();
2366 }
2367 }
2368 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2369 (set_attr "prefix" "evex")
2370 (set_attr "mode" "XI")])
2371
2372 (define_insn "*movoi_internal_avx"
2373 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2374 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2375 "TARGET_AVX
2376 && (register_operand (operands[0], OImode)
2377 || register_operand (operands[1], OImode))"
2378 {
2379 switch (get_attr_type (insn))
2380 {
2381 case TYPE_SSELOG1:
2382 return standard_sse_constant_opcode (insn, operands);
2383
2384 case TYPE_SSEMOV:
2385 return ix86_output_ssemov (insn, operands);
2386
2387 default:
2388 gcc_unreachable ();
2389 }
2390 }
2391 [(set_attr "isa" "*,avx2,*,*")
2392 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2393 (set_attr "prefix" "vex")
2394 (set_attr "mode" "OI")])
2395
2396 (define_insn "*movti_internal"
2397 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2398 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
2399 "(TARGET_64BIT
2400 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2401 || (TARGET_SSE
2402 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2403 && (register_operand (operands[0], TImode)
2404 || register_operand (operands[1], TImode)))"
2405 {
2406 switch (get_attr_type (insn))
2407 {
2408 case TYPE_MULTI:
2409 return "#";
2410
2411 case TYPE_SSELOG1:
2412 return standard_sse_constant_opcode (insn, operands);
2413
2414 case TYPE_SSEMOV:
2415 return ix86_output_ssemov (insn, operands);
2416
2417 default:
2418 gcc_unreachable ();
2419 }
2420 }
2421 [(set (attr "isa")
2422 (cond [(eq_attr "alternative" "0,1,6,7")
2423 (const_string "x64")
2424 (eq_attr "alternative" "3")
2425 (const_string "sse2")
2426 ]
2427 (const_string "*")))
2428 (set (attr "type")
2429 (cond [(eq_attr "alternative" "0,1,6,7")
2430 (const_string "multi")
2431 (eq_attr "alternative" "2,3")
2432 (const_string "sselog1")
2433 ]
2434 (const_string "ssemov")))
2435 (set (attr "prefix")
2436 (if_then_else (eq_attr "type" "sselog1,ssemov")
2437 (const_string "maybe_vex")
2438 (const_string "orig")))
2439 (set (attr "mode")
2440 (cond [(eq_attr "alternative" "0,1")
2441 (const_string "DI")
2442 (match_test "TARGET_AVX")
2443 (const_string "TI")
2444 (ior (not (match_test "TARGET_SSE2"))
2445 (match_test "optimize_function_for_size_p (cfun)"))
2446 (const_string "V4SF")
2447 (and (eq_attr "alternative" "5")
2448 (match_test "TARGET_SSE_TYPELESS_STORES"))
2449 (const_string "V4SF")
2450 ]
2451 (const_string "TI")))
2452 (set (attr "preferred_for_speed")
2453 (cond [(eq_attr "alternative" "6")
2454 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2455 (eq_attr "alternative" "7")
2456 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2457 ]
2458 (symbol_ref "true")))])
2459
2460 (define_split
2461 [(set (match_operand:TI 0 "sse_reg_operand")
2462 (match_operand:TI 1 "general_reg_operand"))]
2463 "TARGET_64BIT && TARGET_SSE4_1
2464 && reload_completed"
2465 [(set (match_dup 2)
2466 (vec_merge:V2DI
2467 (vec_duplicate:V2DI (match_dup 3))
2468 (match_dup 2)
2469 (const_int 2)))]
2470 {
2471 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2472 operands[3] = gen_highpart (DImode, operands[1]);
2473
2474 emit_move_insn (gen_lowpart (DImode, operands[0]),
2475 gen_lowpart (DImode, operands[1]));
2476 })
2477
2478 (define_insn "*movdi_internal"
2479 [(set (match_operand:DI 0 "nonimmediate_operand"
2480 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,?v,?v,?v,m ,m,?r ,?*Yd,?r,?v,?*y,?*x,*k,*k ,*r,*m,*k")
2481 (match_operand:DI 1 "general_operand"
2482 "riFo,riF,Z,rem,i,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,v,*Yd,r ,?v,r ,*x ,*y ,*r,*kBk,*k,*k,CBC"))]
2483 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2484 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2485 {
2486 switch (get_attr_type (insn))
2487 {
2488 case TYPE_MSKMOV:
2489 return "kmovq\t{%1, %0|%0, %1}";
2490
2491 case TYPE_MSKLOG:
2492 if (operands[1] == const0_rtx)
2493 return "kxorq\t%0, %0, %0";
2494 else if (operands[1] == constm1_rtx)
2495 return "kxnorq\t%0, %0, %0";
2496 gcc_unreachable ();
2497
2498 case TYPE_MULTI:
2499 return "#";
2500
2501 case TYPE_MMX:
2502 return "pxor\t%0, %0";
2503
2504 case TYPE_MMXMOV:
2505 /* Handle broken assemblers that require movd instead of movq. */
2506 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2507 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2508 return "movd\t{%1, %0|%0, %1}";
2509 return "movq\t{%1, %0|%0, %1}";
2510
2511 case TYPE_SSELOG1:
2512 return standard_sse_constant_opcode (insn, operands);
2513
2514 case TYPE_SSEMOV:
2515 return ix86_output_ssemov (insn, operands);
2516
2517 case TYPE_SSECVT:
2518 if (SSE_REG_P (operands[0]))
2519 return "movq2dq\t{%1, %0|%0, %1}";
2520 else
2521 return "movdq2q\t{%1, %0|%0, %1}";
2522
2523 case TYPE_LEA:
2524 return "lea{q}\t{%E1, %0|%0, %E1}";
2525
2526 case TYPE_IMOV:
2527 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2528 if (get_attr_mode (insn) == MODE_SI)
2529 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2530 else if (which_alternative == 4)
2531 return "movabs{q}\t{%1, %0|%0, %1}";
2532 else if (ix86_use_lea_for_mov (insn, operands))
2533 return "lea{q}\t{%E1, %0|%0, %E1}";
2534 else
2535 return "mov{q}\t{%1, %0|%0, %1}";
2536
2537 default:
2538 gcc_unreachable ();
2539 }
2540 }
2541 [(set (attr "isa")
2542 (cond [(eq_attr "alternative" "0,1,17,18")
2543 (const_string "nox64")
2544 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2545 (const_string "x64")
2546 (eq_attr "alternative" "19,20")
2547 (const_string "x64_sse2")
2548 (eq_attr "alternative" "21,22")
2549 (const_string "sse2")
2550 ]
2551 (const_string "*")))
2552 (set (attr "type")
2553 (cond [(eq_attr "alternative" "0,1,17,18")
2554 (const_string "multi")
2555 (eq_attr "alternative" "6")
2556 (const_string "mmx")
2557 (eq_attr "alternative" "7,8,9,10,11")
2558 (const_string "mmxmov")
2559 (eq_attr "alternative" "12")
2560 (const_string "sselog1")
2561 (eq_attr "alternative" "13,14,15,16,19,20")
2562 (const_string "ssemov")
2563 (eq_attr "alternative" "21,22")
2564 (const_string "ssecvt")
2565 (eq_attr "alternative" "23,24,25,26")
2566 (const_string "mskmov")
2567 (eq_attr "alternative" "27")
2568 (const_string "msklog")
2569 (and (match_operand 0 "register_operand")
2570 (match_operand 1 "pic_32bit_operand"))
2571 (const_string "lea")
2572 ]
2573 (const_string "imov")))
2574 (set (attr "modrm")
2575 (if_then_else
2576 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2577 (const_string "0")
2578 (const_string "*")))
2579 (set (attr "length_immediate")
2580 (if_then_else
2581 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2582 (const_string "8")
2583 (const_string "*")))
2584 (set (attr "prefix_rex")
2585 (if_then_else
2586 (eq_attr "alternative" "10,11,19,20")
2587 (const_string "1")
2588 (const_string "*")))
2589 (set (attr "prefix")
2590 (if_then_else (eq_attr "type" "sselog1,ssemov")
2591 (const_string "maybe_vex")
2592 (const_string "orig")))
2593 (set (attr "prefix_data16")
2594 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2595 (const_string "1")
2596 (const_string "*")))
2597 (set (attr "mode")
2598 (cond [(eq_attr "alternative" "2")
2599 (const_string "SI")
2600 (eq_attr "alternative" "12,13")
2601 (cond [(match_test "TARGET_AVX")
2602 (const_string "TI")
2603 (ior (not (match_test "TARGET_SSE2"))
2604 (match_test "optimize_function_for_size_p (cfun)"))
2605 (const_string "V4SF")
2606 ]
2607 (const_string "TI"))
2608
2609 (and (eq_attr "alternative" "14,15,16")
2610 (not (match_test "TARGET_SSE2")))
2611 (const_string "V2SF")
2612 ]
2613 (const_string "DI")))
2614 (set (attr "preferred_for_speed")
2615 (cond [(eq_attr "alternative" "10,17,19")
2616 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2617 (eq_attr "alternative" "11,18,20")
2618 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2619 ]
2620 (symbol_ref "true")))
2621 (set (attr "enabled")
2622 (cond [(eq_attr "alternative" "15")
2623 (if_then_else
2624 (match_test "TARGET_STV && TARGET_SSE2")
2625 (symbol_ref "false")
2626 (const_string "*"))
2627 (eq_attr "alternative" "16")
2628 (if_then_else
2629 (match_test "TARGET_STV && TARGET_SSE2")
2630 (symbol_ref "true")
2631 (symbol_ref "false"))
2632 ]
2633 (const_string "*")))])
2634
2635 (define_split
2636 [(set (match_operand:<DWI> 0 "general_reg_operand")
2637 (match_operand:<DWI> 1 "sse_reg_operand"))]
2638 "TARGET_SSE4_1
2639 && reload_completed"
2640 [(set (match_dup 2)
2641 (vec_select:DWIH
2642 (match_dup 3)
2643 (parallel [(const_int 1)])))]
2644 {
2645 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2646 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2647
2648 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2649 gen_lowpart (<MODE>mode, operands[1]));
2650 })
2651
2652 (define_split
2653 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2654 (match_operand:DWI 1 "general_gr_operand"))]
2655 "reload_completed"
2656 [(const_int 0)]
2657 "ix86_split_long_move (operands); DONE;")
2658
2659 (define_split
2660 [(set (match_operand:DI 0 "sse_reg_operand")
2661 (match_operand:DI 1 "general_reg_operand"))]
2662 "!TARGET_64BIT && TARGET_SSE4_1
2663 && reload_completed"
2664 [(set (match_dup 2)
2665 (vec_merge:V4SI
2666 (vec_duplicate:V4SI (match_dup 3))
2667 (match_dup 2)
2668 (const_int 2)))]
2669 {
2670 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2671 operands[3] = gen_highpart (SImode, operands[1]);
2672
2673 emit_move_insn (gen_lowpart (SImode, operands[0]),
2674 gen_lowpart (SImode, operands[1]));
2675 })
2676
2677 ;; movabsq $0x0012345678000000, %rax is longer
2678 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2679 (define_peephole2
2680 [(set (match_operand:DI 0 "register_operand")
2681 (match_operand:DI 1 "const_int_operand"))]
2682 "TARGET_64BIT
2683 && optimize_insn_for_size_p ()
2684 && LEGACY_INT_REG_P (operands[0])
2685 && !x86_64_immediate_operand (operands[1], DImode)
2686 && !x86_64_zext_immediate_operand (operands[1], DImode)
2687 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2688 & ~(HOST_WIDE_INT) 0xffffffff)
2689 && peep2_regno_dead_p (0, FLAGS_REG)"
2690 [(set (match_dup 0) (match_dup 1))
2691 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2692 (clobber (reg:CC FLAGS_REG))])]
2693 {
2694 int shift = ctz_hwi (UINTVAL (operands[1]));
2695 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2696 operands[2] = gen_int_mode (shift, QImode);
2697 })
2698
2699 (define_insn "*movsi_internal"
2700 [(set (match_operand:SI 0 "nonimmediate_operand"
2701 "=r,m ,*y,*y,?*y,?m,?r,?*y,?v,?v,?v,m ,?r,?v,*k,*k ,*rm,*k")
2702 (match_operand:SI 1 "general_operand"
2703 "g ,re,C ,*y,Bk ,*y,*y,r ,C ,?v,Bk,?v,?v,r ,*r,*kBk,*k ,CBC"))]
2704 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2705 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2706 {
2707 switch (get_attr_type (insn))
2708 {
2709 case TYPE_SSELOG1:
2710 return standard_sse_constant_opcode (insn, operands);
2711
2712 case TYPE_MSKMOV:
2713 return "kmovd\t{%1, %0|%0, %1}";
2714
2715 case TYPE_MSKLOG:
2716 if (operands[1] == const0_rtx)
2717 return "kxord\t%0, %0, %0";
2718 else if (operands[1] == constm1_rtx)
2719 return "kxnord\t%0, %0, %0";
2720 gcc_unreachable ();
2721
2722 case TYPE_SSEMOV:
2723 return ix86_output_ssemov (insn, operands);
2724
2725 case TYPE_MMX:
2726 return "pxor\t%0, %0";
2727
2728 case TYPE_MMXMOV:
2729 switch (get_attr_mode (insn))
2730 {
2731 case MODE_DI:
2732 return "movq\t{%1, %0|%0, %1}";
2733 case MODE_SI:
2734 return "movd\t{%1, %0|%0, %1}";
2735
2736 default:
2737 gcc_unreachable ();
2738 }
2739
2740 case TYPE_LEA:
2741 return "lea{l}\t{%E1, %0|%0, %E1}";
2742
2743 case TYPE_IMOV:
2744 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2745 if (ix86_use_lea_for_mov (insn, operands))
2746 return "lea{l}\t{%E1, %0|%0, %E1}";
2747 else
2748 return "mov{l}\t{%1, %0|%0, %1}";
2749
2750 default:
2751 gcc_unreachable ();
2752 }
2753 }
2754 [(set (attr "isa")
2755 (cond [(eq_attr "alternative" "12,13")
2756 (const_string "sse2")
2757 ]
2758 (const_string "*")))
2759 (set (attr "type")
2760 (cond [(eq_attr "alternative" "2")
2761 (const_string "mmx")
2762 (eq_attr "alternative" "3,4,5,6,7")
2763 (const_string "mmxmov")
2764 (eq_attr "alternative" "8")
2765 (const_string "sselog1")
2766 (eq_attr "alternative" "9,10,11,12,13")
2767 (const_string "ssemov")
2768 (eq_attr "alternative" "14,15,16")
2769 (const_string "mskmov")
2770 (eq_attr "alternative" "17")
2771 (const_string "msklog")
2772 (and (match_operand 0 "register_operand")
2773 (match_operand 1 "pic_32bit_operand"))
2774 (const_string "lea")
2775 ]
2776 (const_string "imov")))
2777 (set (attr "prefix")
2778 (if_then_else (eq_attr "type" "sselog1,ssemov")
2779 (const_string "maybe_vex")
2780 (const_string "orig")))
2781 (set (attr "prefix_data16")
2782 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2783 (const_string "1")
2784 (const_string "*")))
2785 (set (attr "mode")
2786 (cond [(eq_attr "alternative" "2,3")
2787 (const_string "DI")
2788 (eq_attr "alternative" "8,9")
2789 (cond [(match_test "TARGET_AVX")
2790 (const_string "TI")
2791 (ior (not (match_test "TARGET_SSE2"))
2792 (match_test "optimize_function_for_size_p (cfun)"))
2793 (const_string "V4SF")
2794 ]
2795 (const_string "TI"))
2796
2797 (and (eq_attr "alternative" "10,11")
2798 (not (match_test "TARGET_SSE2")))
2799 (const_string "SF")
2800 ]
2801 (const_string "SI")))
2802 (set (attr "preferred_for_speed")
2803 (cond [(eq_attr "alternative" "6,12")
2804 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2805 (eq_attr "alternative" "7,13")
2806 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2807 ]
2808 (symbol_ref "true")))])
2809
2810 ;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg.
2811 (define_peephole2
2812 [(set (match_operand:SWI248 0 "general_reg_operand")
2813 (match_operand:SWI248 1 "const_int_operand"))]
2814 "optimize_insn_for_size_p () && optimize_size > 1
2815 && operands[1] != const0_rtx
2816 && IN_RANGE (INTVAL (operands[1]), -128, 127)
2817 && !ix86_red_zone_used
2818 && REGNO (operands[0]) != SP_REG"
2819 [(set (match_dup 2) (match_dup 1))
2820 (set (match_dup 0) (match_dup 3))]
2821 {
2822 if (GET_MODE (operands[0]) != word_mode)
2823 operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0]));
2824
2825 operands[2] = gen_rtx_MEM (word_mode,
2826 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2827 operands[3] = gen_rtx_MEM (word_mode,
2828 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2829 })
2830
2831 ;; With -Oz, transform mov $0,mem to the shorter and $0,mem.
2832 ;; Likewise, transform mov $-1,mem to the shorter or $-1,mem.
2833 (define_peephole2
2834 [(set (match_operand:SWI248 0 "memory_operand")
2835 (match_operand:SWI248 1 "const_int_operand"))]
2836 "(operands[1] == const0_rtx || operands[1] == constm1_rtx)
2837 && optimize_insn_for_size_p () && optimize_size > 1
2838 && peep2_regno_dead_p (0, FLAGS_REG)"
2839 [(parallel [(set (match_dup 0) (match_dup 1))
2840 (clobber (reg:CC FLAGS_REG))])])
2841
2842 (define_insn "*movhi_internal"
2843 [(set (match_operand:HI 0 "nonimmediate_operand"
2844 "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*v,*v,*v,m")
2845 (match_operand:HI 1 "general_operand"
2846 "r ,n,m,rn,r ,*km,*k,*k,CBC,*v,r ,C ,*v,m ,*v"))]
2847 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2848 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2849 {
2850 switch (get_attr_type (insn))
2851 {
2852 case TYPE_IMOVX:
2853 /* movzwl is faster than movw on p2 due to partial word stalls,
2854 though not as fast as an aligned movl. */
2855 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2856
2857 case TYPE_MSKMOV:
2858 switch (which_alternative)
2859 {
2860 case 4:
2861 return "kmovw\t{%k1, %0|%0, %k1}";
2862 case 6:
2863 return "kmovw\t{%1, %k0|%k0, %1}";
2864 case 5:
2865 case 7:
2866 return "kmovw\t{%1, %0|%0, %1}";
2867 default:
2868 gcc_unreachable ();
2869 }
2870
2871 case TYPE_SSEMOV:
2872 return ix86_output_ssemov (insn, operands);
2873
2874 case TYPE_SSELOG1:
2875 if (satisfies_constraint_C (operands[1]))
2876 return standard_sse_constant_opcode (insn, operands);
2877
2878 if (SSE_REG_P (operands[0]))
2879 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
2880 else
2881 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
2882
2883 case TYPE_MSKLOG:
2884 if (operands[1] == const0_rtx)
2885 return "kxorw\t%0, %0, %0";
2886 else if (operands[1] == constm1_rtx)
2887 return "kxnorw\t%0, %0, %0";
2888 gcc_unreachable ();
2889
2890 default:
2891 if (get_attr_mode (insn) == MODE_SI)
2892 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2893 else
2894 return "mov{w}\t{%1, %0|%0, %1}";
2895 }
2896 }
2897 [(set (attr "isa")
2898 (cond [(eq_attr "alternative" "9,10,11,12,13")
2899 (const_string "sse2")
2900 (eq_attr "alternative" "14")
2901 (const_string "sse4")
2902 ]
2903 (const_string "*")))
2904 (set (attr "type")
2905 (cond [(eq_attr "alternative" "4,5,6,7")
2906 (const_string "mskmov")
2907 (eq_attr "alternative" "8")
2908 (const_string "msklog")
2909 (eq_attr "alternative" "13,14")
2910 (if_then_else (match_test "TARGET_AVX512FP16")
2911 (const_string "ssemov")
2912 (const_string "sselog1"))
2913 (eq_attr "alternative" "11")
2914 (const_string "sselog1")
2915 (eq_attr "alternative" "9,10,12")
2916 (const_string "ssemov")
2917 (match_test "optimize_function_for_size_p (cfun)")
2918 (const_string "imov")
2919 (and (eq_attr "alternative" "0")
2920 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2921 (not (match_test "TARGET_HIMODE_MATH"))))
2922 (const_string "imov")
2923 (and (eq_attr "alternative" "1,2")
2924 (match_operand:HI 1 "aligned_operand"))
2925 (const_string "imov")
2926 (and (match_test "TARGET_MOVX")
2927 (eq_attr "alternative" "0,2"))
2928 (const_string "imovx")
2929 ]
2930 (const_string "imov")))
2931 (set (attr "prefix")
2932 (cond [(eq_attr "alternative" "4,5,6,7,8")
2933 (const_string "vex")
2934 (eq_attr "alternative" "9,10,11,12,13,14")
2935 (const_string "maybe_evex")
2936 ]
2937 (const_string "orig")))
2938 (set (attr "mode")
2939 (cond [(eq_attr "alternative" "9,10")
2940 (if_then_else (match_test "TARGET_AVX512FP16")
2941 (const_string "HI")
2942 (const_string "SI"))
2943 (eq_attr "alternative" "13,14")
2944 (if_then_else (match_test "TARGET_AVX512FP16")
2945 (const_string "HI")
2946 (const_string "TI"))
2947 (eq_attr "alternative" "11")
2948 (cond [(match_test "TARGET_AVX")
2949 (const_string "TI")
2950 (ior (not (match_test "TARGET_SSE2"))
2951 (match_test "optimize_function_for_size_p (cfun)"))
2952 (const_string "V4SF")
2953 ]
2954 (const_string "TI"))
2955 (eq_attr "alternative" "12")
2956 (cond [(match_test "TARGET_AVX512FP16")
2957 (const_string "HF")
2958 (match_test "TARGET_AVX")
2959 (const_string "TI")
2960 (ior (not (match_test "TARGET_SSE2"))
2961 (match_test "optimize_function_for_size_p (cfun)"))
2962 (const_string "V4SF")
2963 ]
2964 (const_string "TI"))
2965 (eq_attr "type" "imovx")
2966 (const_string "SI")
2967 (and (eq_attr "alternative" "1,2")
2968 (match_operand:HI 1 "aligned_operand"))
2969 (const_string "SI")
2970 (and (eq_attr "alternative" "0")
2971 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2972 (not (match_test "TARGET_HIMODE_MATH"))))
2973 (const_string "SI")
2974 ]
2975 (const_string "HI")))
2976 (set (attr "preferred_for_speed")
2977 (cond [(eq_attr "alternative" "9")
2978 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2979 (eq_attr "alternative" "10")
2980 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2981 ]
2982 (symbol_ref "true")))])
2983
2984 ;; Situation is quite tricky about when to choose full sized (SImode) move
2985 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2986 ;; partial register dependency machines (such as AMD Athlon), where QImode
2987 ;; moves issue extra dependency and for partial register stalls machines
2988 ;; that don't use QImode patterns (and QImode move cause stall on the next
2989 ;; instruction).
2990 ;;
2991 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2992 ;; register stall machines with, where we use QImode instructions, since
2993 ;; partial register stall can be caused there. Then we use movzx.
2994
2995 (define_insn "*movqi_internal"
2996 [(set (match_operand:QI 0 "nonimmediate_operand"
2997 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
2998 (match_operand:QI 1 "general_operand"
2999 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
3000 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3001 && ix86_hardreg_mov_ok (operands[0], operands[1])"
3002
3003 {
3004 char buf[128];
3005 const char *ops;
3006 const char *suffix;
3007
3008 switch (get_attr_type (insn))
3009 {
3010 case TYPE_IMOVX:
3011 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
3012 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
3013
3014 case TYPE_MSKMOV:
3015 switch (which_alternative)
3016 {
3017 case 9:
3018 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
3019 break;
3020 case 11:
3021 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
3022 break;
3023 case 12:
3024 case 13:
3025 gcc_assert (TARGET_AVX512DQ);
3026 /* FALLTHRU */
3027 case 10:
3028 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
3029 break;
3030 default:
3031 gcc_unreachable ();
3032 }
3033
3034 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
3035
3036 snprintf (buf, sizeof (buf), ops, suffix);
3037 output_asm_insn (buf, operands);
3038 return "";
3039
3040 case TYPE_MSKLOG:
3041 if (operands[1] == const0_rtx)
3042 {
3043 if (get_attr_mode (insn) == MODE_HI)
3044 return "kxorw\t%0, %0, %0";
3045 else
3046 return "kxorb\t%0, %0, %0";
3047 }
3048 else if (operands[1] == constm1_rtx)
3049 {
3050 gcc_assert (TARGET_AVX512DQ);
3051 return "kxnorb\t%0, %0, %0";
3052 }
3053 gcc_unreachable ();
3054
3055 default:
3056 if (get_attr_mode (insn) == MODE_SI)
3057 return "mov{l}\t{%k1, %k0|%k0, %k1}";
3058 else
3059 return "mov{b}\t{%1, %0|%0, %1}";
3060 }
3061 }
3062 [(set (attr "isa")
3063 (cond [(eq_attr "alternative" "1,2")
3064 (const_string "x64")
3065 (eq_attr "alternative" "12,13,15")
3066 (const_string "avx512dq")
3067 ]
3068 (const_string "*")))
3069 (set (attr "type")
3070 (cond [(eq_attr "alternative" "9,10,11,12,13")
3071 (const_string "mskmov")
3072 (eq_attr "alternative" "14,15")
3073 (const_string "msklog")
3074 (and (eq_attr "alternative" "7")
3075 (not (match_operand:QI 1 "aligned_operand")))
3076 (const_string "imovx")
3077 (match_test "optimize_function_for_size_p (cfun)")
3078 (const_string "imov")
3079 (and (eq_attr "alternative" "5")
3080 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
3081 (not (match_test "TARGET_QIMODE_MATH"))))
3082 (const_string "imov")
3083 (eq_attr "alternative" "5,7")
3084 (const_string "imovx")
3085 (and (match_test "TARGET_MOVX")
3086 (eq_attr "alternative" "4"))
3087 (const_string "imovx")
3088 ]
3089 (const_string "imov")))
3090 (set (attr "prefix")
3091 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
3092 (const_string "vex")
3093 (const_string "orig")))
3094 (set (attr "mode")
3095 (cond [(eq_attr "alternative" "5,6,7")
3096 (const_string "SI")
3097 (eq_attr "alternative" "8")
3098 (const_string "QI")
3099 (and (eq_attr "alternative" "9,10,11,14")
3100 (not (match_test "TARGET_AVX512DQ")))
3101 (const_string "HI")
3102 (eq_attr "type" "imovx")
3103 (const_string "SI")
3104 ;; For -Os, 8-bit immediates are always shorter than 32-bit
3105 ;; ones.
3106 (and (eq_attr "type" "imov")
3107 (and (eq_attr "alternative" "3")
3108 (match_test "optimize_function_for_size_p (cfun)")))
3109 (const_string "QI")
3110 ;; For -Os, movl where one or both operands are NON_Q_REGS
3111 ;; and both are LEGACY_REGS is shorter than movb.
3112 ;; Otherwise movb and movl sizes are the same, so decide purely
3113 ;; based on speed factors.
3114 (and (eq_attr "type" "imov")
3115 (and (eq_attr "alternative" "1")
3116 (match_test "optimize_function_for_size_p (cfun)")))
3117 (const_string "SI")
3118 (and (eq_attr "type" "imov")
3119 (and (eq_attr "alternative" "0,1,2,3")
3120 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
3121 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
3122 (const_string "SI")
3123 ;; Avoid partial register stalls when not using QImode arithmetic
3124 (and (eq_attr "type" "imov")
3125 (and (eq_attr "alternative" "0,1,2,3")
3126 (and (match_test "TARGET_PARTIAL_REG_STALL")
3127 (not (match_test "TARGET_QIMODE_MATH")))))
3128 (const_string "SI")
3129 ]
3130 (const_string "QI")))])
3131
3132 /* Reload dislikes loading 0/-1 directly into mask registers.
3133 Try to tidy things up here. */
3134 (define_peephole2
3135 [(set (match_operand:SWI 0 "general_reg_operand")
3136 (match_operand:SWI 1 "immediate_operand"))
3137 (set (match_operand:SWI 2 "mask_reg_operand")
3138 (match_dup 0))]
3139 "peep2_reg_dead_p (2, operands[0])
3140 && (const0_operand (operands[1], <MODE>mode)
3141 || (constm1_operand (operands[1], <MODE>mode)
3142 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
3143 [(set (match_dup 2) (match_dup 1))])
3144
3145 ;; Stores and loads of ax to arbitrary constant address.
3146 ;; We fake an second form of instruction to force reload to load address
3147 ;; into register when rax is not available
3148 (define_insn "*movabs<mode>_1"
3149 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
3150 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
3151 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
3152 {
3153 /* Recover the full memory rtx. */
3154 operands[0] = SET_DEST (PATTERN (insn));
3155 switch (which_alternative)
3156 {
3157 case 0:
3158 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
3159 case 1:
3160 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3161 default:
3162 gcc_unreachable ();
3163 }
3164 }
3165 [(set_attr "type" "imov")
3166 (set_attr "modrm" "0,*")
3167 (set_attr "length_address" "8,0")
3168 (set_attr "length_immediate" "0,*")
3169 (set_attr "memory" "store")
3170 (set_attr "mode" "<MODE>")])
3171
3172 (define_insn "*movabs<mode>_2"
3173 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
3174 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
3175 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
3176 {
3177 /* Recover the full memory rtx. */
3178 operands[1] = SET_SRC (PATTERN (insn));
3179 switch (which_alternative)
3180 {
3181 case 0:
3182 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
3183 case 1:
3184 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
3185 default:
3186 gcc_unreachable ();
3187 }
3188 }
3189 [(set_attr "type" "imov")
3190 (set_attr "modrm" "0,*")
3191 (set_attr "length_address" "8,0")
3192 (set_attr "length_immediate" "0")
3193 (set_attr "memory" "load")
3194 (set_attr "mode" "<MODE>")])
3195
3196 (define_insn "swap<mode>"
3197 [(set (match_operand:SWI48 0 "register_operand" "+r")
3198 (match_operand:SWI48 1 "register_operand" "+r"))
3199 (set (match_dup 1)
3200 (match_dup 0))]
3201 ""
3202 "xchg{<imodesuffix>}\t%1, %0"
3203 [(set_attr "type" "imov")
3204 (set_attr "mode" "<MODE>")
3205 (set_attr "pent_pair" "np")
3206 (set_attr "athlon_decode" "vector")
3207 (set_attr "amdfam10_decode" "double")
3208 (set_attr "bdver1_decode" "double")])
3209
3210 (define_insn "*swap<mode>"
3211 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
3212 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
3213 (set (match_dup 1)
3214 (match_dup 0))]
3215 ""
3216 "@
3217 xchg{<imodesuffix>}\t%1, %0
3218 xchg{l}\t%k1, %k0"
3219 [(set_attr "type" "imov")
3220 (set_attr "mode" "<MODE>,SI")
3221 (set (attr "preferred_for_size")
3222 (cond [(eq_attr "alternative" "0")
3223 (symbol_ref "false")]
3224 (symbol_ref "true")))
3225 ;; Potential partial reg stall on alternative 1.
3226 (set (attr "preferred_for_speed")
3227 (cond [(eq_attr "alternative" "1")
3228 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
3229 (symbol_ref "true")))
3230 (set_attr "pent_pair" "np")
3231 (set_attr "athlon_decode" "vector")
3232 (set_attr "amdfam10_decode" "double")
3233 (set_attr "bdver1_decode" "double")])
3234
3235 (define_peephole2
3236 [(set (match_operand:SWI 0 "general_reg_operand")
3237 (match_operand:SWI 1 "general_reg_operand"))
3238 (set (match_dup 1)
3239 (match_operand:SWI 2 "general_reg_operand"))
3240 (set (match_dup 2) (match_dup 0))]
3241 "peep2_reg_dead_p (3, operands[0])
3242 && optimize_insn_for_size_p ()"
3243 [(parallel [(set (match_dup 1) (match_dup 2))
3244 (set (match_dup 2) (match_dup 1))])])
3245
3246 ;; Convert moves to/from AX_REG into xchg with -Oz.
3247 (define_peephole2
3248 [(set (match_operand:SWI48 0 "general_reg_operand")
3249 (match_operand:SWI48 1 "general_reg_operand"))]
3250 "optimize_size > 1
3251 && ((REGNO (operands[0]) == AX_REG)
3252 != (REGNO (operands[1]) == AX_REG))
3253 && optimize_insn_for_size_p ()
3254 && peep2_reg_dead_p (1, operands[1])"
3255 [(parallel [(set (match_dup 0) (match_dup 1))
3256 (set (match_dup 1) (match_dup 0))])])
3257
3258 (define_expand "movstrict<mode>"
3259 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3260 (match_operand:SWI12 1 "general_operand"))]
3261 ""
3262 {
3263 gcc_assert (SUBREG_P (operands[0]));
3264 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3265 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3266 FAIL;
3267 })
3268
3269 (define_insn "*movstrict<mode>_1"
3270 [(set (strict_low_part
3271 (match_operand:SWI12 0 "register_operand" "+<r>"))
3272 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3273 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3274 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3275 [(set_attr "type" "imov")
3276 (set_attr "mode" "<MODE>")])
3277
3278 (define_insn "*movstrict<mode>_xor"
3279 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3280 (match_operand:SWI12 1 "const0_operand"))
3281 (clobber (reg:CC FLAGS_REG))]
3282 "reload_completed"
3283 "xor{<imodesuffix>}\t%0, %0"
3284 [(set_attr "type" "alu1")
3285 (set_attr "mode" "<MODE>")
3286 (set_attr "length_immediate" "0")])
3287
3288 (define_expand "extv<mode>"
3289 [(set (match_operand:SWI24 0 "register_operand")
3290 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3291 (match_operand:SI 2 "const_int_operand")
3292 (match_operand:SI 3 "const_int_operand")))]
3293 ""
3294 {
3295 /* Handle extractions from %ah et al. */
3296 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3297 FAIL;
3298
3299 unsigned int regno = reg_or_subregno (operands[1]);
3300
3301 /* Be careful to expand only with registers having upper parts. */
3302 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3303 operands[1] = copy_to_reg (operands[1]);
3304 })
3305
3306 (define_insn "*extv<mode>"
3307 [(set (match_operand:SWI24 0 "register_operand" "=R")
3308 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3309 (const_int 8)
3310 (const_int 8)))]
3311 ""
3312 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3313 [(set_attr "type" "imovx")
3314 (set_attr "mode" "SI")])
3315
3316 (define_expand "extzv<mode>"
3317 [(set (match_operand:SWI248 0 "register_operand")
3318 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3319 (match_operand:SI 2 "const_int_operand")
3320 (match_operand:SI 3 "const_int_operand")))]
3321 ""
3322 {
3323 if (ix86_expand_pextr (operands))
3324 DONE;
3325
3326 /* Handle extractions from %ah et al. */
3327 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3328 FAIL;
3329
3330 unsigned int regno = reg_or_subregno (operands[1]);
3331
3332 /* Be careful to expand only with registers having upper parts. */
3333 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3334 operands[1] = copy_to_reg (operands[1]);
3335 })
3336
3337 (define_insn "*extzv<mode>"
3338 [(set (match_operand:SWI248 0 "register_operand" "=R")
3339 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3340 (const_int 8)
3341 (const_int 8)))]
3342 ""
3343 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3344 [(set_attr "type" "imovx")
3345 (set_attr "mode" "SI")])
3346
3347 (define_insn "*extzvqi_mem_rex64"
3348 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
3349 (subreg:QI
3350 (match_operator:SWI248 2 "extract_operator"
3351 [(match_operand 1 "int248_register_operand" "Q")
3352 (const_int 8)
3353 (const_int 8)]) 0))]
3354 "TARGET_64BIT && reload_completed"
3355 "mov{b}\t{%h1, %0|%0, %h1}"
3356 [(set_attr "type" "imov")
3357 (set_attr "mode" "QI")])
3358
3359 (define_insn "*extzvqi"
3360 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
3361 (subreg:QI
3362 (match_operator:SWI248 2 "extract_operator"
3363 [(match_operand 1 "int248_register_operand" "Q,Q,Q")
3364 (const_int 8)
3365 (const_int 8)]) 0))]
3366 ""
3367 {
3368 switch (get_attr_type (insn))
3369 {
3370 case TYPE_IMOVX:
3371 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3372 default:
3373 return "mov{b}\t{%h1, %0|%0, %h1}";
3374 }
3375 }
3376 [(set_attr "isa" "*,*,nox64")
3377 (set (attr "type")
3378 (if_then_else (and (match_operand:QI 0 "register_operand")
3379 (ior (not (match_operand:QI 0 "QIreg_operand"))
3380 (match_test "TARGET_MOVX")))
3381 (const_string "imovx")
3382 (const_string "imov")))
3383 (set (attr "mode")
3384 (if_then_else (eq_attr "type" "imovx")
3385 (const_string "SI")
3386 (const_string "QI")))])
3387
3388 (define_peephole2
3389 [(set (match_operand:QI 0 "register_operand")
3390 (subreg:QI
3391 (match_operator:SWI248 3 "extract_operator"
3392 [(match_operand 1 "int248_register_operand")
3393 (const_int 8)
3394 (const_int 8)]) 0))
3395 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
3396 "TARGET_64BIT
3397 && peep2_reg_dead_p (2, operands[0])"
3398 [(set (match_dup 2)
3399 (subreg:QI
3400 (match_op_dup 3
3401 [(match_dup 1)
3402 (const_int 8)
3403 (const_int 8)]) 0))])
3404
3405 (define_expand "insv<mode>"
3406 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3407 (match_operand:SI 1 "const_int_operand")
3408 (match_operand:SI 2 "const_int_operand"))
3409 (match_operand:SWI248 3 "register_operand"))]
3410 ""
3411 {
3412 rtx dst;
3413
3414 if (ix86_expand_pinsr (operands))
3415 DONE;
3416
3417 /* Handle insertions to %ah et al. */
3418 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3419 FAIL;
3420
3421 unsigned int regno = reg_or_subregno (operands[0]);
3422
3423 /* Be careful to expand only with registers having upper parts. */
3424 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3425 dst = copy_to_reg (operands[0]);
3426 else
3427 dst = operands[0];
3428
3429 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3430
3431 /* Fix up the destination if needed. */
3432 if (dst != operands[0])
3433 emit_move_insn (operands[0], dst);
3434
3435 DONE;
3436 })
3437
3438 (define_insn "*insvqi_1_mem_rex64"
3439 [(set (zero_extract:SWI248
3440 (match_operand 0 "int248_register_operand" "+Q")
3441 (const_int 8)
3442 (const_int 8))
3443 (subreg:SWI248
3444 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3445 "TARGET_64BIT && reload_completed"
3446 "mov{b}\t{%1, %h0|%h0, %1}"
3447 [(set_attr "type" "imov")
3448 (set_attr "mode" "QI")])
3449
3450 (define_insn "@insv<mode>_1"
3451 [(set (zero_extract:SWI248
3452 (match_operand 0 "int248_register_operand" "+Q,Q")
3453 (const_int 8)
3454 (const_int 8))
3455 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3456 ""
3457 {
3458 if (CONST_INT_P (operands[1]))
3459 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3460 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3461 }
3462 [(set_attr "isa" "*,nox64")
3463 (set_attr "type" "imov")
3464 (set_attr "mode" "QI")])
3465
3466 (define_insn "*insvqi_1"
3467 [(set (zero_extract:SWI248
3468 (match_operand 0 "int248_register_operand" "+Q,Q")
3469 (const_int 8)
3470 (const_int 8))
3471 (subreg:SWI248
3472 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3473 ""
3474 "mov{b}\t{%1, %h0|%h0, %1}"
3475 [(set_attr "isa" "*,nox64")
3476 (set_attr "type" "imov")
3477 (set_attr "mode" "QI")])
3478
3479 (define_peephole2
3480 [(set (match_operand:QI 0 "register_operand")
3481 (match_operand:QI 1 "norex_memory_operand"))
3482 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3483 (const_int 8)
3484 (const_int 8))
3485 (subreg:SWI248 (match_dup 0) 0))]
3486 "TARGET_64BIT
3487 && peep2_reg_dead_p (2, operands[0])"
3488 [(set (zero_extract:SWI248 (match_dup 2)
3489 (const_int 8)
3490 (const_int 8))
3491 (subreg:SWI248 (match_dup 1) 0))])
3492
3493 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3494 (define_peephole2
3495 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3496 (const_int 0))
3497 (clobber (reg:CC FLAGS_REG))])
3498 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3499 (const_int 8)
3500 (const_int 8))
3501 (const_int 0))]
3502 "REGNO (operands[0]) == REGNO (operands[1])"
3503 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3504 (const_int 0))
3505 (clobber (reg:CC FLAGS_REG))])])
3506
3507 ;; Combine movl followed by movb.
3508 (define_peephole2
3509 [(set (match_operand:SWI48 0 "general_reg_operand")
3510 (match_operand:SWI48 1 "const_int_operand"))
3511 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3512 (const_int 8)
3513 (const_int 8))
3514 (match_operand:SWI248 3 "const_int_operand"))]
3515 "REGNO (operands[0]) == REGNO (operands[2])"
3516 [(set (match_operand:SWI48 0 "general_reg_operand")
3517 (match_dup 4))]
3518 {
3519 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3520 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3521 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3522 })
3523
3524 (define_insn "*insvqi_2"
3525 [(set (zero_extract:SWI248
3526 (match_operand 0 "int248_register_operand" "+Q")
3527 (const_int 8)
3528 (const_int 8))
3529 (match_operator:SWI248 2 "extract_operator"
3530 [(match_operand 1 "int248_register_operand" "Q")
3531 (const_int 8)
3532 (const_int 8)]))]
3533 ""
3534 "mov{b}\t{%h1, %h0|%h0, %h1}"
3535 [(set_attr "type" "imov")
3536 (set_attr "mode" "QI")])
3537
3538 (define_insn "*insvqi_3"
3539 [(set (zero_extract:SWI248
3540 (match_operand 0 "int248_register_operand" "+Q")
3541 (const_int 8)
3542 (const_int 8))
3543 (any_shiftrt:SWI248
3544 (match_operand:SWI248 1 "register_operand" "Q")
3545 (const_int 8)))]
3546 ""
3547 "mov{b}\t{%h1, %h0|%h0, %h1}"
3548 [(set_attr "type" "imov")
3549 (set_attr "mode" "QI")])
3550
3551 (define_code_iterator any_or_plus [plus ior xor])
3552
3553 (define_insn_and_split "*insvti_highpart_1"
3554 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3555 (any_or_plus:TI
3556 (and:TI
3557 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3558 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3559 (ashift:TI
3560 (zero_extend:TI
3561 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3562 (const_int 64))))]
3563 "TARGET_64BIT
3564 && CONST_WIDE_INT_P (operands[3])
3565 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3566 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3567 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3568 "#"
3569 "&& reload_completed"
3570 [(const_int 0)]
3571 {
3572 operands[4] = gen_lowpart (DImode, operands[1]);
3573 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3574 DONE;
3575 })
3576 \f
3577 ;; Floating point push instructions.
3578
3579 (define_insn "*pushtf"
3580 [(set (match_operand:TF 0 "push_operand" "=<,<")
3581 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3582 "TARGET_64BIT || TARGET_SSE"
3583 {
3584 /* This insn should be already split before reg-stack. */
3585 return "#";
3586 }
3587 [(set_attr "isa" "*,x64")
3588 (set_attr "type" "multi")
3589 (set_attr "unit" "sse,*")
3590 (set_attr "mode" "TF,DI")])
3591
3592 ;; %%% Kill this when call knows how to work this out.
3593 (define_split
3594 [(set (match_operand:TF 0 "push_operand")
3595 (match_operand:TF 1 "sse_reg_operand"))]
3596 "TARGET_SSE && reload_completed"
3597 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3598 (set (match_dup 0) (match_dup 1))]
3599 {
3600 /* Preserve memory attributes. */
3601 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3602 })
3603
3604 (define_insn "*pushxf"
3605 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3606 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3607 ""
3608 {
3609 /* This insn should be already split before reg-stack. */
3610 return "#";
3611 }
3612 [(set_attr "isa" "*,*,*,nox64,x64")
3613 (set_attr "type" "multi")
3614 (set_attr "unit" "i387,*,*,*,*")
3615 (set (attr "mode")
3616 (cond [(eq_attr "alternative" "1,2,3,4")
3617 (if_then_else (match_test "TARGET_64BIT")
3618 (const_string "DI")
3619 (const_string "SI"))
3620 ]
3621 (const_string "XF")))
3622 (set (attr "preferred_for_size")
3623 (cond [(eq_attr "alternative" "1")
3624 (symbol_ref "false")]
3625 (symbol_ref "true")))])
3626
3627 ;; %%% Kill this when call knows how to work this out.
3628 (define_split
3629 [(set (match_operand:XF 0 "push_operand")
3630 (match_operand:XF 1 "fp_register_operand"))]
3631 "reload_completed"
3632 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3633 (set (match_dup 0) (match_dup 1))]
3634 {
3635 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3636 /* Preserve memory attributes. */
3637 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3638 })
3639
3640 (define_insn "*pushdf"
3641 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3642 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3643 ""
3644 {
3645 /* This insn should be already split before reg-stack. */
3646 return "#";
3647 }
3648 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3649 (set_attr "type" "multi")
3650 (set_attr "unit" "i387,*,*,*,*,sse")
3651 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3652 (set (attr "preferred_for_size")
3653 (cond [(eq_attr "alternative" "1")
3654 (symbol_ref "false")]
3655 (symbol_ref "true")))
3656 (set (attr "preferred_for_speed")
3657 (cond [(eq_attr "alternative" "1")
3658 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3659 (symbol_ref "true")))])
3660
3661 ;; %%% Kill this when call knows how to work this out.
3662 (define_split
3663 [(set (match_operand:DF 0 "push_operand")
3664 (match_operand:DF 1 "any_fp_register_operand"))]
3665 "reload_completed"
3666 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3667 (set (match_dup 0) (match_dup 1))]
3668 {
3669 /* Preserve memory attributes. */
3670 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3671 })
3672
3673 (define_mode_iterator HFBF [HF BF])
3674
3675 (define_insn "*push<mode>_rex64"
3676 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3677 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3678 "TARGET_64BIT"
3679 {
3680 /* Anything else should be already split before reg-stack. */
3681 gcc_assert (which_alternative == 0);
3682 return "push{q}\t%q1";
3683 }
3684 [(set_attr "isa" "*,sse4")
3685 (set_attr "type" "push,multi")
3686 (set_attr "mode" "DI,TI")])
3687
3688 (define_insn "*push<mode>"
3689 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3690 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3691 "!TARGET_64BIT"
3692 {
3693 /* Anything else should be already split before reg-stack. */
3694 gcc_assert (which_alternative == 0);
3695 return "push{l}\t%k1";
3696 }
3697 [(set_attr "isa" "*,sse4")
3698 (set_attr "type" "push,multi")
3699 (set_attr "mode" "SI,TI")])
3700
3701 (define_insn "*pushsf_rex64"
3702 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3703 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3704 "TARGET_64BIT"
3705 {
3706 /* Anything else should be already split before reg-stack. */
3707 if (which_alternative != 1)
3708 return "#";
3709 return "push{q}\t%q1";
3710 }
3711 [(set_attr "type" "multi,push,multi")
3712 (set_attr "unit" "i387,*,*")
3713 (set_attr "mode" "SF,DI,SF")])
3714
3715 (define_insn "*pushsf"
3716 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3717 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3718 "!TARGET_64BIT"
3719 {
3720 /* Anything else should be already split before reg-stack. */
3721 if (which_alternative != 1)
3722 return "#";
3723 return "push{l}\t%1";
3724 }
3725 [(set_attr "type" "multi,push,multi")
3726 (set_attr "unit" "i387,*,*")
3727 (set_attr "mode" "SF,SI,SF")])
3728
3729 (define_mode_iterator MODESH [SF HF BF])
3730 ;; %%% Kill this when call knows how to work this out.
3731 (define_split
3732 [(set (match_operand:MODESH 0 "push_operand")
3733 (match_operand:MODESH 1 "any_fp_register_operand"))]
3734 "reload_completed"
3735 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3736 (set (match_dup 0) (match_dup 1))]
3737 {
3738 rtx op = XEXP (operands[0], 0);
3739 if (GET_CODE (op) == PRE_DEC)
3740 {
3741 gcc_assert (!TARGET_64BIT);
3742 op = GEN_INT (-4);
3743 }
3744 else
3745 {
3746 op = XEXP (XEXP (op, 1), 1);
3747 gcc_assert (CONST_INT_P (op));
3748 }
3749 operands[2] = op;
3750 /* Preserve memory attributes. */
3751 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3752 })
3753
3754 (define_split
3755 [(set (match_operand:SF 0 "push_operand")
3756 (match_operand:SF 1 "memory_operand"))]
3757 "reload_completed
3758 && find_constant_src (insn)"
3759 [(set (match_dup 0) (match_dup 2))]
3760 "operands[2] = find_constant_src (curr_insn);")
3761
3762 (define_split
3763 [(set (match_operand 0 "push_operand")
3764 (match_operand 1 "general_gr_operand"))]
3765 "reload_completed
3766 && (GET_MODE (operands[0]) == TFmode
3767 || GET_MODE (operands[0]) == XFmode
3768 || GET_MODE (operands[0]) == DFmode)"
3769 [(const_int 0)]
3770 "ix86_split_long_move (operands); DONE;")
3771 \f
3772 ;; Floating point move instructions.
3773
3774 (define_expand "movtf"
3775 [(set (match_operand:TF 0 "nonimmediate_operand")
3776 (match_operand:TF 1 "nonimmediate_operand"))]
3777 "TARGET_64BIT || TARGET_SSE"
3778 "ix86_expand_move (TFmode, operands); DONE;")
3779
3780 (define_expand "mov<mode>"
3781 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3782 (match_operand:X87MODEFH 1 "general_operand"))]
3783 ""
3784 "ix86_expand_move (<MODE>mode, operands); DONE;")
3785
3786 (define_insn "*movtf_internal"
3787 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3788 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3789 "(TARGET_64BIT || TARGET_SSE)
3790 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3791 && (lra_in_progress || reload_completed
3792 || !CONST_DOUBLE_P (operands[1])
3793 || (standard_sse_constant_p (operands[1], TFmode) == 1
3794 && !memory_operand (operands[0], TFmode))
3795 || (!TARGET_MEMORY_MISMATCH_STALL
3796 && memory_operand (operands[0], TFmode)))"
3797 {
3798 switch (get_attr_type (insn))
3799 {
3800 case TYPE_SSELOG1:
3801 return standard_sse_constant_opcode (insn, operands);
3802
3803 case TYPE_SSEMOV:
3804 return ix86_output_ssemov (insn, operands);
3805
3806 case TYPE_MULTI:
3807 return "#";
3808
3809 default:
3810 gcc_unreachable ();
3811 }
3812 }
3813 [(set_attr "isa" "*,*,*,x64,x64")
3814 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3815 (set (attr "prefix")
3816 (if_then_else (eq_attr "type" "sselog1,ssemov")
3817 (const_string "maybe_vex")
3818 (const_string "orig")))
3819 (set (attr "mode")
3820 (cond [(eq_attr "alternative" "3,4")
3821 (const_string "DI")
3822 (match_test "TARGET_AVX")
3823 (const_string "TI")
3824 (ior (not (match_test "TARGET_SSE2"))
3825 (match_test "optimize_function_for_size_p (cfun)"))
3826 (const_string "V4SF")
3827 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3828 (const_string "V4SF")
3829 (and (eq_attr "alternative" "2")
3830 (match_test "TARGET_SSE_TYPELESS_STORES"))
3831 (const_string "V4SF")
3832 ]
3833 (const_string "TI")))])
3834
3835 (define_split
3836 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3837 (match_operand:TF 1 "general_gr_operand"))]
3838 "reload_completed"
3839 [(const_int 0)]
3840 "ix86_split_long_move (operands); DONE;")
3841
3842 ;; Possible store forwarding (partial memory) stall
3843 ;; in alternatives 4, 6, 7 and 8.
3844 (define_insn "*movxf_internal"
3845 [(set (match_operand:XF 0 "nonimmediate_operand"
3846 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3847 (match_operand:XF 1 "general_operand"
3848 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3849 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3850 && (lra_in_progress || reload_completed
3851 || !CONST_DOUBLE_P (operands[1])
3852 || ((optimize_function_for_size_p (cfun)
3853 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3854 && standard_80387_constant_p (operands[1]) > 0
3855 && !memory_operand (operands[0], XFmode))
3856 || (!TARGET_MEMORY_MISMATCH_STALL
3857 && memory_operand (operands[0], XFmode))
3858 || !TARGET_HARD_XF_REGS)"
3859 {
3860 switch (get_attr_type (insn))
3861 {
3862 case TYPE_FMOV:
3863 if (which_alternative == 2)
3864 return standard_80387_constant_opcode (operands[1]);
3865 return output_387_reg_move (insn, operands);
3866
3867 case TYPE_MULTI:
3868 return "#";
3869
3870 default:
3871 gcc_unreachable ();
3872 }
3873 }
3874 [(set (attr "isa")
3875 (cond [(eq_attr "alternative" "7,10")
3876 (const_string "nox64")
3877 (eq_attr "alternative" "8,11")
3878 (const_string "x64")
3879 ]
3880 (const_string "*")))
3881 (set (attr "type")
3882 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3883 (const_string "multi")
3884 ]
3885 (const_string "fmov")))
3886 (set (attr "mode")
3887 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3888 (if_then_else (match_test "TARGET_64BIT")
3889 (const_string "DI")
3890 (const_string "SI"))
3891 ]
3892 (const_string "XF")))
3893 (set (attr "preferred_for_size")
3894 (cond [(eq_attr "alternative" "3,4")
3895 (symbol_ref "false")]
3896 (symbol_ref "true")))
3897 (set (attr "enabled")
3898 (cond [(eq_attr "alternative" "9,10,11")
3899 (if_then_else
3900 (match_test "TARGET_HARD_XF_REGS")
3901 (symbol_ref "false")
3902 (const_string "*"))
3903 (not (match_test "TARGET_HARD_XF_REGS"))
3904 (symbol_ref "false")
3905 ]
3906 (const_string "*")))])
3907
3908 (define_split
3909 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3910 (match_operand:XF 1 "general_gr_operand"))]
3911 "reload_completed"
3912 [(const_int 0)]
3913 "ix86_split_long_move (operands); DONE;")
3914
3915 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3916 (define_insn "*movdf_internal"
3917 [(set (match_operand:DF 0 "nonimmediate_operand"
3918 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,?r,?v,r ,o ,r ,m")
3919 (match_operand:DF 1 "general_operand"
3920 "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"))]
3921 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3922 && (lra_in_progress || reload_completed
3923 || !CONST_DOUBLE_P (operands[1])
3924 || ((optimize_function_for_size_p (cfun)
3925 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3926 && IS_STACK_MODE (DFmode)
3927 && standard_80387_constant_p (operands[1]) > 0
3928 && !memory_operand (operands[0], DFmode))
3929 || (TARGET_SSE2 && TARGET_SSE_MATH
3930 && standard_sse_constant_p (operands[1], DFmode) == 1
3931 && !memory_operand (operands[0], DFmode))
3932 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3933 && memory_operand (operands[0], DFmode))
3934 || !TARGET_HARD_DF_REGS)"
3935 {
3936 switch (get_attr_type (insn))
3937 {
3938 case TYPE_FMOV:
3939 if (which_alternative == 2)
3940 return standard_80387_constant_opcode (operands[1]);
3941 return output_387_reg_move (insn, operands);
3942
3943 case TYPE_MULTI:
3944 return "#";
3945
3946 case TYPE_IMOV:
3947 if (get_attr_mode (insn) == MODE_SI)
3948 return "mov{l}\t{%1, %k0|%k0, %1}";
3949 else if (which_alternative == 11)
3950 return "movabs{q}\t{%1, %0|%0, %1}";
3951 else
3952 return "mov{q}\t{%1, %0|%0, %1}";
3953
3954 case TYPE_SSELOG1:
3955 return standard_sse_constant_opcode (insn, operands);
3956
3957 case TYPE_SSEMOV:
3958 return ix86_output_ssemov (insn, operands);
3959
3960 default:
3961 gcc_unreachable ();
3962 }
3963 }
3964 [(set (attr "isa")
3965 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3966 (const_string "nox64")
3967 (eq_attr "alternative" "8,9,10,11,24,25")
3968 (const_string "x64")
3969 (eq_attr "alternative" "12,13,14,15")
3970 (const_string "sse2")
3971 (eq_attr "alternative" "20,21")
3972 (const_string "x64_sse2")
3973 ]
3974 (const_string "*")))
3975 (set (attr "type")
3976 (cond [(eq_attr "alternative" "0,1,2")
3977 (const_string "fmov")
3978 (eq_attr "alternative" "3,4,5,6,7,22,23")
3979 (const_string "multi")
3980 (eq_attr "alternative" "8,9,10,11,24,25")
3981 (const_string "imov")
3982 (eq_attr "alternative" "12,16")
3983 (const_string "sselog1")
3984 ]
3985 (const_string "ssemov")))
3986 (set (attr "modrm")
3987 (if_then_else (eq_attr "alternative" "11")
3988 (const_string "0")
3989 (const_string "*")))
3990 (set (attr "length_immediate")
3991 (if_then_else (eq_attr "alternative" "11")
3992 (const_string "8")
3993 (const_string "*")))
3994 (set (attr "prefix")
3995 (if_then_else (eq_attr "type" "sselog1,ssemov")
3996 (const_string "maybe_vex")
3997 (const_string "orig")))
3998 (set (attr "prefix_data16")
3999 (if_then_else
4000 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4001 (eq_attr "mode" "V1DF"))
4002 (const_string "1")
4003 (const_string "*")))
4004 (set (attr "mode")
4005 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4006 (const_string "SI")
4007 (eq_attr "alternative" "8,9,11,20,21,24,25")
4008 (const_string "DI")
4009
4010 /* xorps is one byte shorter for non-AVX targets. */
4011 (eq_attr "alternative" "12,16")
4012 (cond [(match_test "TARGET_AVX")
4013 (const_string "V2DF")
4014 (ior (not (match_test "TARGET_SSE2"))
4015 (match_test "optimize_function_for_size_p (cfun)"))
4016 (const_string "V4SF")
4017 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4018 (const_string "TI")
4019 ]
4020 (const_string "V2DF"))
4021
4022 /* For architectures resolving dependencies on
4023 whole SSE registers use movapd to break dependency
4024 chains, otherwise use short move to avoid extra work. */
4025
4026 /* movaps is one byte shorter for non-AVX targets. */
4027 (eq_attr "alternative" "13,17")
4028 (cond [(match_test "TARGET_AVX")
4029 (const_string "DF")
4030 (ior (not (match_test "TARGET_SSE2"))
4031 (match_test "optimize_function_for_size_p (cfun)"))
4032 (const_string "V4SF")
4033 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4034 (const_string "V4SF")
4035 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4036 (const_string "V2DF")
4037 ]
4038 (const_string "DF"))
4039
4040 /* For architectures resolving dependencies on register
4041 parts we may avoid extra work to zero out upper part
4042 of register. */
4043 (eq_attr "alternative" "14,18")
4044 (cond [(not (match_test "TARGET_SSE2"))
4045 (const_string "V2SF")
4046 (match_test "TARGET_AVX")
4047 (const_string "DF")
4048 (match_test "TARGET_SSE_SPLIT_REGS")
4049 (const_string "V1DF")
4050 ]
4051 (const_string "DF"))
4052
4053 (and (eq_attr "alternative" "15,19")
4054 (not (match_test "TARGET_SSE2")))
4055 (const_string "V2SF")
4056 ]
4057 (const_string "DF")))
4058 (set (attr "preferred_for_size")
4059 (cond [(eq_attr "alternative" "3,4")
4060 (symbol_ref "false")]
4061 (symbol_ref "true")))
4062 (set (attr "preferred_for_speed")
4063 (cond [(eq_attr "alternative" "3,4")
4064 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4065 (eq_attr "alternative" "20")
4066 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4067 (eq_attr "alternative" "21")
4068 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4069 ]
4070 (symbol_ref "true")))
4071 (set (attr "enabled")
4072 (cond [(eq_attr "alternative" "22,23,24,25")
4073 (if_then_else
4074 (match_test "TARGET_HARD_DF_REGS")
4075 (symbol_ref "false")
4076 (const_string "*"))
4077 (not (match_test "TARGET_HARD_DF_REGS"))
4078 (symbol_ref "false")
4079 ]
4080 (const_string "*")))])
4081
4082 (define_split
4083 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4084 (match_operand:DF 1 "general_gr_operand"))]
4085 "!TARGET_64BIT && reload_completed"
4086 [(const_int 0)]
4087 "ix86_split_long_move (operands); DONE;")
4088
4089 (define_insn "*movsf_internal"
4090 [(set (match_operand:SF 0 "nonimmediate_operand"
4091 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4092 (match_operand:SF 1 "general_operand"
4093 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4094 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4095 && (lra_in_progress || reload_completed
4096 || !CONST_DOUBLE_P (operands[1])
4097 || ((optimize_function_for_size_p (cfun)
4098 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4099 && IS_STACK_MODE (SFmode)
4100 && standard_80387_constant_p (operands[1]) > 0)
4101 || (TARGET_SSE && TARGET_SSE_MATH
4102 && standard_sse_constant_p (operands[1], SFmode) == 1)
4103 || memory_operand (operands[0], SFmode)
4104 || !TARGET_HARD_SF_REGS)"
4105 {
4106 switch (get_attr_type (insn))
4107 {
4108 case TYPE_FMOV:
4109 if (which_alternative == 2)
4110 return standard_80387_constant_opcode (operands[1]);
4111 return output_387_reg_move (insn, operands);
4112
4113 case TYPE_IMOV:
4114 return "mov{l}\t{%1, %0|%0, %1}";
4115
4116 case TYPE_SSELOG1:
4117 return standard_sse_constant_opcode (insn, operands);
4118
4119 case TYPE_SSEMOV:
4120 return ix86_output_ssemov (insn, operands);
4121
4122 case TYPE_MMXMOV:
4123 switch (get_attr_mode (insn))
4124 {
4125 case MODE_DI:
4126 return "movq\t{%1, %0|%0, %1}";
4127 case MODE_SI:
4128 return "movd\t{%1, %0|%0, %1}";
4129
4130 default:
4131 gcc_unreachable ();
4132 }
4133
4134 default:
4135 gcc_unreachable ();
4136 }
4137 }
4138 [(set (attr "isa")
4139 (cond [(eq_attr "alternative" "9,10")
4140 (const_string "sse2")
4141 ]
4142 (const_string "*")))
4143 (set (attr "type")
4144 (cond [(eq_attr "alternative" "0,1,2")
4145 (const_string "fmov")
4146 (eq_attr "alternative" "3,4,16,17")
4147 (const_string "imov")
4148 (eq_attr "alternative" "5")
4149 (const_string "sselog1")
4150 (eq_attr "alternative" "11,12,13,14,15")
4151 (const_string "mmxmov")
4152 ]
4153 (const_string "ssemov")))
4154 (set (attr "prefix")
4155 (if_then_else (eq_attr "type" "sselog1,ssemov")
4156 (const_string "maybe_vex")
4157 (const_string "orig")))
4158 (set (attr "prefix_data16")
4159 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4160 (const_string "1")
4161 (const_string "*")))
4162 (set (attr "mode")
4163 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4164 (const_string "SI")
4165 (eq_attr "alternative" "11")
4166 (const_string "DI")
4167 (eq_attr "alternative" "5")
4168 (cond [(and (match_test "TARGET_AVX512F")
4169 (not (match_test "TARGET_PREFER_AVX256")))
4170 (const_string "V16SF")
4171 (match_test "TARGET_AVX")
4172 (const_string "V4SF")
4173 (ior (not (match_test "TARGET_SSE2"))
4174 (match_test "optimize_function_for_size_p (cfun)"))
4175 (const_string "V4SF")
4176 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4177 (const_string "TI")
4178 ]
4179 (const_string "V4SF"))
4180
4181 /* For architectures resolving dependencies on
4182 whole SSE registers use APS move to break dependency
4183 chains, otherwise use short move to avoid extra work.
4184
4185 Do the same for architectures resolving dependencies on
4186 the parts. While in DF mode it is better to always handle
4187 just register parts, the SF mode is different due to lack
4188 of instructions to load just part of the register. It is
4189 better to maintain the whole registers in single format
4190 to avoid problems on using packed logical operations. */
4191 (eq_attr "alternative" "6")
4192 (cond [(ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4193 (match_test "TARGET_SSE_SPLIT_REGS"))
4194 (const_string "V4SF")
4195 ]
4196 (const_string "SF"))
4197 ]
4198 (const_string "SF")))
4199 (set (attr "preferred_for_speed")
4200 (cond [(eq_attr "alternative" "9,14")
4201 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4202 (eq_attr "alternative" "10,15")
4203 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4204 ]
4205 (symbol_ref "true")))
4206 (set (attr "enabled")
4207 (cond [(eq_attr "alternative" "16,17")
4208 (if_then_else
4209 (match_test "TARGET_HARD_SF_REGS")
4210 (symbol_ref "false")
4211 (const_string "*"))
4212 (not (match_test "TARGET_HARD_SF_REGS"))
4213 (symbol_ref "false")
4214 ]
4215 (const_string "*")))])
4216
4217 (define_mode_attr hfbfconstf
4218 [(HF "F") (BF "")])
4219
4220 (define_insn "*mov<mode>_internal"
4221 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4222 "=?r,?r,?r,?m,v,v,?r,m,?v,v")
4223 (match_operand:HFBF 1 "general_operand"
4224 "r ,F ,m ,r<hfbfconstf>,C,v, v,v,r ,m"))]
4225 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4226 && (lra_in_progress
4227 || reload_completed
4228 || !CONST_DOUBLE_P (operands[1])
4229 || (TARGET_SSE2
4230 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4231 || memory_operand (operands[0], <MODE>mode))"
4232 {
4233 switch (get_attr_type (insn))
4234 {
4235 case TYPE_IMOVX:
4236 /* movzwl is faster than movw on p2 due to partial word stalls,
4237 though not as fast as an aligned movl. */
4238 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4239
4240 case TYPE_SSEMOV:
4241 return ix86_output_ssemov (insn, operands);
4242
4243 case TYPE_SSELOG1:
4244 if (satisfies_constraint_C (operands[1]))
4245 return standard_sse_constant_opcode (insn, operands);
4246
4247 if (SSE_REG_P (operands[0]))
4248 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4249 else
4250 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4251
4252 default:
4253 if (get_attr_mode (insn) == MODE_SI)
4254 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4255 else
4256 return "mov{w}\t{%1, %0|%0, %1}";
4257 }
4258 }
4259 [(set (attr "isa")
4260 (cond [(eq_attr "alternative" "4,5,6,8,9")
4261 (const_string "sse2")
4262 (eq_attr "alternative" "7")
4263 (const_string "sse4")
4264 ]
4265 (const_string "*")))
4266 (set (attr "type")
4267 (cond [(eq_attr "alternative" "4")
4268 (const_string "sselog1")
4269 (eq_attr "alternative" "5,6,8")
4270 (const_string "ssemov")
4271 (eq_attr "alternative" "7,9")
4272 (if_then_else
4273 (match_test ("TARGET_AVX512FP16"))
4274 (const_string "ssemov")
4275 (const_string "sselog1"))
4276 (match_test "optimize_function_for_size_p (cfun)")
4277 (const_string "imov")
4278 (and (eq_attr "alternative" "0")
4279 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4280 (not (match_test "TARGET_HIMODE_MATH"))))
4281 (const_string "imov")
4282 (and (eq_attr "alternative" "1,2")
4283 (match_operand:HI 1 "aligned_operand"))
4284 (const_string "imov")
4285 (and (match_test "TARGET_MOVX")
4286 (eq_attr "alternative" "0,2"))
4287 (const_string "imovx")
4288 ]
4289 (const_string "imov")))
4290 (set (attr "prefix")
4291 (cond [(eq_attr "alternative" "4,5,6,7,8,9")
4292 (const_string "maybe_vex")
4293 ]
4294 (const_string "orig")))
4295 (set (attr "mode")
4296 (cond [(eq_attr "alternative" "4")
4297 (const_string "V4SF")
4298 (eq_attr "alternative" "6,8")
4299 (if_then_else
4300 (match_test "TARGET_AVX512FP16")
4301 (const_string "HI")
4302 (const_string "SI"))
4303 (eq_attr "alternative" "7,9")
4304 (if_then_else
4305 (match_test "TARGET_AVX512FP16")
4306 (const_string "HI")
4307 (const_string "TI"))
4308 (eq_attr "alternative" "5")
4309 (cond [(match_test "TARGET_AVX512FP16")
4310 (const_string "HF")
4311 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4312 (match_test "TARGET_SSE_SPLIT_REGS"))
4313 (const_string "V4SF")
4314 ]
4315 (const_string "SF"))
4316 (eq_attr "type" "imovx")
4317 (const_string "SI")
4318 (and (eq_attr "alternative" "1,2")
4319 (match_operand:HI 1 "aligned_operand"))
4320 (const_string "SI")
4321 (and (eq_attr "alternative" "0")
4322 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4323 (not (match_test "TARGET_HIMODE_MATH"))))
4324 (const_string "SI")
4325 ]
4326 (const_string "HI")))
4327 (set (attr "enabled")
4328 (cond [(and (match_test "<MODE>mode == BFmode")
4329 (eq_attr "alternative" "1"))
4330 (symbol_ref "false")
4331 ]
4332 (const_string "*")))])
4333
4334 (define_split
4335 [(set (match_operand 0 "any_fp_register_operand")
4336 (match_operand 1 "memory_operand"))]
4337 "reload_completed
4338 && (GET_MODE (operands[0]) == TFmode
4339 || GET_MODE (operands[0]) == XFmode
4340 || GET_MODE (operands[0]) == DFmode
4341 || GET_MODE (operands[0]) == SFmode)
4342 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4343 [(set (match_dup 0) (match_dup 2))]
4344 "operands[2] = find_constant_src (curr_insn);")
4345
4346 (define_split
4347 [(set (match_operand 0 "any_fp_register_operand")
4348 (float_extend (match_operand 1 "memory_operand")))]
4349 "reload_completed
4350 && (GET_MODE (operands[0]) == TFmode
4351 || GET_MODE (operands[0]) == XFmode
4352 || GET_MODE (operands[0]) == DFmode)
4353 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4354 [(set (match_dup 0) (match_dup 2))]
4355 "operands[2] = find_constant_src (curr_insn);")
4356
4357 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4358 (define_split
4359 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4360 (match_operand:X87MODEF 1 "immediate_operand"))]
4361 "reload_completed
4362 && (standard_80387_constant_p (operands[1]) == 8
4363 || standard_80387_constant_p (operands[1]) == 9)"
4364 [(set (match_dup 0)(match_dup 1))
4365 (set (match_dup 0)
4366 (neg:X87MODEF (match_dup 0)))]
4367 {
4368 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4369 operands[1] = CONST0_RTX (<MODE>mode);
4370 else
4371 operands[1] = CONST1_RTX (<MODE>mode);
4372 })
4373
4374 (define_insn "*swapxf"
4375 [(set (match_operand:XF 0 "register_operand" "+f")
4376 (match_operand:XF 1 "register_operand" "+f"))
4377 (set (match_dup 1)
4378 (match_dup 0))]
4379 "TARGET_80387"
4380 {
4381 if (STACK_TOP_P (operands[0]))
4382 return "fxch\t%1";
4383 else
4384 return "fxch\t%0";
4385 }
4386 [(set_attr "type" "fxch")
4387 (set_attr "mode" "XF")])
4388 \f
4389
4390 ;; Zero extension instructions
4391
4392 (define_insn_and_split "zero_extendditi2"
4393 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4394 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4395 "TARGET_64BIT"
4396 "#"
4397 "&& reload_completed"
4398 [(set (match_dup 3) (match_dup 1))
4399 (set (match_dup 4) (const_int 0))]
4400 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4401
4402 (define_expand "zero_extendsidi2"
4403 [(set (match_operand:DI 0 "nonimmediate_operand")
4404 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4405
4406 (define_insn "*zero_extendsidi2"
4407 [(set (match_operand:DI 0 "nonimmediate_operand"
4408 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4409 (zero_extend:DI
4410 (match_operand:SI 1 "x86_64_zext_operand"
4411 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
4412 ""
4413 {
4414 switch (get_attr_type (insn))
4415 {
4416 case TYPE_IMOVX:
4417 if (ix86_use_lea_for_mov (insn, operands))
4418 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4419 else
4420 return "mov{l}\t{%1, %k0|%k0, %1}";
4421
4422 case TYPE_MULTI:
4423 return "#";
4424
4425 case TYPE_MMXMOV:
4426 return "movd\t{%1, %0|%0, %1}";
4427
4428 case TYPE_SSEMOV:
4429 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4430 {
4431 if (EXT_REX_SSE_REG_P (operands[0])
4432 || EXT_REX_SSE_REG_P (operands[1]))
4433 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4434 else
4435 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4436 }
4437
4438 if (GENERAL_REG_P (operands[0]))
4439 return "%vmovd\t{%1, %k0|%k0, %1}";
4440
4441 return "%vmovd\t{%1, %0|%0, %1}";
4442
4443 case TYPE_MSKMOV:
4444 return "kmovd\t{%1, %k0|%k0, %1}";
4445
4446 default:
4447 gcc_unreachable ();
4448 }
4449 }
4450 [(set (attr "isa")
4451 (cond [(eq_attr "alternative" "0,1,2")
4452 (const_string "nox64")
4453 (eq_attr "alternative" "3")
4454 (const_string "x64")
4455 (eq_attr "alternative" "7,8,9")
4456 (const_string "sse2")
4457 (eq_attr "alternative" "10")
4458 (const_string "sse4")
4459 (eq_attr "alternative" "11")
4460 (const_string "avx512f")
4461 (eq_attr "alternative" "12")
4462 (const_string "x64_avx512bw")
4463 (eq_attr "alternative" "13")
4464 (const_string "avx512bw")
4465 ]
4466 (const_string "*")))
4467 (set (attr "mmx_isa")
4468 (if_then_else (eq_attr "alternative" "5,6")
4469 (const_string "native")
4470 (const_string "*")))
4471 (set (attr "type")
4472 (cond [(eq_attr "alternative" "0,1,2,4")
4473 (const_string "multi")
4474 (eq_attr "alternative" "5,6")
4475 (const_string "mmxmov")
4476 (eq_attr "alternative" "7")
4477 (if_then_else (match_test "TARGET_64BIT")
4478 (const_string "ssemov")
4479 (const_string "multi"))
4480 (eq_attr "alternative" "8,9,10,11")
4481 (const_string "ssemov")
4482 (eq_attr "alternative" "12,13")
4483 (const_string "mskmov")
4484 ]
4485 (const_string "imovx")))
4486 (set (attr "prefix_extra")
4487 (if_then_else (eq_attr "alternative" "10,11")
4488 (const_string "1")
4489 (const_string "*")))
4490 (set (attr "prefix")
4491 (if_then_else (eq_attr "type" "ssemov")
4492 (const_string "maybe_vex")
4493 (const_string "orig")))
4494 (set (attr "prefix_0f")
4495 (if_then_else (eq_attr "type" "imovx")
4496 (const_string "0")
4497 (const_string "*")))
4498 (set (attr "mode")
4499 (cond [(eq_attr "alternative" "5,6")
4500 (const_string "DI")
4501 (and (eq_attr "alternative" "7")
4502 (match_test "TARGET_64BIT"))
4503 (const_string "TI")
4504 (eq_attr "alternative" "8,10,11")
4505 (const_string "TI")
4506 ]
4507 (const_string "SI")))
4508 (set (attr "preferred_for_speed")
4509 (cond [(eq_attr "alternative" "7")
4510 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4511 (eq_attr "alternative" "5,8")
4512 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4513 ]
4514 (symbol_ref "true")))])
4515
4516 (define_split
4517 [(set (match_operand:DI 0 "memory_operand")
4518 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4519 "reload_completed"
4520 [(set (match_dup 4) (const_int 0))]
4521 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4522
4523 (define_split
4524 [(set (match_operand:DI 0 "general_reg_operand")
4525 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4526 "!TARGET_64BIT && reload_completed
4527 && REGNO (operands[0]) == REGNO (operands[1])"
4528 [(set (match_dup 4) (const_int 0))]
4529 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4530
4531 (define_split
4532 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4533 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4534 "!TARGET_64BIT && reload_completed
4535 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4536 [(set (match_dup 3) (match_dup 1))
4537 (set (match_dup 4) (const_int 0))]
4538 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4539
4540 (define_mode_attr kmov_isa
4541 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4542
4543 (define_insn "zero_extend<mode>di2"
4544 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4545 (zero_extend:DI
4546 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4547 "TARGET_64BIT"
4548 "@
4549 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4550 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4551 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4552 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4553 (set_attr "type" "imovx,mskmov,mskmov")
4554 (set_attr "mode" "SI,<MODE>,<MODE>")])
4555
4556 (define_expand "zero_extend<mode>si2"
4557 [(set (match_operand:SI 0 "register_operand")
4558 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4559 ""
4560 {
4561 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4562 {
4563 operands[1] = force_reg (<MODE>mode, operands[1]);
4564 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4565 DONE;
4566 }
4567 })
4568
4569 (define_insn_and_split "zero_extend<mode>si2_and"
4570 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4571 (zero_extend:SI
4572 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4573 (clobber (reg:CC FLAGS_REG))]
4574 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4575 "#"
4576 "&& reload_completed"
4577 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4578 (clobber (reg:CC FLAGS_REG))])]
4579 {
4580 if (!REG_P (operands[1])
4581 || REGNO (operands[0]) != REGNO (operands[1]))
4582 {
4583 ix86_expand_clear (operands[0]);
4584
4585 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4586 emit_insn (gen_rtx_SET
4587 (gen_rtx_STRICT_LOW_PART
4588 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4589 operands[1]));
4590 DONE;
4591 }
4592
4593 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4594 }
4595 [(set_attr "type" "alu1")
4596 (set_attr "mode" "SI")])
4597
4598 (define_insn "*zero_extend<mode>si2"
4599 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4600 (zero_extend:SI
4601 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4602 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4603 "@
4604 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4605 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4606 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4607 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4608 (set_attr "type" "imovx,mskmov,mskmov")
4609 (set_attr "mode" "SI,<MODE>,<MODE>")])
4610
4611 (define_expand "zero_extendqihi2"
4612 [(set (match_operand:HI 0 "register_operand")
4613 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4614 ""
4615 {
4616 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4617 {
4618 operands[1] = force_reg (QImode, operands[1]);
4619 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4620 DONE;
4621 }
4622 })
4623
4624 (define_insn_and_split "zero_extendqihi2_and"
4625 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4626 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4627 (clobber (reg:CC FLAGS_REG))]
4628 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4629 "#"
4630 "&& reload_completed"
4631 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4632 (clobber (reg:CC FLAGS_REG))])]
4633 {
4634 if (!REG_P (operands[1])
4635 || REGNO (operands[0]) != REGNO (operands[1]))
4636 {
4637 ix86_expand_clear (operands[0]);
4638
4639 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4640 emit_insn (gen_rtx_SET
4641 (gen_rtx_STRICT_LOW_PART
4642 (VOIDmode, gen_lowpart (QImode, operands[0])),
4643 operands[1]));
4644 DONE;
4645 }
4646
4647 operands[0] = gen_lowpart (SImode, operands[0]);
4648 }
4649 [(set_attr "type" "alu1")
4650 (set_attr "mode" "SI")])
4651
4652 ; zero extend to SImode to avoid partial register stalls
4653 (define_insn "*zero_extendqihi2"
4654 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4655 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4656 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4657 "@
4658 movz{bl|x}\t{%1, %k0|%k0, %1}
4659 kmovb\t{%1, %k0|%k0, %1}
4660 kmovb\t{%1, %0|%0, %1}"
4661 [(set_attr "isa" "*,avx512dq,avx512dq")
4662 (set_attr "type" "imovx,mskmov,mskmov")
4663 (set_attr "mode" "SI,QI,QI")])
4664
4665 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4666 (define_peephole2
4667 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4668 (const_int 0))
4669 (clobber (reg:CC FLAGS_REG))])
4670 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4671 (match_operand:SWI12 2 "nonimmediate_operand"))]
4672 "REGNO (operands[0]) == REGNO (operands[1])
4673 && (<SWI48:MODE>mode != SImode
4674 || !TARGET_ZERO_EXTEND_WITH_AND
4675 || !optimize_function_for_speed_p (cfun))"
4676 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4677
4678 ;; Likewise, but preserving FLAGS_REG.
4679 (define_peephole2
4680 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4681 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4682 (match_operand:SWI12 2 "nonimmediate_operand"))]
4683 "REGNO (operands[0]) == REGNO (operands[1])
4684 && (<SWI48:MODE>mode != SImode
4685 || !TARGET_ZERO_EXTEND_WITH_AND
4686 || !optimize_function_for_speed_p (cfun))"
4687 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4688 \f
4689 ;; Sign extension instructions
4690
4691 (define_expand "extendsidi2"
4692 [(set (match_operand:DI 0 "register_operand")
4693 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4694 ""
4695 {
4696 if (!TARGET_64BIT)
4697 {
4698 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4699 DONE;
4700 }
4701 })
4702
4703 (define_insn "*extendsidi2_rex64"
4704 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4705 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4706 "TARGET_64BIT"
4707 "@
4708 {cltq|cdqe}
4709 movs{lq|x}\t{%1, %0|%0, %1}"
4710 [(set_attr "type" "imovx")
4711 (set_attr "mode" "DI")
4712 (set_attr "prefix_0f" "0")
4713 (set_attr "modrm" "0,1")])
4714
4715 (define_insn "extendsidi2_1"
4716 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4717 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4718 (clobber (reg:CC FLAGS_REG))
4719 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4720 "!TARGET_64BIT"
4721 "#")
4722
4723 (define_insn "extendditi2"
4724 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4725 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4726 (clobber (reg:CC FLAGS_REG))
4727 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4728 "TARGET_64BIT"
4729 "#")
4730
4731 ;; Split the memory case. If the source register doesn't die, it will stay
4732 ;; this way, if it does die, following peephole2s take care of it.
4733 (define_split
4734 [(set (match_operand:<DWI> 0 "memory_operand")
4735 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4736 (clobber (reg:CC FLAGS_REG))
4737 (clobber (match_operand:DWIH 2 "register_operand"))]
4738 "reload_completed"
4739 [(const_int 0)]
4740 {
4741 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4742
4743 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4744
4745 emit_move_insn (operands[3], operands[1]);
4746
4747 /* Generate a cltd if possible and doing so it profitable. */
4748 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4749 && REGNO (operands[1]) == AX_REG
4750 && REGNO (operands[2]) == DX_REG)
4751 {
4752 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4753 }
4754 else
4755 {
4756 emit_move_insn (operands[2], operands[1]);
4757 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4758 }
4759 emit_move_insn (operands[4], operands[2]);
4760 DONE;
4761 })
4762
4763 ;; Peepholes for the case where the source register does die, after
4764 ;; being split with the above splitter.
4765 (define_peephole2
4766 [(set (match_operand:DWIH 0 "memory_operand")
4767 (match_operand:DWIH 1 "general_reg_operand"))
4768 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4769 (parallel [(set (match_dup 2)
4770 (ashiftrt:DWIH (match_dup 2)
4771 (match_operand 4 "const_int_operand")))
4772 (clobber (reg:CC FLAGS_REG))])
4773 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4774 "REGNO (operands[1]) != REGNO (operands[2])
4775 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4776 && peep2_reg_dead_p (2, operands[1])
4777 && peep2_reg_dead_p (4, operands[2])
4778 && !reg_mentioned_p (operands[2], operands[3])"
4779 [(set (match_dup 0) (match_dup 1))
4780 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4781 (clobber (reg:CC FLAGS_REG))])
4782 (set (match_dup 3) (match_dup 1))])
4783
4784 (define_peephole2
4785 [(set (match_operand:DWIH 0 "memory_operand")
4786 (match_operand:DWIH 1 "general_reg_operand"))
4787 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4788 (ashiftrt:DWIH (match_dup 1)
4789 (match_operand 4 "const_int_operand")))
4790 (clobber (reg:CC FLAGS_REG))])
4791 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4792 "/* cltd is shorter than sarl $31, %eax */
4793 !optimize_function_for_size_p (cfun)
4794 && REGNO (operands[1]) == AX_REG
4795 && REGNO (operands[2]) == DX_REG
4796 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4797 && peep2_reg_dead_p (2, operands[1])
4798 && peep2_reg_dead_p (3, operands[2])
4799 && !reg_mentioned_p (operands[2], operands[3])"
4800 [(set (match_dup 0) (match_dup 1))
4801 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4802 (clobber (reg:CC FLAGS_REG))])
4803 (set (match_dup 3) (match_dup 1))])
4804
4805 ;; Extend to register case. Optimize case where source and destination
4806 ;; registers match and cases where we can use cltd.
4807 (define_split
4808 [(set (match_operand:<DWI> 0 "register_operand")
4809 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4810 (clobber (reg:CC FLAGS_REG))
4811 (clobber (match_scratch:DWIH 2))]
4812 "reload_completed"
4813 [(const_int 0)]
4814 {
4815 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4816
4817 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4818
4819 if (REGNO (operands[3]) != REGNO (operands[1]))
4820 emit_move_insn (operands[3], operands[1]);
4821
4822 rtx src = operands[1];
4823 if (REGNO (operands[3]) == AX_REG)
4824 src = operands[3];
4825
4826 /* Generate a cltd if possible and doing so it profitable. */
4827 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4828 && REGNO (src) == AX_REG
4829 && REGNO (operands[4]) == DX_REG)
4830 {
4831 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4832 DONE;
4833 }
4834
4835 if (REGNO (operands[4]) != REGNO (operands[1]))
4836 emit_move_insn (operands[4], operands[1]);
4837
4838 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
4839 DONE;
4840 })
4841
4842 (define_insn "extend<mode>di2"
4843 [(set (match_operand:DI 0 "register_operand" "=r")
4844 (sign_extend:DI
4845 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4846 "TARGET_64BIT"
4847 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4848 [(set_attr "type" "imovx")
4849 (set_attr "mode" "DI")])
4850
4851 (define_insn "extendhisi2"
4852 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4853 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4854 ""
4855 {
4856 switch (get_attr_prefix_0f (insn))
4857 {
4858 case 0:
4859 return "{cwtl|cwde}";
4860 default:
4861 return "movs{wl|x}\t{%1, %0|%0, %1}";
4862 }
4863 }
4864 [(set_attr "type" "imovx")
4865 (set_attr "mode" "SI")
4866 (set (attr "prefix_0f")
4867 ;; movsx is short decodable while cwtl is vector decoded.
4868 (if_then_else (and (eq_attr "cpu" "!k6")
4869 (eq_attr "alternative" "0"))
4870 (const_string "0")
4871 (const_string "1")))
4872 (set (attr "znver1_decode")
4873 (if_then_else (eq_attr "prefix_0f" "0")
4874 (const_string "double")
4875 (const_string "direct")))
4876 (set (attr "modrm")
4877 (if_then_else (eq_attr "prefix_0f" "0")
4878 (const_string "0")
4879 (const_string "1")))])
4880
4881 (define_insn "*extendhisi2_zext"
4882 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4883 (zero_extend:DI
4884 (sign_extend:SI
4885 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4886 "TARGET_64BIT"
4887 {
4888 switch (get_attr_prefix_0f (insn))
4889 {
4890 case 0:
4891 return "{cwtl|cwde}";
4892 default:
4893 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4894 }
4895 }
4896 [(set_attr "type" "imovx")
4897 (set_attr "mode" "SI")
4898 (set (attr "prefix_0f")
4899 ;; movsx is short decodable while cwtl is vector decoded.
4900 (if_then_else (and (eq_attr "cpu" "!k6")
4901 (eq_attr "alternative" "0"))
4902 (const_string "0")
4903 (const_string "1")))
4904 (set (attr "modrm")
4905 (if_then_else (eq_attr "prefix_0f" "0")
4906 (const_string "0")
4907 (const_string "1")))])
4908
4909 (define_insn "extendqisi2"
4910 [(set (match_operand:SI 0 "register_operand" "=r")
4911 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4912 ""
4913 "movs{bl|x}\t{%1, %0|%0, %1}"
4914 [(set_attr "type" "imovx")
4915 (set_attr "mode" "SI")])
4916
4917 (define_insn "*extendqisi2_zext"
4918 [(set (match_operand:DI 0 "register_operand" "=r")
4919 (zero_extend:DI
4920 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4921 "TARGET_64BIT"
4922 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4923 [(set_attr "type" "imovx")
4924 (set_attr "mode" "SI")])
4925
4926 (define_insn "extendqihi2"
4927 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4928 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4929 ""
4930 {
4931 switch (get_attr_prefix_0f (insn))
4932 {
4933 case 0:
4934 return "{cbtw|cbw}";
4935 default:
4936 return "movs{bw|x}\t{%1, %0|%0, %1}";
4937 }
4938 }
4939 [(set_attr "type" "imovx")
4940 (set_attr "mode" "HI")
4941 (set (attr "prefix_0f")
4942 ;; movsx is short decodable while cwtl is vector decoded.
4943 (if_then_else (and (eq_attr "cpu" "!k6")
4944 (eq_attr "alternative" "0"))
4945 (const_string "0")
4946 (const_string "1")))
4947 (set (attr "modrm")
4948 (if_then_else (eq_attr "prefix_0f" "0")
4949 (const_string "0")
4950 (const_string "1")))])
4951
4952 (define_insn "*extendqi<SWI24:mode>_ext_1"
4953 [(set (match_operand:SWI24 0 "register_operand" "=R")
4954 (sign_extend:SWI24
4955 (subreg:QI
4956 (match_operator:SWI248 2 "extract_operator"
4957 [(match_operand 1 "int248_register_operand" "Q")
4958 (const_int 8)
4959 (const_int 8)]) 0)))]
4960 ""
4961 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
4962 [(set_attr "type" "imovx")
4963 (set_attr "mode" "<SWI24:MODE>")])
4964 \f
4965 ;; Conversions between float and double.
4966
4967 ;; These are all no-ops in the model used for the 80387.
4968 ;; So just emit moves.
4969
4970 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4971 (define_split
4972 [(set (match_operand:DF 0 "push_operand")
4973 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4974 "reload_completed"
4975 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4976 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4977
4978 (define_split
4979 [(set (match_operand:XF 0 "push_operand")
4980 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4981 "reload_completed"
4982 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4983 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4984 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4985
4986 (define_expand "extendsfdf2"
4987 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4988 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4989 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4990 {
4991 /* ??? Needed for compress_float_constant since all fp constants
4992 are TARGET_LEGITIMATE_CONSTANT_P. */
4993 if (CONST_DOUBLE_P (operands[1]))
4994 {
4995 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4996 && standard_80387_constant_p (operands[1]) > 0)
4997 {
4998 operands[1] = simplify_const_unary_operation
4999 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5000 emit_move_insn_1 (operands[0], operands[1]);
5001 DONE;
5002 }
5003 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5004 }
5005 })
5006
5007 (define_insn "*extendsfdf2"
5008 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5009 (float_extend:DF
5010 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5011 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5012 {
5013 switch (which_alternative)
5014 {
5015 case 0:
5016 case 1:
5017 return output_387_reg_move (insn, operands);
5018
5019 case 2:
5020 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5021 case 3:
5022 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5023
5024 default:
5025 gcc_unreachable ();
5026 }
5027 }
5028 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5029 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5030 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5031 (set_attr "mode" "SF,XF,DF,DF")
5032 (set (attr "enabled")
5033 (if_then_else
5034 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5035 (if_then_else
5036 (eq_attr "alternative" "0,1")
5037 (symbol_ref "TARGET_MIX_SSE_I387")
5038 (symbol_ref "true"))
5039 (if_then_else
5040 (eq_attr "alternative" "0,1")
5041 (symbol_ref "true")
5042 (symbol_ref "false"))))])
5043
5044 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5045 cvtss2sd:
5046 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5047 cvtps2pd xmm2,xmm1
5048 We do the conversion post reload to avoid producing of 128bit spills
5049 that might lead to ICE on 32bit target. The sequence unlikely combine
5050 anyway. */
5051 (define_split
5052 [(set (match_operand:DF 0 "sse_reg_operand")
5053 (float_extend:DF
5054 (match_operand:SF 1 "nonimmediate_operand")))]
5055 "TARGET_USE_VECTOR_FP_CONVERTS
5056 && optimize_insn_for_speed_p ()
5057 && reload_completed
5058 && (!EXT_REX_SSE_REG_P (operands[0])
5059 || TARGET_AVX512VL)"
5060 [(set (match_dup 2)
5061 (float_extend:V2DF
5062 (vec_select:V2SF
5063 (match_dup 3)
5064 (parallel [(const_int 0) (const_int 1)]))))]
5065 {
5066 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5067 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5068 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5069 Try to avoid move when unpacking can be done in source. */
5070 if (REG_P (operands[1]))
5071 {
5072 /* If it is unsafe to overwrite upper half of source, we need
5073 to move to destination and unpack there. */
5074 if (REGNO (operands[0]) != REGNO (operands[1])
5075 || (EXT_REX_SSE_REG_P (operands[1])
5076 && !TARGET_AVX512VL))
5077 {
5078 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5079 emit_move_insn (tmp, operands[1]);
5080 }
5081 else
5082 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5083 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5084 =v, v, then vbroadcastss will be only needed for AVX512F without
5085 AVX512VL. */
5086 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5087 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5088 operands[3]));
5089 else
5090 {
5091 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5092 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5093 }
5094 }
5095 else
5096 emit_insn (gen_vec_setv4sf_0 (operands[3],
5097 CONST0_RTX (V4SFmode), operands[1]));
5098 })
5099
5100 ;; It's more profitable to split and then extend in the same register.
5101 (define_peephole2
5102 [(set (match_operand:DF 0 "sse_reg_operand")
5103 (float_extend:DF
5104 (match_operand:SF 1 "memory_operand")))]
5105 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5106 && optimize_insn_for_speed_p ()"
5107 [(set (match_dup 2) (match_dup 1))
5108 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5109 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5110
5111 ;; Break partial SSE register dependency stall. This splitter should split
5112 ;; late in the pass sequence (after register rename pass), so allocated
5113 ;; registers won't change anymore
5114
5115 (define_split
5116 [(set (match_operand:DF 0 "sse_reg_operand")
5117 (float_extend:DF
5118 (match_operand:SF 1 "nonimmediate_operand")))]
5119 "!TARGET_AVX
5120 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5121 && epilogue_completed
5122 && optimize_function_for_speed_p (cfun)
5123 && (!REG_P (operands[1])
5124 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5125 && (!EXT_REX_SSE_REG_P (operands[0])
5126 || TARGET_AVX512VL)"
5127 [(set (match_dup 0)
5128 (vec_merge:V2DF
5129 (vec_duplicate:V2DF
5130 (float_extend:DF
5131 (match_dup 1)))
5132 (match_dup 0)
5133 (const_int 1)))]
5134 {
5135 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5136 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5137 })
5138
5139 (define_expand "extendhfsf2"
5140 [(set (match_operand:SF 0 "register_operand")
5141 (float_extend:SF
5142 (match_operand:HF 1 "nonimmediate_operand")))]
5143 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5144 {
5145 if (!TARGET_AVX512FP16)
5146 {
5147 rtx res = gen_reg_rtx (V4SFmode);
5148 rtx tmp = gen_reg_rtx (V8HFmode);
5149 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5150
5151 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5152 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5153 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5154 DONE;
5155 }
5156 })
5157
5158 (define_expand "extendhfdf2"
5159 [(set (match_operand:DF 0 "register_operand")
5160 (float_extend:DF
5161 (match_operand:HF 1 "nonimmediate_operand")))]
5162 "TARGET_AVX512FP16")
5163
5164 (define_insn "*extendhf<mode>2"
5165 [(set (match_operand:MODEF 0 "register_operand" "=v")
5166 (float_extend:MODEF
5167 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5168 "TARGET_AVX512FP16"
5169 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5170 [(set_attr "type" "ssecvt")
5171 (set_attr "prefix" "evex")
5172 (set_attr "mode" "<MODE>")])
5173
5174 (define_expand "extendbfsf2"
5175 [(set (match_operand:SF 0 "register_operand")
5176 (unspec:SF
5177 [(match_operand:BF 1 "register_operand")]
5178 UNSPEC_CVTBFSF))]
5179 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5180
5181 ;; Don't use float_extend since psrlld doesn't raise
5182 ;; exceptions and turn a sNaN into a qNaN.
5183 (define_insn "extendbfsf2_1"
5184 [(set (match_operand:SF 0 "register_operand" "=x,Yw")
5185 (unspec:SF
5186 [(match_operand:BF 1 "register_operand" " 0,Yw")]
5187 UNSPEC_CVTBFSF))]
5188 "TARGET_SSE2"
5189 "@
5190 pslld\t{$16, %0|%0, 16}
5191 vpslld\t{$16, %1, %0|%0, %1, 16}"
5192 [(set_attr "isa" "noavx,avx")
5193 (set_attr "type" "sseishft1")
5194 (set_attr "length_immediate" "1")
5195 (set_attr "prefix_data16" "1,*")
5196 (set_attr "prefix" "orig,vex")
5197 (set_attr "mode" "TI")
5198 (set_attr "memory" "none")])
5199
5200 (define_expand "extend<mode>xf2"
5201 [(set (match_operand:XF 0 "nonimmediate_operand")
5202 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5203 "TARGET_80387"
5204 {
5205 /* ??? Needed for compress_float_constant since all fp constants
5206 are TARGET_LEGITIMATE_CONSTANT_P. */
5207 if (CONST_DOUBLE_P (operands[1]))
5208 {
5209 if (standard_80387_constant_p (operands[1]) > 0)
5210 {
5211 operands[1] = simplify_const_unary_operation
5212 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5213 emit_move_insn_1 (operands[0], operands[1]);
5214 DONE;
5215 }
5216 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5217 }
5218 })
5219
5220 (define_insn "*extend<mode>xf2_i387"
5221 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5222 (float_extend:XF
5223 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5224 "TARGET_80387"
5225 "* return output_387_reg_move (insn, operands);"
5226 [(set_attr "type" "fmov")
5227 (set_attr "mode" "<MODE>,XF")])
5228
5229 ;; %%% This seems like bad news.
5230 ;; This cannot output into an f-reg because there is no way to be sure
5231 ;; of truncating in that case. Otherwise this is just like a simple move
5232 ;; insn. So we pretend we can output to a reg in order to get better
5233 ;; register preferencing, but we really use a stack slot.
5234
5235 ;; Conversion from DFmode to SFmode.
5236
5237 (define_insn "truncdfsf2"
5238 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5239 (float_truncate:SF
5240 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5241 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5242 {
5243 switch (which_alternative)
5244 {
5245 case 0:
5246 case 1:
5247 return output_387_reg_move (insn, operands);
5248
5249 case 2:
5250 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5251 case 3:
5252 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5253
5254 default:
5255 gcc_unreachable ();
5256 }
5257 }
5258 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5259 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5260 (set_attr "mode" "SF")
5261 (set (attr "enabled")
5262 (if_then_else
5263 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5264 (cond [(eq_attr "alternative" "0")
5265 (symbol_ref "TARGET_MIX_SSE_I387")
5266 (eq_attr "alternative" "1")
5267 (symbol_ref "TARGET_MIX_SSE_I387
5268 && flag_unsafe_math_optimizations")
5269 ]
5270 (symbol_ref "true"))
5271 (cond [(eq_attr "alternative" "0")
5272 (symbol_ref "true")
5273 (eq_attr "alternative" "1")
5274 (symbol_ref "flag_unsafe_math_optimizations")
5275 ]
5276 (symbol_ref "false"))))])
5277
5278 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5279 cvtsd2ss:
5280 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5281 cvtpd2ps xmm2,xmm1
5282 We do the conversion post reload to avoid producing of 128bit spills
5283 that might lead to ICE on 32bit target. The sequence unlikely combine
5284 anyway. */
5285 (define_split
5286 [(set (match_operand:SF 0 "sse_reg_operand")
5287 (float_truncate:SF
5288 (match_operand:DF 1 "nonimmediate_operand")))]
5289 "TARGET_USE_VECTOR_FP_CONVERTS
5290 && optimize_insn_for_speed_p ()
5291 && reload_completed
5292 && (!EXT_REX_SSE_REG_P (operands[0])
5293 || TARGET_AVX512VL)"
5294 [(set (match_dup 2)
5295 (vec_concat:V4SF
5296 (float_truncate:V2SF
5297 (match_dup 4))
5298 (match_dup 3)))]
5299 {
5300 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5301 operands[3] = CONST0_RTX (V2SFmode);
5302 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5303 /* Use movsd for loading from memory, unpcklpd for registers.
5304 Try to avoid move when unpacking can be done in source, or SSE3
5305 movddup is available. */
5306 if (REG_P (operands[1]))
5307 {
5308 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5309 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5310 {
5311 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5312 emit_move_insn (tmp, operands[1]);
5313 operands[1] = tmp;
5314 }
5315 else if (!TARGET_SSE3)
5316 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5317 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5318 }
5319 else
5320 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5321 CONST0_RTX (DFmode)));
5322 })
5323
5324 ;; It's more profitable to split and then truncate in the same register.
5325 (define_peephole2
5326 [(set (match_operand:SF 0 "sse_reg_operand")
5327 (float_truncate:SF
5328 (match_operand:DF 1 "memory_operand")))]
5329 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5330 && optimize_insn_for_speed_p ()"
5331 [(set (match_dup 2) (match_dup 1))
5332 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5333 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5334
5335 ;; Break partial SSE register dependency stall. This splitter should split
5336 ;; late in the pass sequence (after register rename pass), so allocated
5337 ;; registers won't change anymore
5338
5339 (define_split
5340 [(set (match_operand:SF 0 "sse_reg_operand")
5341 (float_truncate:SF
5342 (match_operand:DF 1 "nonimmediate_operand")))]
5343 "!TARGET_AVX
5344 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5345 && epilogue_completed
5346 && optimize_function_for_speed_p (cfun)
5347 && (!REG_P (operands[1])
5348 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5349 && (!EXT_REX_SSE_REG_P (operands[0])
5350 || TARGET_AVX512VL)"
5351 [(set (match_dup 0)
5352 (vec_merge:V4SF
5353 (vec_duplicate:V4SF
5354 (float_truncate:SF
5355 (match_dup 1)))
5356 (match_dup 0)
5357 (const_int 1)))]
5358 {
5359 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5360 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5361 })
5362
5363 ;; Conversion from XFmode to {SF,DF}mode
5364
5365 (define_insn "truncxf<mode>2"
5366 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5367 (float_truncate:MODEF
5368 (match_operand:XF 1 "register_operand" "f,f")))]
5369 "TARGET_80387"
5370 "* return output_387_reg_move (insn, operands);"
5371 [(set_attr "type" "fmov")
5372 (set_attr "mode" "<MODE>")
5373 (set (attr "enabled")
5374 (cond [(eq_attr "alternative" "1")
5375 (symbol_ref "flag_unsafe_math_optimizations")
5376 ]
5377 (symbol_ref "true")))])
5378
5379 ;; Conversion from {SF,DF}mode to HFmode.
5380
5381 (define_expand "truncsfhf2"
5382 [(set (match_operand:HF 0 "register_operand")
5383 (float_truncate:HF
5384 (match_operand:SF 1 "nonimmediate_operand")))]
5385 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5386 {
5387 if (!TARGET_AVX512FP16)
5388 {
5389 rtx res = gen_reg_rtx (V8HFmode);
5390 rtx tmp = gen_reg_rtx (V4SFmode);
5391 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5392
5393 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5394 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5395 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5396 DONE;
5397 }
5398 })
5399
5400 (define_expand "truncdfhf2"
5401 [(set (match_operand:HF 0 "register_operand")
5402 (float_truncate:HF
5403 (match_operand:DF 1 "nonimmediate_operand")))]
5404 "TARGET_AVX512FP16")
5405
5406 (define_insn "*trunc<mode>hf2"
5407 [(set (match_operand:HF 0 "register_operand" "=v")
5408 (float_truncate:HF
5409 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5410 "TARGET_AVX512FP16"
5411 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5412 [(set_attr "type" "ssecvt")
5413 (set_attr "prefix" "evex")
5414 (set_attr "mode" "HF")])
5415
5416 (define_insn "truncsfbf2"
5417 [(set (match_operand:BF 0 "register_operand" "=x, v")
5418 (float_truncate:BF
5419 (match_operand:SF 1 "register_operand" "x,v")))]
5420 "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5421 && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5422 "@
5423 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5424 vcvtneps2bf16\t{%1, %0|%0, %1}"
5425 [(set_attr "isa" "avxneconvert,avx512bf16vl")
5426 (set_attr "prefix" "vex,evex")])
5427
5428 ;; Signed conversion to DImode.
5429
5430 (define_expand "fix_truncxfdi2"
5431 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5432 (fix:DI (match_operand:XF 1 "register_operand")))
5433 (clobber (reg:CC FLAGS_REG))])]
5434 "TARGET_80387"
5435 {
5436 if (TARGET_FISTTP)
5437 {
5438 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5439 DONE;
5440 }
5441 })
5442
5443 (define_expand "fix_trunc<mode>di2"
5444 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5445 (fix:DI (match_operand:MODEF 1 "register_operand")))
5446 (clobber (reg:CC FLAGS_REG))])]
5447 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5448 {
5449 if (TARGET_FISTTP
5450 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5451 {
5452 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5453 DONE;
5454 }
5455 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5456 {
5457 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5458 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5459 if (out != operands[0])
5460 emit_move_insn (operands[0], out);
5461 DONE;
5462 }
5463 })
5464
5465 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5466 [(set (match_operand:SWI48 0 "register_operand" "=r")
5467 (any_fix:SWI48
5468 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5469 "TARGET_AVX512FP16"
5470 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5471 [(set_attr "type" "sseicvt")
5472 (set_attr "prefix" "evex")
5473 (set_attr "mode" "<MODE>")])
5474
5475 ;; Signed conversion to SImode.
5476
5477 (define_expand "fix_truncxfsi2"
5478 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5479 (fix:SI (match_operand:XF 1 "register_operand")))
5480 (clobber (reg:CC FLAGS_REG))])]
5481 "TARGET_80387"
5482 {
5483 if (TARGET_FISTTP)
5484 {
5485 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5486 DONE;
5487 }
5488 })
5489
5490 (define_expand "fix_trunc<mode>si2"
5491 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5492 (fix:SI (match_operand:MODEF 1 "register_operand")))
5493 (clobber (reg:CC FLAGS_REG))])]
5494 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5495 {
5496 if (TARGET_FISTTP
5497 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5498 {
5499 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5500 DONE;
5501 }
5502 if (SSE_FLOAT_MODE_P (<MODE>mode))
5503 {
5504 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5505 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5506 if (out != operands[0])
5507 emit_move_insn (operands[0], out);
5508 DONE;
5509 }
5510 })
5511
5512 ;; Signed conversion to HImode.
5513
5514 (define_expand "fix_trunc<mode>hi2"
5515 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5516 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5517 (clobber (reg:CC FLAGS_REG))])]
5518 "TARGET_80387
5519 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5520 {
5521 if (TARGET_FISTTP)
5522 {
5523 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5524 DONE;
5525 }
5526 })
5527
5528 ;; Unsigned conversion to DImode
5529
5530 (define_insn "fixuns_trunc<mode>di2"
5531 [(set (match_operand:DI 0 "register_operand" "=r")
5532 (unsigned_fix:DI
5533 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5534 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5535 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5536 [(set_attr "type" "sseicvt")
5537 (set_attr "prefix" "evex")
5538 (set_attr "mode" "DI")])
5539
5540 ;; Unsigned conversion to SImode.
5541
5542 (define_expand "fixuns_trunc<mode>si2"
5543 [(parallel
5544 [(set (match_operand:SI 0 "register_operand")
5545 (unsigned_fix:SI
5546 (match_operand:MODEF 1 "nonimmediate_operand")))
5547 (use (match_dup 2))
5548 (clobber (scratch:<ssevecmode>))
5549 (clobber (scratch:<ssevecmode>))])]
5550 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5551 {
5552 machine_mode mode = <MODE>mode;
5553 machine_mode vecmode = <ssevecmode>mode;
5554 REAL_VALUE_TYPE TWO31r;
5555 rtx two31;
5556
5557 if (TARGET_AVX512F)
5558 {
5559 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5560 DONE;
5561 }
5562
5563 if (optimize_insn_for_size_p ())
5564 FAIL;
5565
5566 real_ldexp (&TWO31r, &dconst1, 31);
5567 two31 = const_double_from_real_value (TWO31r, mode);
5568 two31 = ix86_build_const_vector (vecmode, true, two31);
5569 operands[2] = force_reg (vecmode, two31);
5570 })
5571
5572 (define_insn "fixuns_trunc<mode>si2_avx512f"
5573 [(set (match_operand:SI 0 "register_operand" "=r")
5574 (unsigned_fix:SI
5575 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5576 "TARGET_AVX512F && TARGET_SSE_MATH"
5577 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5578 [(set_attr "type" "sseicvt")
5579 (set_attr "prefix" "evex")
5580 (set_attr "mode" "SI")])
5581
5582 (define_insn "*fixuns_trunchfsi2zext"
5583 [(set (match_operand:DI 0 "register_operand" "=r")
5584 (zero_extend:DI
5585 (unsigned_fix:SI
5586 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5587 "TARGET_64BIT && TARGET_AVX512FP16"
5588 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5589 [(set_attr "type" "sseicvt")
5590 (set_attr "prefix" "evex")
5591 (set_attr "mode" "SI")])
5592
5593 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5594 [(set (match_operand:DI 0 "register_operand" "=r")
5595 (zero_extend:DI
5596 (unsigned_fix:SI
5597 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5598 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5599 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5600 [(set_attr "type" "sseicvt")
5601 (set_attr "prefix" "evex")
5602 (set_attr "mode" "SI")])
5603
5604 (define_insn_and_split "*fixuns_trunc<mode>_1"
5605 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5606 (unsigned_fix:SI
5607 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5608 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5609 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5610 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5611 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5612 && optimize_function_for_speed_p (cfun)"
5613 "#"
5614 "&& reload_completed"
5615 [(const_int 0)]
5616 {
5617 ix86_split_convert_uns_si_sse (operands);
5618 DONE;
5619 })
5620
5621 ;; Unsigned conversion to HImode.
5622 ;; Without these patterns, we'll try the unsigned SI conversion which
5623 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5624
5625 (define_expand "fixuns_trunchfhi2"
5626 [(set (match_dup 2)
5627 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5628 (set (match_operand:HI 0 "nonimmediate_operand")
5629 (subreg:HI (match_dup 2) 0))]
5630 "TARGET_AVX512FP16"
5631 "operands[2] = gen_reg_rtx (SImode);")
5632
5633 (define_expand "fixuns_trunc<mode>hi2"
5634 [(set (match_dup 2)
5635 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5636 (set (match_operand:HI 0 "nonimmediate_operand")
5637 (subreg:HI (match_dup 2) 0))]
5638 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5639 "operands[2] = gen_reg_rtx (SImode);")
5640
5641 ;; When SSE is available, it is always faster to use it!
5642 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5643 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5644 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5645 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5646 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5647 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5648 [(set_attr "type" "sseicvt")
5649 (set_attr "prefix" "maybe_vex")
5650 (set (attr "prefix_rex")
5651 (if_then_else
5652 (match_test "<SWI48:MODE>mode == DImode")
5653 (const_string "1")
5654 (const_string "*")))
5655 (set_attr "mode" "<MODEF:MODE>")
5656 (set_attr "athlon_decode" "double,vector")
5657 (set_attr "amdfam10_decode" "double,double")
5658 (set_attr "bdver1_decode" "double,double")])
5659
5660 ;; Avoid vector decoded forms of the instruction.
5661 (define_peephole2
5662 [(match_scratch:MODEF 2 "x")
5663 (set (match_operand:SWI48 0 "register_operand")
5664 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5665 "TARGET_AVOID_VECTOR_DECODE
5666 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5667 && optimize_insn_for_speed_p ()"
5668 [(set (match_dup 2) (match_dup 1))
5669 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5670
5671 (define_insn "fix_trunc<mode>_i387_fisttp"
5672 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5673 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5674 (clobber (match_scratch:XF 2 "=&f"))]
5675 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5676 && TARGET_FISTTP
5677 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5678 && (TARGET_64BIT || <MODE>mode != DImode))
5679 && TARGET_SSE_MATH)"
5680 "* return output_fix_trunc (insn, operands, true);"
5681 [(set_attr "type" "fisttp")
5682 (set_attr "mode" "<MODE>")])
5683
5684 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5685 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5686 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5687 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5688 ;; function in i386.cc.
5689 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5690 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5691 (fix:SWI248x (match_operand 1 "register_operand")))
5692 (clobber (reg:CC FLAGS_REG))]
5693 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5694 && !TARGET_FISTTP
5695 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5696 && (TARGET_64BIT || <MODE>mode != DImode))
5697 && ix86_pre_reload_split ()"
5698 "#"
5699 "&& 1"
5700 [(const_int 0)]
5701 {
5702 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5703
5704 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5705 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5706
5707 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5708 operands[2], operands[3]));
5709 DONE;
5710 }
5711 [(set_attr "type" "fistp")
5712 (set_attr "i387_cw" "trunc")
5713 (set_attr "mode" "<MODE>")])
5714
5715 (define_insn "fix_truncdi_i387"
5716 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5717 (fix:DI (match_operand 1 "register_operand" "f")))
5718 (use (match_operand:HI 2 "memory_operand" "m"))
5719 (use (match_operand:HI 3 "memory_operand" "m"))
5720 (clobber (match_scratch:XF 4 "=&f"))]
5721 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5722 && !TARGET_FISTTP
5723 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5724 "* return output_fix_trunc (insn, operands, false);"
5725 [(set_attr "type" "fistp")
5726 (set_attr "i387_cw" "trunc")
5727 (set_attr "mode" "DI")])
5728
5729 (define_insn "fix_trunc<mode>_i387"
5730 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5731 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5732 (use (match_operand:HI 2 "memory_operand" "m"))
5733 (use (match_operand:HI 3 "memory_operand" "m"))]
5734 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5735 && !TARGET_FISTTP
5736 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5737 "* return output_fix_trunc (insn, operands, false);"
5738 [(set_attr "type" "fistp")
5739 (set_attr "i387_cw" "trunc")
5740 (set_attr "mode" "<MODE>")])
5741
5742 (define_insn "x86_fnstcw_1"
5743 [(set (match_operand:HI 0 "memory_operand" "=m")
5744 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5745 "TARGET_80387"
5746 "fnstcw\t%0"
5747 [(set (attr "length")
5748 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5749 (set_attr "mode" "HI")
5750 (set_attr "unit" "i387")
5751 (set_attr "bdver1_decode" "vector")])
5752 \f
5753 ;; Conversion between fixed point and floating point.
5754
5755 ;; Even though we only accept memory inputs, the backend _really_
5756 ;; wants to be able to do this between registers. Thankfully, LRA
5757 ;; will fix this up for us during register allocation.
5758
5759 (define_insn "floathi<mode>2"
5760 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5761 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5762 "TARGET_80387
5763 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5764 || TARGET_MIX_SSE_I387)"
5765 "fild%Z1\t%1"
5766 [(set_attr "type" "fmov")
5767 (set_attr "mode" "<MODE>")
5768 (set_attr "znver1_decode" "double")
5769 (set_attr "fp_int_src" "true")])
5770
5771 (define_insn "float<SWI48x:mode>xf2"
5772 [(set (match_operand:XF 0 "register_operand" "=f")
5773 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5774 "TARGET_80387"
5775 "fild%Z1\t%1"
5776 [(set_attr "type" "fmov")
5777 (set_attr "mode" "XF")
5778 (set_attr "znver1_decode" "double")
5779 (set_attr "fp_int_src" "true")])
5780
5781 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5782 [(set (match_operand:MODEF 0 "register_operand")
5783 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5784 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5785 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5786 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5787
5788 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5789 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5790 (float:MODEF
5791 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5792 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5793 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5794 "@
5795 fild%Z1\t%1
5796 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5797 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5798 [(set_attr "type" "fmov,sseicvt,sseicvt")
5799 (set_attr "avx_partial_xmm_update" "false,true,true")
5800 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5801 (set_attr "mode" "<MODEF:MODE>")
5802 (set (attr "prefix_rex")
5803 (if_then_else
5804 (and (eq_attr "prefix" "maybe_vex")
5805 (match_test "<SWI48:MODE>mode == DImode"))
5806 (const_string "1")
5807 (const_string "*")))
5808 (set_attr "unit" "i387,*,*")
5809 (set_attr "athlon_decode" "*,double,direct")
5810 (set_attr "amdfam10_decode" "*,vector,double")
5811 (set_attr "bdver1_decode" "*,double,direct")
5812 (set_attr "znver1_decode" "double,*,*")
5813 (set_attr "fp_int_src" "true")
5814 (set (attr "enabled")
5815 (if_then_else
5816 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5817 (if_then_else
5818 (eq_attr "alternative" "0")
5819 (symbol_ref "TARGET_MIX_SSE_I387
5820 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5821 <SWI48:MODE>mode)")
5822 (symbol_ref "true"))
5823 (if_then_else
5824 (eq_attr "alternative" "0")
5825 (symbol_ref "true")
5826 (symbol_ref "false"))))
5827 (set (attr "preferred_for_speed")
5828 (cond [(eq_attr "alternative" "1")
5829 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5830 (symbol_ref "true")))])
5831
5832 (define_insn "float<floatunssuffix><mode>hf2"
5833 [(set (match_operand:HF 0 "register_operand" "=v")
5834 (any_float:HF
5835 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5836 "TARGET_AVX512FP16"
5837 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
5838 [(set_attr "type" "sseicvt")
5839 (set_attr "prefix" "evex")
5840 (set_attr "mode" "HF")])
5841
5842 (define_insn "*floatdi<MODEF:mode>2_i387"
5843 [(set (match_operand:MODEF 0 "register_operand" "=f")
5844 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5845 "!TARGET_64BIT
5846 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5847 "fild%Z1\t%1"
5848 [(set_attr "type" "fmov")
5849 (set_attr "mode" "<MODEF:MODE>")
5850 (set_attr "znver1_decode" "double")
5851 (set_attr "fp_int_src" "true")])
5852
5853 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5854 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5855 ;; alternative in sse2_loadld.
5856 (define_split
5857 [(set (match_operand:MODEF 0 "sse_reg_operand")
5858 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5859 "TARGET_SSE2
5860 && TARGET_USE_VECTOR_CONVERTS
5861 && optimize_function_for_speed_p (cfun)
5862 && reload_completed
5863 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5864 && (!EXT_REX_SSE_REG_P (operands[0])
5865 || TARGET_AVX512VL)"
5866 [(const_int 0)]
5867 {
5868 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5869 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5870
5871 emit_insn (gen_sse2_loadld (operands[4],
5872 CONST0_RTX (V4SImode), operands[1]));
5873
5874 if (<ssevecmode>mode == V4SFmode)
5875 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5876 else
5877 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5878 DONE;
5879 })
5880
5881 ;; Avoid store forwarding (partial memory) stall penalty
5882 ;; by passing DImode value through XMM registers. */
5883
5884 (define_split
5885 [(set (match_operand:X87MODEF 0 "register_operand")
5886 (float:X87MODEF
5887 (match_operand:DI 1 "register_operand")))]
5888 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5889 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5890 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5891 && can_create_pseudo_p ()"
5892 [(const_int 0)]
5893 {
5894 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
5895 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
5896 DONE;
5897 })
5898
5899 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5900 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5901 (float:X87MODEF
5902 (match_operand:DI 1 "register_operand" "r,r")))
5903 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5904 (clobber (match_scratch:V4SI 3 "=x,x"))
5905 (clobber (match_scratch:V4SI 4 "=X,x"))]
5906 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5907 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5908 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5909 "#"
5910 "&& reload_completed"
5911 [(set (match_dup 2) (match_dup 3))
5912 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5913 {
5914 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5915 Assemble the 64-bit DImode value in an xmm register. */
5916 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5917 gen_lowpart (SImode, operands[1])));
5918 if (TARGET_SSE4_1)
5919 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5920 gen_highpart (SImode, operands[1]),
5921 GEN_INT (2)));
5922 else
5923 {
5924 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5925 gen_highpart (SImode, operands[1])));
5926 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5927 operands[4]));
5928 }
5929 operands[3] = gen_lowpart (DImode, operands[3]);
5930 }
5931 [(set_attr "isa" "sse4,*")
5932 (set_attr "type" "multi")
5933 (set_attr "mode" "<X87MODEF:MODE>")
5934 (set_attr "unit" "i387")
5935 (set_attr "fp_int_src" "true")])
5936
5937 ;; Break partial SSE register dependency stall. This splitter should split
5938 ;; late in the pass sequence (after register rename pass), so allocated
5939 ;; registers won't change anymore
5940
5941 (define_split
5942 [(set (match_operand:MODEF 0 "sse_reg_operand")
5943 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5944 "!TARGET_AVX
5945 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
5946 && epilogue_completed
5947 && optimize_function_for_speed_p (cfun)
5948 && (!EXT_REX_SSE_REG_P (operands[0])
5949 || TARGET_AVX512VL)"
5950 [(set (match_dup 0)
5951 (vec_merge:<MODEF:ssevecmode>
5952 (vec_duplicate:<MODEF:ssevecmode>
5953 (float:MODEF
5954 (match_dup 1)))
5955 (match_dup 0)
5956 (const_int 1)))]
5957 {
5958 const machine_mode vmode = <MODEF:ssevecmode>mode;
5959
5960 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5961 emit_move_insn (operands[0], CONST0_RTX (vmode));
5962 })
5963
5964 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5965 [(set (match_operand:MODEF 0 "register_operand")
5966 (unsigned_float:MODEF
5967 (match_operand:SWI12 1 "nonimmediate_operand")))]
5968 "!TARGET_64BIT
5969 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5970 {
5971 operands[1] = convert_to_mode (SImode, operands[1], 1);
5972 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5973 DONE;
5974 })
5975
5976 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5977 [(set (match_operand:MODEF 0 "register_operand" "=v")
5978 (unsigned_float:MODEF
5979 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5980 "TARGET_AVX512F && TARGET_SSE_MATH"
5981 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5982 [(set_attr "type" "sseicvt")
5983 (set_attr "avx_partial_xmm_update" "true")
5984 (set_attr "prefix" "evex")
5985 (set_attr "mode" "<MODEF:MODE>")])
5986
5987 ;; Avoid store forwarding (partial memory) stall penalty by extending
5988 ;; SImode value to DImode through XMM register instead of pushing two
5989 ;; SImode values to stack. Also note that fild loads from memory only.
5990
5991 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5992 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5993 (unsigned_float:X87MODEF
5994 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5995 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5996 (clobber (match_scratch:DI 3 "=x"))]
5997 "!TARGET_64BIT
5998 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5999 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6000 "#"
6001 "&& reload_completed"
6002 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6003 (set (match_dup 2) (match_dup 3))
6004 (set (match_dup 0)
6005 (float:X87MODEF (match_dup 2)))]
6006 ""
6007 [(set_attr "type" "multi")
6008 (set_attr "mode" "<MODE>")])
6009
6010 (define_expand "floatunssi<mode>2"
6011 [(set (match_operand:X87MODEF 0 "register_operand")
6012 (unsigned_float:X87MODEF
6013 (match_operand:SI 1 "nonimmediate_operand")))]
6014 "(!TARGET_64BIT
6015 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6016 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6017 || ((!TARGET_64BIT || TARGET_AVX512F)
6018 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6019 {
6020 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6021 {
6022 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6023 (operands[0], operands[1],
6024 assign_386_stack_local (DImode, SLOT_TEMP)));
6025 DONE;
6026 }
6027 if (!TARGET_AVX512F)
6028 {
6029 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6030 DONE;
6031 }
6032 })
6033
6034 (define_expand "floatunsdisf2"
6035 [(set (match_operand:SF 0 "register_operand")
6036 (unsigned_float:SF
6037 (match_operand:DI 1 "nonimmediate_operand")))]
6038 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6039 {
6040 if (!TARGET_AVX512F)
6041 {
6042 x86_emit_floatuns (operands);
6043 DONE;
6044 }
6045 })
6046
6047 (define_expand "floatunsdidf2"
6048 [(set (match_operand:DF 0 "register_operand")
6049 (unsigned_float:DF
6050 (match_operand:DI 1 "nonimmediate_operand")))]
6051 "((TARGET_64BIT && TARGET_AVX512F)
6052 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6053 && TARGET_SSE2 && TARGET_SSE_MATH"
6054 {
6055 if (!TARGET_64BIT)
6056 {
6057 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6058 DONE;
6059 }
6060 if (!TARGET_AVX512F)
6061 {
6062 x86_emit_floatuns (operands);
6063 DONE;
6064 }
6065 })
6066 \f
6067 ;; Load effective address instructions
6068
6069 (define_insn "*lea<mode>"
6070 [(set (match_operand:SWI48 0 "register_operand" "=r")
6071 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6072 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6073 {
6074 if (SImode_address_operand (operands[1], VOIDmode))
6075 {
6076 gcc_assert (TARGET_64BIT);
6077 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6078 }
6079 else
6080 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6081 }
6082 [(set_attr "type" "lea")
6083 (set (attr "mode")
6084 (if_then_else
6085 (match_operand 1 "SImode_address_operand")
6086 (const_string "SI")
6087 (const_string "<MODE>")))])
6088
6089 (define_peephole2
6090 [(set (match_operand:SWI48 0 "register_operand")
6091 (match_operand:SWI48 1 "address_no_seg_operand"))]
6092 "ix86_hardreg_mov_ok (operands[0], operands[1])
6093 && peep2_regno_dead_p (0, FLAGS_REG)
6094 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6095 [(const_int 0)]
6096 {
6097 machine_mode mode = <MODE>mode;
6098
6099 /* Emit all operations in SImode for zero-extended addresses. */
6100 if (SImode_address_operand (operands[1], VOIDmode))
6101 mode = SImode;
6102
6103 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6104
6105 /* Zero-extend return register to DImode for zero-extended addresses. */
6106 if (mode != <MODE>mode)
6107 emit_insn (gen_zero_extendsidi2 (operands[0],
6108 gen_lowpart (mode, operands[0])));
6109
6110 DONE;
6111 })
6112
6113 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6114 ;; peephole2 optimized back into a lea. Split that into the shift during
6115 ;; the following split pass.
6116 (define_split
6117 [(set (match_operand:SWI48 0 "general_reg_operand")
6118 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6119 (clobber (reg:CC FLAGS_REG))]
6120 "reload_completed"
6121 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6122 (clobber (reg:CC FLAGS_REG))])]
6123 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6124 \f
6125 ;; Add instructions
6126
6127 (define_expand "add<mode>3"
6128 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6129 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6130 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6131 ""
6132 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6133
6134 (define_insn_and_split "*add<dwi>3_doubleword"
6135 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6136 (plus:<DWI>
6137 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6138 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6139 (clobber (reg:CC FLAGS_REG))]
6140 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6141 "#"
6142 "&& reload_completed"
6143 [(parallel [(set (reg:CCC FLAGS_REG)
6144 (compare:CCC
6145 (plus:DWIH (match_dup 1) (match_dup 2))
6146 (match_dup 1)))
6147 (set (match_dup 0)
6148 (plus:DWIH (match_dup 1) (match_dup 2)))])
6149 (parallel [(set (match_dup 3)
6150 (plus:DWIH
6151 (plus:DWIH
6152 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6153 (match_dup 4))
6154 (match_dup 5)))
6155 (clobber (reg:CC FLAGS_REG))])]
6156 {
6157 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6158 if (operands[2] == const0_rtx)
6159 {
6160 if (operands[5] != const0_rtx)
6161 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6162 else if (!rtx_equal_p (operands[3], operands[4]))
6163 emit_move_insn (operands[3], operands[4]);
6164 else
6165 emit_note (NOTE_INSN_DELETED);
6166 DONE;
6167 }
6168 })
6169
6170 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6171 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6172 (plus:<DWI>
6173 (zero_extend:<DWI>
6174 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))
6175 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6176 (clobber (reg:CC FLAGS_REG))]
6177 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6178 "#"
6179 "&& reload_completed"
6180 [(parallel [(set (reg:CCC FLAGS_REG)
6181 (compare:CCC
6182 (plus:DWIH (match_dup 1) (match_dup 2))
6183 (match_dup 1)))
6184 (set (match_dup 0)
6185 (plus:DWIH (match_dup 1) (match_dup 2)))])
6186 (parallel [(set (match_dup 3)
6187 (plus:DWIH
6188 (plus:DWIH
6189 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6190 (match_dup 4))
6191 (const_int 0)))
6192 (clobber (reg:CC FLAGS_REG))])]
6193 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6194
6195 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6196 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6197 (plus:<DWI>
6198 (any_or_plus:<DWI>
6199 (ashift:<DWI>
6200 (zero_extend:<DWI>
6201 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6202 (match_operand:QI 3 "const_int_operand"))
6203 (zero_extend:<DWI>
6204 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6205 (match_operand:<DWI> 1 "register_operand" "0")))
6206 (clobber (reg:CC FLAGS_REG))]
6207 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6208 "#"
6209 "&& reload_completed"
6210 [(parallel [(set (reg:CCC FLAGS_REG)
6211 (compare:CCC
6212 (plus:DWIH (match_dup 1) (match_dup 4))
6213 (match_dup 1)))
6214 (set (match_dup 0)
6215 (plus:DWIH (match_dup 1) (match_dup 4)))])
6216 (parallel [(set (match_dup 5)
6217 (plus:DWIH
6218 (plus:DWIH
6219 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6220 (match_dup 6))
6221 (match_dup 2)))
6222 (clobber (reg:CC FLAGS_REG))])]
6223 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6224
6225 (define_insn "*add<mode>_1"
6226 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6227 (plus:SWI48
6228 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6229 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6230 (clobber (reg:CC FLAGS_REG))]
6231 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6232 {
6233 switch (get_attr_type (insn))
6234 {
6235 case TYPE_LEA:
6236 return "#";
6237
6238 case TYPE_INCDEC:
6239 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6240 if (operands[2] == const1_rtx)
6241 return "inc{<imodesuffix>}\t%0";
6242 else
6243 {
6244 gcc_assert (operands[2] == constm1_rtx);
6245 return "dec{<imodesuffix>}\t%0";
6246 }
6247
6248 default:
6249 /* For most processors, ADD is faster than LEA. This alternative
6250 was added to use ADD as much as possible. */
6251 if (which_alternative == 2)
6252 std::swap (operands[1], operands[2]);
6253
6254 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6255 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6256 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6257
6258 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6259 }
6260 }
6261 [(set (attr "type")
6262 (cond [(eq_attr "alternative" "3")
6263 (const_string "lea")
6264 (match_operand:SWI48 2 "incdec_operand")
6265 (const_string "incdec")
6266 ]
6267 (const_string "alu")))
6268 (set (attr "length_immediate")
6269 (if_then_else
6270 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6271 (const_string "1")
6272 (const_string "*")))
6273 (set_attr "mode" "<MODE>")])
6274
6275 ;; It may seem that nonimmediate operand is proper one for operand 1.
6276 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6277 ;; we take care in ix86_binary_operator_ok to not allow two memory
6278 ;; operands so proper swapping will be done in reload. This allow
6279 ;; patterns constructed from addsi_1 to match.
6280
6281 (define_insn "addsi_1_zext"
6282 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6283 (zero_extend:DI
6284 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6285 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6286 (clobber (reg:CC FLAGS_REG))]
6287 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6288 {
6289 switch (get_attr_type (insn))
6290 {
6291 case TYPE_LEA:
6292 return "#";
6293
6294 case TYPE_INCDEC:
6295 if (operands[2] == const1_rtx)
6296 return "inc{l}\t%k0";
6297 else
6298 {
6299 gcc_assert (operands[2] == constm1_rtx);
6300 return "dec{l}\t%k0";
6301 }
6302
6303 default:
6304 /* For most processors, ADD is faster than LEA. This alternative
6305 was added to use ADD as much as possible. */
6306 if (which_alternative == 1)
6307 std::swap (operands[1], operands[2]);
6308
6309 if (x86_maybe_negate_const_int (&operands[2], SImode))
6310 return "sub{l}\t{%2, %k0|%k0, %2}";
6311
6312 return "add{l}\t{%2, %k0|%k0, %2}";
6313 }
6314 }
6315 [(set (attr "type")
6316 (cond [(eq_attr "alternative" "2")
6317 (const_string "lea")
6318 (match_operand:SI 2 "incdec_operand")
6319 (const_string "incdec")
6320 ]
6321 (const_string "alu")))
6322 (set (attr "length_immediate")
6323 (if_then_else
6324 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6325 (const_string "1")
6326 (const_string "*")))
6327 (set_attr "mode" "SI")])
6328
6329 (define_insn "*addhi_1"
6330 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6331 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6332 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6333 (clobber (reg:CC FLAGS_REG))]
6334 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6335 {
6336 switch (get_attr_type (insn))
6337 {
6338 case TYPE_LEA:
6339 return "#";
6340
6341 case TYPE_INCDEC:
6342 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6343 if (operands[2] == const1_rtx)
6344 return "inc{w}\t%0";
6345 else
6346 {
6347 gcc_assert (operands[2] == constm1_rtx);
6348 return "dec{w}\t%0";
6349 }
6350
6351 default:
6352 /* For most processors, ADD is faster than LEA. This alternative
6353 was added to use ADD as much as possible. */
6354 if (which_alternative == 2)
6355 std::swap (operands[1], operands[2]);
6356
6357 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6358 if (x86_maybe_negate_const_int (&operands[2], HImode))
6359 return "sub{w}\t{%2, %0|%0, %2}";
6360
6361 return "add{w}\t{%2, %0|%0, %2}";
6362 }
6363 }
6364 [(set (attr "type")
6365 (cond [(eq_attr "alternative" "3")
6366 (const_string "lea")
6367 (match_operand:HI 2 "incdec_operand")
6368 (const_string "incdec")
6369 ]
6370 (const_string "alu")))
6371 (set (attr "length_immediate")
6372 (if_then_else
6373 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6374 (const_string "1")
6375 (const_string "*")))
6376 (set_attr "mode" "HI,HI,HI,SI")])
6377
6378 (define_insn "*addqi_1"
6379 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6380 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6381 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6382 (clobber (reg:CC FLAGS_REG))]
6383 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6384 {
6385 bool widen = (get_attr_mode (insn) != MODE_QI);
6386
6387 switch (get_attr_type (insn))
6388 {
6389 case TYPE_LEA:
6390 return "#";
6391
6392 case TYPE_INCDEC:
6393 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6394 if (operands[2] == const1_rtx)
6395 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6396 else
6397 {
6398 gcc_assert (operands[2] == constm1_rtx);
6399 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6400 }
6401
6402 default:
6403 /* For most processors, ADD is faster than LEA. These alternatives
6404 were added to use ADD as much as possible. */
6405 if (which_alternative == 2 || which_alternative == 4)
6406 std::swap (operands[1], operands[2]);
6407
6408 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6409 if (x86_maybe_negate_const_int (&operands[2], QImode))
6410 {
6411 if (widen)
6412 return "sub{l}\t{%2, %k0|%k0, %2}";
6413 else
6414 return "sub{b}\t{%2, %0|%0, %2}";
6415 }
6416 if (widen)
6417 return "add{l}\t{%k2, %k0|%k0, %k2}";
6418 else
6419 return "add{b}\t{%2, %0|%0, %2}";
6420 }
6421 }
6422 [(set (attr "type")
6423 (cond [(eq_attr "alternative" "5")
6424 (const_string "lea")
6425 (match_operand:QI 2 "incdec_operand")
6426 (const_string "incdec")
6427 ]
6428 (const_string "alu")))
6429 (set (attr "length_immediate")
6430 (if_then_else
6431 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6432 (const_string "1")
6433 (const_string "*")))
6434 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6435 ;; Potential partial reg stall on alternatives 3 and 4.
6436 (set (attr "preferred_for_speed")
6437 (cond [(eq_attr "alternative" "3,4")
6438 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6439 (symbol_ref "true")))])
6440
6441 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6442 (define_insn_and_split "*add<mode>_1_slp"
6443 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6444 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6445 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6446 (clobber (reg:CC FLAGS_REG))]
6447 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6448 {
6449 if (which_alternative)
6450 return "#";
6451
6452 switch (get_attr_type (insn))
6453 {
6454 case TYPE_INCDEC:
6455 if (operands[2] == const1_rtx)
6456 return "inc{<imodesuffix>}\t%0";
6457 else
6458 {
6459 gcc_assert (operands[2] == constm1_rtx);
6460 return "dec{<imodesuffix>}\t%0";
6461 }
6462
6463 default:
6464 if (x86_maybe_negate_const_int (&operands[2], QImode))
6465 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6466
6467 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6468 }
6469 }
6470 "&& reload_completed"
6471 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6472 (parallel
6473 [(set (strict_low_part (match_dup 0))
6474 (plus:SWI12 (match_dup 0) (match_dup 2)))
6475 (clobber (reg:CC FLAGS_REG))])]
6476 ""
6477 [(set (attr "type")
6478 (if_then_else (match_operand:QI 2 "incdec_operand")
6479 (const_string "incdec")
6480 (const_string "alu")))
6481 (set_attr "mode" "<MODE>")])
6482
6483 ;; Split non destructive adds if we cannot use lea.
6484 (define_split
6485 [(set (match_operand:SWI48 0 "register_operand")
6486 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6487 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6488 (clobber (reg:CC FLAGS_REG))]
6489 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6490 [(set (match_dup 0) (match_dup 1))
6491 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6492 (clobber (reg:CC FLAGS_REG))])])
6493
6494 ;; Split non destructive adds if we cannot use lea.
6495 (define_split
6496 [(set (match_operand:DI 0 "register_operand")
6497 (zero_extend:DI
6498 (plus:SI (match_operand:SI 1 "register_operand")
6499 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6500 (clobber (reg:CC FLAGS_REG))]
6501 "TARGET_64BIT
6502 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6503 [(set (match_dup 3) (match_dup 1))
6504 (parallel [(set (match_dup 0)
6505 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6506 (clobber (reg:CC FLAGS_REG))])]
6507 "operands[3] = gen_lowpart (SImode, operands[0]);")
6508
6509 ;; Convert add to the lea pattern to avoid flags dependency.
6510 (define_split
6511 [(set (match_operand:SWI 0 "register_operand")
6512 (plus:SWI (match_operand:SWI 1 "register_operand")
6513 (match_operand:SWI 2 "<nonmemory_operand>")))
6514 (clobber (reg:CC FLAGS_REG))]
6515 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6516 [(set (match_dup 0)
6517 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6518 {
6519 if (<MODE>mode != <LEAMODE>mode)
6520 {
6521 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6522 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6523 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6524 }
6525 })
6526
6527 ;; Convert add to the lea pattern to avoid flags dependency.
6528 (define_split
6529 [(set (match_operand:DI 0 "register_operand")
6530 (zero_extend:DI
6531 (plus:SI (match_operand:SI 1 "register_operand")
6532 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6533 (clobber (reg:CC FLAGS_REG))]
6534 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6535 [(set (match_dup 0)
6536 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6537
6538 (define_insn "*add<mode>_2"
6539 [(set (reg FLAGS_REG)
6540 (compare
6541 (plus:SWI
6542 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6543 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6544 (const_int 0)))
6545 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6546 (plus:SWI (match_dup 1) (match_dup 2)))]
6547 "ix86_match_ccmode (insn, CCGOCmode)
6548 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6549 {
6550 switch (get_attr_type (insn))
6551 {
6552 case TYPE_INCDEC:
6553 if (operands[2] == const1_rtx)
6554 return "inc{<imodesuffix>}\t%0";
6555 else
6556 {
6557 gcc_assert (operands[2] == constm1_rtx);
6558 return "dec{<imodesuffix>}\t%0";
6559 }
6560
6561 default:
6562 if (which_alternative == 2)
6563 std::swap (operands[1], operands[2]);
6564
6565 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6566 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6567 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6568
6569 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6570 }
6571 }
6572 [(set (attr "type")
6573 (if_then_else (match_operand:SWI 2 "incdec_operand")
6574 (const_string "incdec")
6575 (const_string "alu")))
6576 (set (attr "length_immediate")
6577 (if_then_else
6578 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6579 (const_string "1")
6580 (const_string "*")))
6581 (set_attr "mode" "<MODE>")])
6582
6583 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6584 (define_insn "*addsi_2_zext"
6585 [(set (reg FLAGS_REG)
6586 (compare
6587 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6588 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6589 (const_int 0)))
6590 (set (match_operand:DI 0 "register_operand" "=r,r")
6591 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6592 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6593 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6594 {
6595 switch (get_attr_type (insn))
6596 {
6597 case TYPE_INCDEC:
6598 if (operands[2] == const1_rtx)
6599 return "inc{l}\t%k0";
6600 else
6601 {
6602 gcc_assert (operands[2] == constm1_rtx);
6603 return "dec{l}\t%k0";
6604 }
6605
6606 default:
6607 if (which_alternative == 1)
6608 std::swap (operands[1], operands[2]);
6609
6610 if (x86_maybe_negate_const_int (&operands[2], SImode))
6611 return "sub{l}\t{%2, %k0|%k0, %2}";
6612
6613 return "add{l}\t{%2, %k0|%k0, %2}";
6614 }
6615 }
6616 [(set (attr "type")
6617 (if_then_else (match_operand:SI 2 "incdec_operand")
6618 (const_string "incdec")
6619 (const_string "alu")))
6620 (set (attr "length_immediate")
6621 (if_then_else
6622 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6623 (const_string "1")
6624 (const_string "*")))
6625 (set_attr "mode" "SI")])
6626
6627 (define_insn "*add<mode>_3"
6628 [(set (reg FLAGS_REG)
6629 (compare
6630 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6631 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6632 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6633 "ix86_match_ccmode (insn, CCZmode)
6634 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6635 {
6636 switch (get_attr_type (insn))
6637 {
6638 case TYPE_INCDEC:
6639 if (operands[2] == const1_rtx)
6640 return "inc{<imodesuffix>}\t%0";
6641 else
6642 {
6643 gcc_assert (operands[2] == constm1_rtx);
6644 return "dec{<imodesuffix>}\t%0";
6645 }
6646
6647 default:
6648 if (which_alternative == 1)
6649 std::swap (operands[1], operands[2]);
6650
6651 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6652 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6653 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6654
6655 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6656 }
6657 }
6658 [(set (attr "type")
6659 (if_then_else (match_operand:SWI 2 "incdec_operand")
6660 (const_string "incdec")
6661 (const_string "alu")))
6662 (set (attr "length_immediate")
6663 (if_then_else
6664 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6665 (const_string "1")
6666 (const_string "*")))
6667 (set_attr "mode" "<MODE>")])
6668
6669 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6670 (define_insn "*addsi_3_zext"
6671 [(set (reg FLAGS_REG)
6672 (compare
6673 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6674 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6675 (set (match_operand:DI 0 "register_operand" "=r,r")
6676 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6677 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6678 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6679 {
6680 switch (get_attr_type (insn))
6681 {
6682 case TYPE_INCDEC:
6683 if (operands[2] == const1_rtx)
6684 return "inc{l}\t%k0";
6685 else
6686 {
6687 gcc_assert (operands[2] == constm1_rtx);
6688 return "dec{l}\t%k0";
6689 }
6690
6691 default:
6692 if (which_alternative == 1)
6693 std::swap (operands[1], operands[2]);
6694
6695 if (x86_maybe_negate_const_int (&operands[2], SImode))
6696 return "sub{l}\t{%2, %k0|%k0, %2}";
6697
6698 return "add{l}\t{%2, %k0|%k0, %2}";
6699 }
6700 }
6701 [(set (attr "type")
6702 (if_then_else (match_operand:SI 2 "incdec_operand")
6703 (const_string "incdec")
6704 (const_string "alu")))
6705 (set (attr "length_immediate")
6706 (if_then_else
6707 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6708 (const_string "1")
6709 (const_string "*")))
6710 (set_attr "mode" "SI")])
6711
6712 ; For comparisons against 1, -1 and 128, we may generate better code
6713 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6714 ; is matched then. We can't accept general immediate, because for
6715 ; case of overflows, the result is messed up.
6716 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6717 ; only for comparisons not depending on it.
6718
6719 (define_insn "*adddi_4"
6720 [(set (reg FLAGS_REG)
6721 (compare
6722 (match_operand:DI 1 "nonimmediate_operand" "0")
6723 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6724 (clobber (match_scratch:DI 0 "=r"))]
6725 "TARGET_64BIT
6726 && ix86_match_ccmode (insn, CCGCmode)"
6727 {
6728 switch (get_attr_type (insn))
6729 {
6730 case TYPE_INCDEC:
6731 if (operands[2] == constm1_rtx)
6732 return "inc{q}\t%0";
6733 else
6734 {
6735 gcc_assert (operands[2] == const1_rtx);
6736 return "dec{q}\t%0";
6737 }
6738
6739 default:
6740 if (x86_maybe_negate_const_int (&operands[2], DImode))
6741 return "add{q}\t{%2, %0|%0, %2}";
6742
6743 return "sub{q}\t{%2, %0|%0, %2}";
6744 }
6745 }
6746 [(set (attr "type")
6747 (if_then_else (match_operand:DI 2 "incdec_operand")
6748 (const_string "incdec")
6749 (const_string "alu")))
6750 (set (attr "length_immediate")
6751 (if_then_else
6752 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6753 (const_string "1")
6754 (const_string "*")))
6755 (set_attr "mode" "DI")])
6756
6757 ; For comparisons against 1, -1 and 128, we may generate better code
6758 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6759 ; is matched then. We can't accept general immediate, because for
6760 ; case of overflows, the result is messed up.
6761 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6762 ; only for comparisons not depending on it.
6763
6764 (define_insn "*add<mode>_4"
6765 [(set (reg FLAGS_REG)
6766 (compare
6767 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6768 (match_operand:SWI124 2 "const_int_operand")))
6769 (clobber (match_scratch:SWI124 0 "=<r>"))]
6770 "ix86_match_ccmode (insn, CCGCmode)"
6771 {
6772 switch (get_attr_type (insn))
6773 {
6774 case TYPE_INCDEC:
6775 if (operands[2] == constm1_rtx)
6776 return "inc{<imodesuffix>}\t%0";
6777 else
6778 {
6779 gcc_assert (operands[2] == const1_rtx);
6780 return "dec{<imodesuffix>}\t%0";
6781 }
6782
6783 default:
6784 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6785 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6786
6787 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6788 }
6789 }
6790 [(set (attr "type")
6791 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6792 (const_string "incdec")
6793 (const_string "alu")))
6794 (set (attr "length_immediate")
6795 (if_then_else
6796 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6797 (const_string "1")
6798 (const_string "*")))
6799 (set_attr "mode" "<MODE>")])
6800
6801 (define_insn "*add<mode>_5"
6802 [(set (reg FLAGS_REG)
6803 (compare
6804 (plus:SWI
6805 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6806 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6807 (const_int 0)))
6808 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6809 "ix86_match_ccmode (insn, CCGOCmode)
6810 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6811 {
6812 switch (get_attr_type (insn))
6813 {
6814 case TYPE_INCDEC:
6815 if (operands[2] == const1_rtx)
6816 return "inc{<imodesuffix>}\t%0";
6817 else
6818 {
6819 gcc_assert (operands[2] == constm1_rtx);
6820 return "dec{<imodesuffix>}\t%0";
6821 }
6822
6823 default:
6824 if (which_alternative == 1)
6825 std::swap (operands[1], operands[2]);
6826
6827 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6828 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6829 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6830
6831 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6832 }
6833 }
6834 [(set (attr "type")
6835 (if_then_else (match_operand:SWI 2 "incdec_operand")
6836 (const_string "incdec")
6837 (const_string "alu")))
6838 (set (attr "length_immediate")
6839 (if_then_else
6840 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6841 (const_string "1")
6842 (const_string "*")))
6843 (set_attr "mode" "<MODE>")])
6844
6845 (define_insn "*addqi_ext<mode>_0"
6846 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
6847 (plus:QI
6848 (subreg:QI
6849 (match_operator:SWI248 3 "extract_operator"
6850 [(match_operand 2 "int248_register_operand" "Q,Q")
6851 (const_int 8)
6852 (const_int 8)]) 0)
6853 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
6854 (clobber (reg:CC FLAGS_REG))]
6855 ""
6856 "add{b}\t{%h2, %0|%0, %h2}"
6857 [(set_attr "isa" "*,nox64")
6858 (set_attr "type" "alu")
6859 (set_attr "mode" "QI")])
6860
6861 (define_expand "addqi_ext_1"
6862 [(parallel
6863 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
6864 (const_int 8)
6865 (const_int 8))
6866 (subreg:HI
6867 (plus:QI
6868 (subreg:QI
6869 (zero_extract:HI (match_operand:HI 1 "register_operand")
6870 (const_int 8)
6871 (const_int 8)) 0)
6872 (match_operand:QI 2 "const_int_operand")) 0))
6873 (clobber (reg:CC FLAGS_REG))])])
6874
6875 (define_insn "*addqi_ext<mode>_1"
6876 [(set (zero_extract:SWI248
6877 (match_operand 0 "int248_register_operand" "+Q,Q")
6878 (const_int 8)
6879 (const_int 8))
6880 (subreg:SWI248
6881 (plus:QI
6882 (subreg:QI
6883 (match_operator:SWI248 3 "extract_operator"
6884 [(match_operand 1 "int248_register_operand" "0,0")
6885 (const_int 8)
6886 (const_int 8)]) 0)
6887 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
6888 (clobber (reg:CC FLAGS_REG))]
6889 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6890 rtx_equal_p (operands[0], operands[1])"
6891 {
6892 switch (get_attr_type (insn))
6893 {
6894 case TYPE_INCDEC:
6895 if (operands[2] == const1_rtx)
6896 return "inc{b}\t%h0";
6897 else
6898 {
6899 gcc_assert (operands[2] == constm1_rtx);
6900 return "dec{b}\t%h0";
6901 }
6902
6903 default:
6904 return "add{b}\t{%2, %h0|%h0, %2}";
6905 }
6906 }
6907 [(set_attr "isa" "*,nox64")
6908 (set (attr "type")
6909 (if_then_else (match_operand:QI 2 "incdec_operand")
6910 (const_string "incdec")
6911 (const_string "alu")))
6912 (set_attr "mode" "QI")])
6913
6914 (define_insn "*addqi_ext<mode>_2"
6915 [(set (zero_extract:SWI248
6916 (match_operand 0 "int248_register_operand" "+Q")
6917 (const_int 8)
6918 (const_int 8))
6919 (subreg:SWI248
6920 (plus:QI
6921 (subreg:QI
6922 (match_operator:SWI248 3 "extract_operator"
6923 [(match_operand 1 "int248_register_operand" "%0")
6924 (const_int 8)
6925 (const_int 8)]) 0)
6926 (subreg:QI
6927 (match_operator:SWI248 4 "extract_operator"
6928 [(match_operand 2 "int248_register_operand" "Q")
6929 (const_int 8)
6930 (const_int 8)]) 0)) 0))
6931 (clobber (reg:CC FLAGS_REG))]
6932 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6933 rtx_equal_p (operands[0], operands[1])
6934 || rtx_equal_p (operands[0], operands[2])"
6935 "add{b}\t{%h2, %h0|%h0, %h2}"
6936 [(set_attr "type" "alu")
6937 (set_attr "mode" "QI")])
6938
6939 ;; Like DWI, but use POImode instead of OImode.
6940 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
6941
6942 ;; Add with jump on overflow.
6943 (define_expand "addv<mode>4"
6944 [(parallel [(set (reg:CCO FLAGS_REG)
6945 (eq:CCO
6946 (plus:<DPWI>
6947 (sign_extend:<DPWI>
6948 (match_operand:SWIDWI 1 "nonimmediate_operand"))
6949 (match_dup 4))
6950 (sign_extend:<DPWI>
6951 (plus:SWIDWI (match_dup 1)
6952 (match_operand:SWIDWI 2
6953 "<general_hilo_operand>")))))
6954 (set (match_operand:SWIDWI 0 "register_operand")
6955 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
6956 (set (pc) (if_then_else
6957 (eq (reg:CCO FLAGS_REG) (const_int 0))
6958 (label_ref (match_operand 3))
6959 (pc)))]
6960 ""
6961 {
6962 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6963 if (CONST_SCALAR_INT_P (operands[2]))
6964 operands[4] = operands[2];
6965 else
6966 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
6967 })
6968
6969 (define_insn "*addv<mode>4"
6970 [(set (reg:CCO FLAGS_REG)
6971 (eq:CCO (plus:<DWI>
6972 (sign_extend:<DWI>
6973 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6974 (sign_extend:<DWI>
6975 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
6976 (sign_extend:<DWI>
6977 (plus:SWI (match_dup 1) (match_dup 2)))))
6978 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6979 (plus:SWI (match_dup 1) (match_dup 2)))]
6980 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6981 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6982 [(set_attr "type" "alu")
6983 (set_attr "mode" "<MODE>")])
6984
6985 (define_insn "addv<mode>4_1"
6986 [(set (reg:CCO FLAGS_REG)
6987 (eq:CCO (plus:<DWI>
6988 (sign_extend:<DWI>
6989 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6990 (match_operand:<DWI> 3 "const_int_operand"))
6991 (sign_extend:<DWI>
6992 (plus:SWI
6993 (match_dup 1)
6994 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6995 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6996 (plus:SWI (match_dup 1) (match_dup 2)))]
6997 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6998 && CONST_INT_P (operands[2])
6999 && INTVAL (operands[2]) == INTVAL (operands[3])"
7000 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7001 [(set_attr "type" "alu")
7002 (set_attr "mode" "<MODE>")
7003 (set (attr "length_immediate")
7004 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7005 (const_string "1")
7006 (match_test "<MODE_SIZE> == 8")
7007 (const_string "4")]
7008 (const_string "<MODE_SIZE>")))])
7009
7010 ;; Quad word integer modes as mode attribute.
7011 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7012
7013 (define_insn_and_split "*addv<dwi>4_doubleword"
7014 [(set (reg:CCO FLAGS_REG)
7015 (eq:CCO
7016 (plus:<QPWI>
7017 (sign_extend:<QPWI>
7018 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7019 (sign_extend:<QPWI>
7020 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7021 (sign_extend:<QPWI>
7022 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7023 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7024 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7025 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7026 "#"
7027 "&& reload_completed"
7028 [(parallel [(set (reg:CCC FLAGS_REG)
7029 (compare:CCC
7030 (plus:DWIH (match_dup 1) (match_dup 2))
7031 (match_dup 1)))
7032 (set (match_dup 0)
7033 (plus:DWIH (match_dup 1) (match_dup 2)))])
7034 (parallel [(set (reg:CCO FLAGS_REG)
7035 (eq:CCO
7036 (plus:<DWI>
7037 (plus:<DWI>
7038 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7039 (sign_extend:<DWI> (match_dup 4)))
7040 (sign_extend:<DWI> (match_dup 5)))
7041 (sign_extend:<DWI>
7042 (plus:DWIH
7043 (plus:DWIH
7044 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7045 (match_dup 4))
7046 (match_dup 5)))))
7047 (set (match_dup 3)
7048 (plus:DWIH
7049 (plus:DWIH
7050 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7051 (match_dup 4))
7052 (match_dup 5)))])]
7053 {
7054 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7055 })
7056
7057 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7058 [(set (reg:CCO FLAGS_REG)
7059 (eq:CCO
7060 (plus:<QPWI>
7061 (sign_extend:<QPWI>
7062 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7063 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7064 (sign_extend:<QPWI>
7065 (plus:<DWI>
7066 (match_dup 1)
7067 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7068 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7069 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7070 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7071 && CONST_SCALAR_INT_P (operands[2])
7072 && rtx_equal_p (operands[2], operands[3])"
7073 "#"
7074 "&& reload_completed"
7075 [(parallel [(set (reg:CCC FLAGS_REG)
7076 (compare:CCC
7077 (plus:DWIH (match_dup 1) (match_dup 2))
7078 (match_dup 1)))
7079 (set (match_dup 0)
7080 (plus:DWIH (match_dup 1) (match_dup 2)))])
7081 (parallel [(set (reg:CCO FLAGS_REG)
7082 (eq:CCO
7083 (plus:<DWI>
7084 (plus:<DWI>
7085 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7086 (sign_extend:<DWI> (match_dup 4)))
7087 (match_dup 5))
7088 (sign_extend:<DWI>
7089 (plus:DWIH
7090 (plus:DWIH
7091 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7092 (match_dup 4))
7093 (match_dup 5)))))
7094 (set (match_dup 3)
7095 (plus:DWIH
7096 (plus:DWIH
7097 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7098 (match_dup 4))
7099 (match_dup 5)))])]
7100 {
7101 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7102 if (operands[2] == const0_rtx)
7103 {
7104 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7105 operands[5]));
7106 DONE;
7107 }
7108 })
7109
7110 (define_insn "*addv<mode>4_overflow_1"
7111 [(set (reg:CCO FLAGS_REG)
7112 (eq:CCO
7113 (plus:<DWI>
7114 (plus:<DWI>
7115 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7116 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7117 (sign_extend:<DWI>
7118 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7119 (sign_extend:<DWI>
7120 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7121 (sign_extend:<DWI>
7122 (plus:SWI
7123 (plus:SWI
7124 (match_operator:SWI 5 "ix86_carry_flag_operator"
7125 [(match_dup 3) (const_int 0)])
7126 (match_dup 1))
7127 (match_dup 2)))))
7128 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7129 (plus:SWI
7130 (plus:SWI
7131 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7132 (match_dup 1))
7133 (match_dup 2)))]
7134 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7135 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7136 [(set_attr "type" "alu")
7137 (set_attr "mode" "<MODE>")])
7138
7139 (define_insn "*addv<mode>4_overflow_2"
7140 [(set (reg:CCO FLAGS_REG)
7141 (eq:CCO
7142 (plus:<DWI>
7143 (plus:<DWI>
7144 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7145 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7146 (sign_extend:<DWI>
7147 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7148 (match_operand:<DWI> 6 "const_int_operand" "n"))
7149 (sign_extend:<DWI>
7150 (plus:SWI
7151 (plus:SWI
7152 (match_operator:SWI 5 "ix86_carry_flag_operator"
7153 [(match_dup 3) (const_int 0)])
7154 (match_dup 1))
7155 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7156 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7157 (plus:SWI
7158 (plus:SWI
7159 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7160 (match_dup 1))
7161 (match_dup 2)))]
7162 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7163 && CONST_INT_P (operands[2])
7164 && INTVAL (operands[2]) == INTVAL (operands[6])"
7165 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7166 [(set_attr "type" "alu")
7167 (set_attr "mode" "<MODE>")
7168 (set (attr "length_immediate")
7169 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7170 (const_string "1")
7171 (const_string "4")))])
7172
7173 (define_expand "uaddv<mode>4"
7174 [(parallel [(set (reg:CCC FLAGS_REG)
7175 (compare:CCC
7176 (plus:SWIDWI
7177 (match_operand:SWIDWI 1 "nonimmediate_operand")
7178 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7179 (match_dup 1)))
7180 (set (match_operand:SWIDWI 0 "register_operand")
7181 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7182 (set (pc) (if_then_else
7183 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7184 (label_ref (match_operand 3))
7185 (pc)))]
7186 ""
7187 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7188
7189 ;; The lea patterns for modes less than 32 bits need to be matched by
7190 ;; several insns converted to real lea by splitters.
7191
7192 (define_insn_and_split "*lea<mode>_general_1"
7193 [(set (match_operand:SWI12 0 "register_operand" "=r")
7194 (plus:SWI12
7195 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7196 (match_operand:SWI12 2 "register_operand" "r"))
7197 (match_operand:SWI12 3 "immediate_operand" "i")))]
7198 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7199 "#"
7200 "&& reload_completed"
7201 [(set (match_dup 0)
7202 (plus:SI
7203 (plus:SI (match_dup 1) (match_dup 2))
7204 (match_dup 3)))]
7205 {
7206 operands[0] = gen_lowpart (SImode, operands[0]);
7207 operands[1] = gen_lowpart (SImode, operands[1]);
7208 operands[2] = gen_lowpart (SImode, operands[2]);
7209 operands[3] = gen_lowpart (SImode, operands[3]);
7210 }
7211 [(set_attr "type" "lea")
7212 (set_attr "mode" "SI")])
7213
7214 (define_insn_and_split "*lea<mode>_general_2"
7215 [(set (match_operand:SWI12 0 "register_operand" "=r")
7216 (plus:SWI12
7217 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7218 (match_operand 2 "const248_operand" "n"))
7219 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7220 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7221 "#"
7222 "&& reload_completed"
7223 [(set (match_dup 0)
7224 (plus:SI
7225 (mult:SI (match_dup 1) (match_dup 2))
7226 (match_dup 3)))]
7227 {
7228 operands[0] = gen_lowpart (SImode, operands[0]);
7229 operands[1] = gen_lowpart (SImode, operands[1]);
7230 operands[3] = gen_lowpart (SImode, operands[3]);
7231 }
7232 [(set_attr "type" "lea")
7233 (set_attr "mode" "SI")])
7234
7235 (define_insn_and_split "*lea<mode>_general_2b"
7236 [(set (match_operand:SWI12 0 "register_operand" "=r")
7237 (plus:SWI12
7238 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7239 (match_operand 2 "const123_operand" "n"))
7240 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7241 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7242 "#"
7243 "&& reload_completed"
7244 [(set (match_dup 0)
7245 (plus:SI
7246 (ashift:SI (match_dup 1) (match_dup 2))
7247 (match_dup 3)))]
7248 {
7249 operands[0] = gen_lowpart (SImode, operands[0]);
7250 operands[1] = gen_lowpart (SImode, operands[1]);
7251 operands[3] = gen_lowpart (SImode, operands[3]);
7252 }
7253 [(set_attr "type" "lea")
7254 (set_attr "mode" "SI")])
7255
7256 (define_insn_and_split "*lea<mode>_general_3"
7257 [(set (match_operand:SWI12 0 "register_operand" "=r")
7258 (plus:SWI12
7259 (plus:SWI12
7260 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7261 (match_operand 2 "const248_operand" "n"))
7262 (match_operand:SWI12 3 "register_operand" "r"))
7263 (match_operand:SWI12 4 "immediate_operand" "i")))]
7264 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7265 "#"
7266 "&& reload_completed"
7267 [(set (match_dup 0)
7268 (plus:SI
7269 (plus:SI
7270 (mult:SI (match_dup 1) (match_dup 2))
7271 (match_dup 3))
7272 (match_dup 4)))]
7273 {
7274 operands[0] = gen_lowpart (SImode, operands[0]);
7275 operands[1] = gen_lowpart (SImode, operands[1]);
7276 operands[3] = gen_lowpart (SImode, operands[3]);
7277 operands[4] = gen_lowpart (SImode, operands[4]);
7278 }
7279 [(set_attr "type" "lea")
7280 (set_attr "mode" "SI")])
7281
7282 (define_insn_and_split "*lea<mode>_general_3b"
7283 [(set (match_operand:SWI12 0 "register_operand" "=r")
7284 (plus:SWI12
7285 (plus:SWI12
7286 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7287 (match_operand 2 "const123_operand" "n"))
7288 (match_operand:SWI12 3 "register_operand" "r"))
7289 (match_operand:SWI12 4 "immediate_operand" "i")))]
7290 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7291 "#"
7292 "&& reload_completed"
7293 [(set (match_dup 0)
7294 (plus:SI
7295 (plus:SI
7296 (ashift:SI (match_dup 1) (match_dup 2))
7297 (match_dup 3))
7298 (match_dup 4)))]
7299 {
7300 operands[0] = gen_lowpart (SImode, operands[0]);
7301 operands[1] = gen_lowpart (SImode, operands[1]);
7302 operands[3] = gen_lowpart (SImode, operands[3]);
7303 operands[4] = gen_lowpart (SImode, operands[4]);
7304 }
7305 [(set_attr "type" "lea")
7306 (set_attr "mode" "SI")])
7307
7308 (define_insn_and_split "*lea<mode>_general_4"
7309 [(set (match_operand:SWI12 0 "register_operand" "=r")
7310 (any_or:SWI12
7311 (ashift:SWI12
7312 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7313 (match_operand 2 "const_0_to_3_operand"))
7314 (match_operand 3 "const_int_operand")))]
7315 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7316 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7317 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7318 "#"
7319 "&& reload_completed"
7320 [(set (match_dup 0)
7321 (plus:SI
7322 (mult:SI (match_dup 1) (match_dup 2))
7323 (match_dup 3)))]
7324 {
7325 operands[0] = gen_lowpart (SImode, operands[0]);
7326 operands[1] = gen_lowpart (SImode, operands[1]);
7327 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7328 }
7329 [(set_attr "type" "lea")
7330 (set_attr "mode" "SI")])
7331
7332 (define_insn_and_split "*lea<mode>_general_4"
7333 [(set (match_operand:SWI48 0 "register_operand" "=r")
7334 (any_or:SWI48
7335 (ashift:SWI48
7336 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7337 (match_operand 2 "const_0_to_3_operand"))
7338 (match_operand 3 "const_int_operand")))]
7339 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7340 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7341 "#"
7342 "&& reload_completed"
7343 [(set (match_dup 0)
7344 (plus:SWI48
7345 (mult:SWI48 (match_dup 1) (match_dup 2))
7346 (match_dup 3)))]
7347 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7348 [(set_attr "type" "lea")
7349 (set_attr "mode" "<MODE>")])
7350 \f
7351 ;; Subtract instructions
7352
7353 (define_expand "sub<mode>3"
7354 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7355 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7356 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7357 ""
7358 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7359
7360 (define_insn_and_split "*sub<dwi>3_doubleword"
7361 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7362 (minus:<DWI>
7363 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7364 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7365 (clobber (reg:CC FLAGS_REG))]
7366 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7367 "#"
7368 "&& reload_completed"
7369 [(parallel [(set (reg:CC FLAGS_REG)
7370 (compare:CC (match_dup 1) (match_dup 2)))
7371 (set (match_dup 0)
7372 (minus:DWIH (match_dup 1) (match_dup 2)))])
7373 (parallel [(set (match_dup 3)
7374 (minus:DWIH
7375 (minus:DWIH
7376 (match_dup 4)
7377 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7378 (match_dup 5)))
7379 (clobber (reg:CC FLAGS_REG))])]
7380 {
7381 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7382 if (operands[2] == const0_rtx)
7383 {
7384 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7385 DONE;
7386 }
7387 })
7388
7389 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7390 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7391 (minus:<DWI>
7392 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7393 (zero_extend:<DWI>
7394 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7395 (clobber (reg:CC FLAGS_REG))]
7396 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7397 "#"
7398 "&& reload_completed"
7399 [(parallel [(set (reg:CC FLAGS_REG)
7400 (compare:CC (match_dup 1) (match_dup 2)))
7401 (set (match_dup 0)
7402 (minus:DWIH (match_dup 1) (match_dup 2)))])
7403 (parallel [(set (match_dup 3)
7404 (minus:DWIH
7405 (minus:DWIH
7406 (match_dup 4)
7407 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7408 (const_int 0)))
7409 (clobber (reg:CC FLAGS_REG))])]
7410 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7411
7412 (define_insn "*sub<mode>_1"
7413 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7414 (minus:SWI
7415 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7416 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7417 (clobber (reg:CC FLAGS_REG))]
7418 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7419 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7420 [(set_attr "type" "alu")
7421 (set_attr "mode" "<MODE>")])
7422
7423 (define_insn "*subsi_1_zext"
7424 [(set (match_operand:DI 0 "register_operand" "=r")
7425 (zero_extend:DI
7426 (minus:SI (match_operand:SI 1 "register_operand" "0")
7427 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7428 (clobber (reg:CC FLAGS_REG))]
7429 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7430 "sub{l}\t{%2, %k0|%k0, %2}"
7431 [(set_attr "type" "alu")
7432 (set_attr "mode" "SI")])
7433
7434 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7435 (define_insn_and_split "*sub<mode>_1_slp"
7436 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7437 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7438 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7439 (clobber (reg:CC FLAGS_REG))]
7440 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7441 "@
7442 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7443 #"
7444 "&& reload_completed"
7445 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7446 (parallel
7447 [(set (strict_low_part (match_dup 0))
7448 (minus:SWI12 (match_dup 0) (match_dup 2)))
7449 (clobber (reg:CC FLAGS_REG))])]
7450 ""
7451 [(set_attr "type" "alu")
7452 (set_attr "mode" "<MODE>")])
7453
7454 (define_insn "*sub<mode>_2"
7455 [(set (reg FLAGS_REG)
7456 (compare
7457 (minus:SWI
7458 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7459 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7460 (const_int 0)))
7461 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7462 (minus:SWI (match_dup 1) (match_dup 2)))]
7463 "ix86_match_ccmode (insn, CCGOCmode)
7464 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7465 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7466 [(set_attr "type" "alu")
7467 (set_attr "mode" "<MODE>")])
7468
7469 (define_insn "*subsi_2_zext"
7470 [(set (reg FLAGS_REG)
7471 (compare
7472 (minus:SI (match_operand:SI 1 "register_operand" "0")
7473 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7474 (const_int 0)))
7475 (set (match_operand:DI 0 "register_operand" "=r")
7476 (zero_extend:DI
7477 (minus:SI (match_dup 1)
7478 (match_dup 2))))]
7479 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7480 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7481 "sub{l}\t{%2, %k0|%k0, %2}"
7482 [(set_attr "type" "alu")
7483 (set_attr "mode" "SI")])
7484
7485 (define_insn "*subqi_ext<mode>_0"
7486 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
7487 (minus:QI
7488 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")
7489 (subreg:QI
7490 (match_operator:SWI248 3 "extract_operator"
7491 [(match_operand 2 "int248_register_operand" "Q,Q")
7492 (const_int 8)
7493 (const_int 8)]) 0)))
7494 (clobber (reg:CC FLAGS_REG))]
7495 ""
7496 "sub{b}\t{%h2, %0|%0, %h2}"
7497 [(set_attr "isa" "*,nox64")
7498 (set_attr "type" "alu")
7499 (set_attr "mode" "QI")])
7500
7501 (define_insn "*subqi_ext<mode>_2"
7502 [(set (zero_extract:SWI248
7503 (match_operand 0 "int248_register_operand" "+Q")
7504 (const_int 8)
7505 (const_int 8))
7506 (subreg:SWI248
7507 (minus:QI
7508 (subreg:QI
7509 (match_operator:SWI248 3 "extract_operator"
7510 [(match_operand 1 "int248_register_operand" "0")
7511 (const_int 8)
7512 (const_int 8)]) 0)
7513 (subreg:QI
7514 (match_operator:SWI248 4 "extract_operator"
7515 [(match_operand 2 "int248_register_operand" "Q")
7516 (const_int 8)
7517 (const_int 8)]) 0)) 0))
7518 (clobber (reg:CC FLAGS_REG))]
7519 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7520 rtx_equal_p (operands[0], operands[1])"
7521 "sub{b}\t{%h2, %h0|%h0, %h2}"
7522 [(set_attr "type" "alu")
7523 (set_attr "mode" "QI")])
7524
7525 ;; Subtract with jump on overflow.
7526 (define_expand "subv<mode>4"
7527 [(parallel [(set (reg:CCO FLAGS_REG)
7528 (eq:CCO
7529 (minus:<DPWI>
7530 (sign_extend:<DPWI>
7531 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7532 (match_dup 4))
7533 (sign_extend:<DPWI>
7534 (minus:SWIDWI (match_dup 1)
7535 (match_operand:SWIDWI 2
7536 "<general_hilo_operand>")))))
7537 (set (match_operand:SWIDWI 0 "register_operand")
7538 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7539 (set (pc) (if_then_else
7540 (eq (reg:CCO FLAGS_REG) (const_int 0))
7541 (label_ref (match_operand 3))
7542 (pc)))]
7543 ""
7544 {
7545 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7546 if (CONST_SCALAR_INT_P (operands[2]))
7547 operands[4] = operands[2];
7548 else
7549 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7550 })
7551
7552 (define_insn "*subv<mode>4"
7553 [(set (reg:CCO FLAGS_REG)
7554 (eq:CCO (minus:<DWI>
7555 (sign_extend:<DWI>
7556 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7557 (sign_extend:<DWI>
7558 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7559 (sign_extend:<DWI>
7560 (minus:SWI (match_dup 1) (match_dup 2)))))
7561 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7562 (minus:SWI (match_dup 1) (match_dup 2)))]
7563 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7564 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7565 [(set_attr "type" "alu")
7566 (set_attr "mode" "<MODE>")])
7567
7568 (define_insn "subv<mode>4_1"
7569 [(set (reg:CCO FLAGS_REG)
7570 (eq:CCO (minus:<DWI>
7571 (sign_extend:<DWI>
7572 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7573 (match_operand:<DWI> 3 "const_int_operand"))
7574 (sign_extend:<DWI>
7575 (minus:SWI
7576 (match_dup 1)
7577 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7578 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7579 (minus:SWI (match_dup 1) (match_dup 2)))]
7580 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7581 && CONST_INT_P (operands[2])
7582 && INTVAL (operands[2]) == INTVAL (operands[3])"
7583 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7584 [(set_attr "type" "alu")
7585 (set_attr "mode" "<MODE>")
7586 (set (attr "length_immediate")
7587 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7588 (const_string "1")
7589 (match_test "<MODE_SIZE> == 8")
7590 (const_string "4")]
7591 (const_string "<MODE_SIZE>")))])
7592
7593 (define_insn_and_split "*subv<dwi>4_doubleword"
7594 [(set (reg:CCO FLAGS_REG)
7595 (eq:CCO
7596 (minus:<QPWI>
7597 (sign_extend:<QPWI>
7598 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7599 (sign_extend:<QPWI>
7600 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7601 (sign_extend:<QPWI>
7602 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7603 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7604 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7605 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7606 "#"
7607 "&& reload_completed"
7608 [(parallel [(set (reg:CC FLAGS_REG)
7609 (compare:CC (match_dup 1) (match_dup 2)))
7610 (set (match_dup 0)
7611 (minus:DWIH (match_dup 1) (match_dup 2)))])
7612 (parallel [(set (reg:CCO FLAGS_REG)
7613 (eq:CCO
7614 (minus:<DWI>
7615 (minus:<DWI>
7616 (sign_extend:<DWI> (match_dup 4))
7617 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7618 (sign_extend:<DWI> (match_dup 5)))
7619 (sign_extend:<DWI>
7620 (minus:DWIH
7621 (minus:DWIH
7622 (match_dup 4)
7623 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7624 (match_dup 5)))))
7625 (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 {
7632 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7633 })
7634
7635 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7636 [(set (reg:CCO FLAGS_REG)
7637 (eq:CCO
7638 (minus:<QPWI>
7639 (sign_extend:<QPWI>
7640 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7641 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7642 (sign_extend:<QPWI>
7643 (minus:<DWI>
7644 (match_dup 1)
7645 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7646 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7647 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7648 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7649 && CONST_SCALAR_INT_P (operands[2])
7650 && rtx_equal_p (operands[2], operands[3])"
7651 "#"
7652 "&& reload_completed"
7653 [(parallel [(set (reg:CC FLAGS_REG)
7654 (compare:CC (match_dup 1) (match_dup 2)))
7655 (set (match_dup 0)
7656 (minus:DWIH (match_dup 1) (match_dup 2)))])
7657 (parallel [(set (reg:CCO FLAGS_REG)
7658 (eq:CCO
7659 (minus:<DWI>
7660 (minus:<DWI>
7661 (sign_extend:<DWI> (match_dup 4))
7662 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7663 (match_dup 5))
7664 (sign_extend:<DWI>
7665 (minus:DWIH
7666 (minus:DWIH
7667 (match_dup 4)
7668 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7669 (match_dup 5)))))
7670 (set (match_dup 3)
7671 (minus:DWIH
7672 (minus:DWIH
7673 (match_dup 4)
7674 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7675 (match_dup 5)))])]
7676 {
7677 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7678 if (operands[2] == const0_rtx)
7679 {
7680 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7681 operands[5]));
7682 DONE;
7683 }
7684 })
7685
7686 (define_insn "*subv<mode>4_overflow_1"
7687 [(set (reg:CCO FLAGS_REG)
7688 (eq:CCO
7689 (minus:<DWI>
7690 (minus:<DWI>
7691 (sign_extend:<DWI>
7692 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7693 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7694 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7695 (sign_extend:<DWI>
7696 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7697 (sign_extend:<DWI>
7698 (minus:SWI
7699 (minus:SWI
7700 (match_dup 1)
7701 (match_operator:SWI 5 "ix86_carry_flag_operator"
7702 [(match_dup 3) (const_int 0)]))
7703 (match_dup 2)))))
7704 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7705 (minus:SWI
7706 (minus:SWI
7707 (match_dup 1)
7708 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7709 (match_dup 2)))]
7710 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7711 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7712 [(set_attr "type" "alu")
7713 (set_attr "mode" "<MODE>")])
7714
7715 (define_insn "*subv<mode>4_overflow_2"
7716 [(set (reg:CCO FLAGS_REG)
7717 (eq:CCO
7718 (minus:<DWI>
7719 (minus:<DWI>
7720 (sign_extend:<DWI>
7721 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7722 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7723 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7724 (match_operand:<DWI> 6 "const_int_operand" "n"))
7725 (sign_extend:<DWI>
7726 (minus:SWI
7727 (minus:SWI
7728 (match_dup 1)
7729 (match_operator:SWI 5 "ix86_carry_flag_operator"
7730 [(match_dup 3) (const_int 0)]))
7731 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7732 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7733 (minus:SWI
7734 (minus:SWI
7735 (match_dup 1)
7736 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7737 (match_dup 2)))]
7738 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7739 && CONST_INT_P (operands[2])
7740 && INTVAL (operands[2]) == INTVAL (operands[6])"
7741 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7742 [(set_attr "type" "alu")
7743 (set_attr "mode" "<MODE>")
7744 (set (attr "length_immediate")
7745 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7746 (const_string "1")
7747 (const_string "4")))])
7748
7749 (define_expand "usubv<mode>4"
7750 [(parallel [(set (reg:CC FLAGS_REG)
7751 (compare:CC
7752 (match_operand:SWI 1 "nonimmediate_operand")
7753 (match_operand:SWI 2 "<general_operand>")))
7754 (set (match_operand:SWI 0 "register_operand")
7755 (minus:SWI (match_dup 1) (match_dup 2)))])
7756 (set (pc) (if_then_else
7757 (ltu (reg:CC FLAGS_REG) (const_int 0))
7758 (label_ref (match_operand 3))
7759 (pc)))]
7760 ""
7761 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
7762
7763 (define_insn "*sub<mode>_3"
7764 [(set (reg FLAGS_REG)
7765 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7766 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7767 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7768 (minus:SWI (match_dup 1) (match_dup 2)))]
7769 "ix86_match_ccmode (insn, CCmode)
7770 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7771 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7772 [(set_attr "type" "alu")
7773 (set_attr "mode" "<MODE>")])
7774
7775 (define_peephole2
7776 [(parallel
7777 [(set (reg:CC FLAGS_REG)
7778 (compare:CC (match_operand:SWI 0 "general_reg_operand")
7779 (match_operand:SWI 1 "general_gr_operand")))
7780 (set (match_dup 0)
7781 (minus:SWI (match_dup 0) (match_dup 1)))])]
7782 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
7783 [(set (reg:CC FLAGS_REG)
7784 (compare:CC (match_dup 0) (match_dup 1)))])
7785
7786 (define_peephole2
7787 [(set (match_operand:SWI 0 "general_reg_operand")
7788 (match_operand:SWI 1 "memory_operand"))
7789 (parallel [(set (reg:CC FLAGS_REG)
7790 (compare:CC (match_dup 0)
7791 (match_operand:SWI 2 "memory_operand")))
7792 (set (match_dup 0)
7793 (minus:SWI (match_dup 0) (match_dup 2)))])
7794 (set (match_dup 1) (match_dup 0))]
7795 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7796 && peep2_reg_dead_p (3, operands[0])
7797 && !reg_overlap_mentioned_p (operands[0], operands[1])
7798 && !reg_overlap_mentioned_p (operands[0], operands[2])"
7799 [(set (match_dup 0) (match_dup 2))
7800 (parallel [(set (reg:CC FLAGS_REG)
7801 (compare:CC (match_dup 1) (match_dup 0)))
7802 (set (match_dup 1)
7803 (minus:SWI (match_dup 1) (match_dup 0)))])])
7804
7805 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
7806 ;; subl $1, %eax; jnc .Lxx;
7807 (define_peephole2
7808 [(parallel
7809 [(set (match_operand:SWI 0 "general_reg_operand")
7810 (plus:SWI (match_dup 0) (const_int -1)))
7811 (clobber (reg FLAGS_REG))])
7812 (set (reg:CCZ FLAGS_REG)
7813 (compare:CCZ (match_dup 0) (const_int -1)))
7814 (set (pc)
7815 (if_then_else (match_operator 1 "bt_comparison_operator"
7816 [(reg:CCZ FLAGS_REG) (const_int 0)])
7817 (match_operand 2)
7818 (pc)))]
7819 "peep2_regno_dead_p (3, FLAGS_REG)"
7820 [(parallel
7821 [(set (reg:CC FLAGS_REG)
7822 (compare:CC (match_dup 0) (const_int 1)))
7823 (set (match_dup 0)
7824 (minus:SWI (match_dup 0) (const_int 1)))])
7825 (set (pc)
7826 (if_then_else (match_dup 3)
7827 (match_dup 2)
7828 (pc)))]
7829 {
7830 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
7831 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7832 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7833 })
7834
7835 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
7836 (define_insn_and_split "*dec_cmov<mode>"
7837 [(set (match_operand:SWI248 0 "register_operand" "=r")
7838 (if_then_else:SWI248
7839 (match_operator 1 "bt_comparison_operator"
7840 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
7841 (plus:SWI248 (match_dup 2) (const_int -1))
7842 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
7843 (clobber (reg:CC FLAGS_REG))]
7844 "TARGET_CMOVE"
7845 "#"
7846 "&& reload_completed"
7847 [(parallel [(set (reg:CC FLAGS_REG)
7848 (compare:CC (match_dup 2) (const_int 1)))
7849 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
7850 (set (match_dup 0)
7851 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
7852 {
7853 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
7854 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7855 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7856 })
7857
7858 (define_insn "*subsi_3_zext"
7859 [(set (reg FLAGS_REG)
7860 (compare (match_operand:SI 1 "register_operand" "0")
7861 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
7862 (set (match_operand:DI 0 "register_operand" "=r")
7863 (zero_extend:DI
7864 (minus:SI (match_dup 1)
7865 (match_dup 2))))]
7866 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7867 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7868 "sub{l}\t{%2, %1|%1, %2}"
7869 [(set_attr "type" "alu")
7870 (set_attr "mode" "SI")])
7871 \f
7872 ;; Add with carry and subtract with borrow
7873
7874 (define_insn "@add<mode>3_carry"
7875 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7876 (plus:SWI
7877 (plus:SWI
7878 (match_operator:SWI 4 "ix86_carry_flag_operator"
7879 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7880 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7881 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7882 (clobber (reg:CC FLAGS_REG))]
7883 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7884 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7885 [(set_attr "type" "alu")
7886 (set_attr "use_carry" "1")
7887 (set_attr "pent_pair" "pu")
7888 (set_attr "mode" "<MODE>")])
7889
7890 (define_peephole2
7891 [(set (match_operand:SWI 0 "general_reg_operand")
7892 (match_operand:SWI 1 "memory_operand"))
7893 (parallel [(set (match_dup 0)
7894 (plus:SWI
7895 (plus:SWI
7896 (match_operator:SWI 4 "ix86_carry_flag_operator"
7897 [(match_operand 3 "flags_reg_operand")
7898 (const_int 0)])
7899 (match_dup 0))
7900 (match_operand:SWI 2 "memory_operand")))
7901 (clobber (reg:CC FLAGS_REG))])
7902 (set (match_dup 1) (match_dup 0))]
7903 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7904 && peep2_reg_dead_p (3, operands[0])
7905 && !reg_overlap_mentioned_p (operands[0], operands[1])
7906 && !reg_overlap_mentioned_p (operands[0], operands[2])"
7907 [(set (match_dup 0) (match_dup 2))
7908 (parallel [(set (match_dup 1)
7909 (plus:SWI (plus:SWI (match_op_dup 4
7910 [(match_dup 3) (const_int 0)])
7911 (match_dup 1))
7912 (match_dup 0)))
7913 (clobber (reg:CC FLAGS_REG))])])
7914
7915 (define_peephole2
7916 [(set (match_operand:SWI 0 "general_reg_operand")
7917 (match_operand:SWI 1 "memory_operand"))
7918 (parallel [(set (match_dup 0)
7919 (plus:SWI
7920 (plus:SWI
7921 (match_operator:SWI 4 "ix86_carry_flag_operator"
7922 [(match_operand 3 "flags_reg_operand")
7923 (const_int 0)])
7924 (match_dup 0))
7925 (match_operand:SWI 2 "memory_operand")))
7926 (clobber (reg:CC FLAGS_REG))])
7927 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
7928 (set (match_dup 1) (match_dup 5))]
7929 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7930 && peep2_reg_dead_p (3, operands[0])
7931 && peep2_reg_dead_p (4, operands[5])
7932 && !reg_overlap_mentioned_p (operands[0], operands[1])
7933 && !reg_overlap_mentioned_p (operands[0], operands[2])
7934 && !reg_overlap_mentioned_p (operands[5], operands[1])"
7935 [(set (match_dup 0) (match_dup 2))
7936 (parallel [(set (match_dup 1)
7937 (plus:SWI (plus:SWI (match_op_dup 4
7938 [(match_dup 3) (const_int 0)])
7939 (match_dup 1))
7940 (match_dup 0)))
7941 (clobber (reg:CC FLAGS_REG))])])
7942
7943 (define_insn "*add<mode>3_carry_0"
7944 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7945 (plus:SWI
7946 (match_operator:SWI 2 "ix86_carry_flag_operator"
7947 [(reg FLAGS_REG) (const_int 0)])
7948 (match_operand:SWI 1 "nonimmediate_operand" "0")))
7949 (clobber (reg:CC FLAGS_REG))]
7950 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
7951 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
7952 [(set_attr "type" "alu")
7953 (set_attr "use_carry" "1")
7954 (set_attr "pent_pair" "pu")
7955 (set_attr "mode" "<MODE>")])
7956
7957 (define_insn "*add<mode>3_carry_0r"
7958 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7959 (plus:SWI
7960 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
7961 [(reg FLAGS_REG) (const_int 0)])
7962 (match_operand:SWI 1 "nonimmediate_operand" "0")))
7963 (clobber (reg:CC FLAGS_REG))]
7964 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
7965 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
7966 [(set_attr "type" "alu")
7967 (set_attr "use_carry" "1")
7968 (set_attr "pent_pair" "pu")
7969 (set_attr "mode" "<MODE>")])
7970
7971 (define_insn "*addsi3_carry_zext"
7972 [(set (match_operand:DI 0 "register_operand" "=r")
7973 (zero_extend:DI
7974 (plus:SI
7975 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
7976 [(reg FLAGS_REG) (const_int 0)])
7977 (match_operand:SI 1 "register_operand" "%0"))
7978 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7979 (clobber (reg:CC FLAGS_REG))]
7980 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7981 "adc{l}\t{%2, %k0|%k0, %2}"
7982 [(set_attr "type" "alu")
7983 (set_attr "use_carry" "1")
7984 (set_attr "pent_pair" "pu")
7985 (set_attr "mode" "SI")])
7986
7987 (define_insn "*addsi3_carry_zext_0"
7988 [(set (match_operand:DI 0 "register_operand" "=r")
7989 (zero_extend:DI
7990 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
7991 [(reg FLAGS_REG) (const_int 0)])
7992 (match_operand:SI 1 "register_operand" "0"))))
7993 (clobber (reg:CC FLAGS_REG))]
7994 "TARGET_64BIT"
7995 "adc{l}\t{$0, %k0|%k0, 0}"
7996 [(set_attr "type" "alu")
7997 (set_attr "use_carry" "1")
7998 (set_attr "pent_pair" "pu")
7999 (set_attr "mode" "SI")])
8000
8001 (define_insn "*addsi3_carry_zext_0r"
8002 [(set (match_operand:DI 0 "register_operand" "=r")
8003 (zero_extend:DI
8004 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8005 [(reg FLAGS_REG) (const_int 0)])
8006 (match_operand:SI 1 "register_operand" "0"))))
8007 (clobber (reg:CC FLAGS_REG))]
8008 "TARGET_64BIT"
8009 "sbb{l}\t{$-1, %k0|%k0, -1}"
8010 [(set_attr "type" "alu")
8011 (set_attr "use_carry" "1")
8012 (set_attr "pent_pair" "pu")
8013 (set_attr "mode" "SI")])
8014
8015 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8016
8017 (define_insn "addcarry<mode>"
8018 [(set (reg:CCC FLAGS_REG)
8019 (compare:CCC
8020 (zero_extend:<DWI>
8021 (plus:SWI48
8022 (plus:SWI48
8023 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8024 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8025 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8026 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8027 (plus:<DWI>
8028 (zero_extend:<DWI> (match_dup 2))
8029 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8030 [(match_dup 3) (const_int 0)]))))
8031 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8032 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8033 [(match_dup 3) (const_int 0)])
8034 (match_dup 1))
8035 (match_dup 2)))]
8036 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8037 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8038 [(set_attr "type" "alu")
8039 (set_attr "use_carry" "1")
8040 (set_attr "pent_pair" "pu")
8041 (set_attr "mode" "<MODE>")])
8042
8043 (define_peephole2
8044 [(parallel [(set (reg:CCC FLAGS_REG)
8045 (compare:CCC
8046 (zero_extend:<DWI>
8047 (plus:SWI48
8048 (plus:SWI48
8049 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8050 [(match_operand 2 "flags_reg_operand")
8051 (const_int 0)])
8052 (match_operand:SWI48 0 "general_reg_operand"))
8053 (match_operand:SWI48 1 "memory_operand")))
8054 (plus:<DWI>
8055 (zero_extend:<DWI> (match_dup 1))
8056 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8057 [(match_dup 2) (const_int 0)]))))
8058 (set (match_dup 0)
8059 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8060 [(match_dup 2) (const_int 0)])
8061 (match_dup 0))
8062 (match_dup 1)))])
8063 (set (match_dup 1) (match_dup 0))]
8064 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8065 && peep2_reg_dead_p (2, operands[0])
8066 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8067 [(parallel [(set (reg:CCC FLAGS_REG)
8068 (compare:CCC
8069 (zero_extend:<DWI>
8070 (plus:SWI48
8071 (plus:SWI48
8072 (match_op_dup 4
8073 [(match_dup 2) (const_int 0)])
8074 (match_dup 1))
8075 (match_dup 0)))
8076 (plus:<DWI>
8077 (zero_extend:<DWI> (match_dup 0))
8078 (match_op_dup 3
8079 [(match_dup 2) (const_int 0)]))))
8080 (set (match_dup 1)
8081 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8082 [(match_dup 2) (const_int 0)])
8083 (match_dup 1))
8084 (match_dup 0)))])])
8085
8086 (define_peephole2
8087 [(set (match_operand:SWI48 0 "general_reg_operand")
8088 (match_operand:SWI48 1 "memory_operand"))
8089 (parallel [(set (reg:CCC FLAGS_REG)
8090 (compare:CCC
8091 (zero_extend:<DWI>
8092 (plus:SWI48
8093 (plus:SWI48
8094 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8095 [(match_operand 3 "flags_reg_operand")
8096 (const_int 0)])
8097 (match_dup 0))
8098 (match_operand:SWI48 2 "memory_operand")))
8099 (plus:<DWI>
8100 (zero_extend:<DWI> (match_dup 2))
8101 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8102 [(match_dup 3) (const_int 0)]))))
8103 (set (match_dup 0)
8104 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8105 [(match_dup 3) (const_int 0)])
8106 (match_dup 0))
8107 (match_dup 2)))])
8108 (set (match_dup 1) (match_dup 0))]
8109 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8110 && peep2_reg_dead_p (3, operands[0])
8111 && !reg_overlap_mentioned_p (operands[0], operands[1])
8112 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8113 [(set (match_dup 0) (match_dup 2))
8114 (parallel [(set (reg:CCC FLAGS_REG)
8115 (compare:CCC
8116 (zero_extend:<DWI>
8117 (plus:SWI48
8118 (plus:SWI48
8119 (match_op_dup 5
8120 [(match_dup 3) (const_int 0)])
8121 (match_dup 1))
8122 (match_dup 0)))
8123 (plus:<DWI>
8124 (zero_extend:<DWI> (match_dup 0))
8125 (match_op_dup 4
8126 [(match_dup 3) (const_int 0)]))))
8127 (set (match_dup 1)
8128 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8129 [(match_dup 3) (const_int 0)])
8130 (match_dup 1))
8131 (match_dup 0)))])])
8132
8133 (define_peephole2
8134 [(parallel [(set (reg:CCC FLAGS_REG)
8135 (compare:CCC
8136 (zero_extend:<DWI>
8137 (plus:SWI48
8138 (plus:SWI48
8139 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8140 [(match_operand 2 "flags_reg_operand")
8141 (const_int 0)])
8142 (match_operand:SWI48 0 "general_reg_operand"))
8143 (match_operand:SWI48 1 "memory_operand")))
8144 (plus:<DWI>
8145 (zero_extend:<DWI> (match_dup 1))
8146 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8147 [(match_dup 2) (const_int 0)]))))
8148 (set (match_dup 0)
8149 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8150 [(match_dup 2) (const_int 0)])
8151 (match_dup 0))
8152 (match_dup 1)))])
8153 (set (match_operand:QI 5 "general_reg_operand")
8154 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8155 (set (match_operand:SWI48 6 "general_reg_operand")
8156 (zero_extend:SWI48 (match_dup 5)))
8157 (set (match_dup 1) (match_dup 0))]
8158 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8159 && peep2_reg_dead_p (4, operands[0])
8160 && !reg_overlap_mentioned_p (operands[0], operands[1])
8161 && !reg_overlap_mentioned_p (operands[0], operands[5])
8162 && !reg_overlap_mentioned_p (operands[5], operands[1])
8163 && !reg_overlap_mentioned_p (operands[0], operands[6])
8164 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8165 [(parallel [(set (reg:CCC FLAGS_REG)
8166 (compare:CCC
8167 (zero_extend:<DWI>
8168 (plus:SWI48
8169 (plus:SWI48
8170 (match_op_dup 4
8171 [(match_dup 2) (const_int 0)])
8172 (match_dup 1))
8173 (match_dup 0)))
8174 (plus:<DWI>
8175 (zero_extend:<DWI> (match_dup 0))
8176 (match_op_dup 3
8177 [(match_dup 2) (const_int 0)]))))
8178 (set (match_dup 1)
8179 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8180 [(match_dup 2) (const_int 0)])
8181 (match_dup 1))
8182 (match_dup 0)))])
8183 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8184 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8185
8186 (define_expand "addcarry<mode>_0"
8187 [(parallel
8188 [(set (reg:CCC FLAGS_REG)
8189 (compare:CCC
8190 (plus:SWI48
8191 (match_operand:SWI48 1 "nonimmediate_operand")
8192 (match_operand:SWI48 2 "x86_64_general_operand"))
8193 (match_dup 1)))
8194 (set (match_operand:SWI48 0 "nonimmediate_operand")
8195 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8196 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8197
8198 (define_insn "*addcarry<mode>_1"
8199 [(set (reg:CCC FLAGS_REG)
8200 (compare:CCC
8201 (zero_extend:<DWI>
8202 (plus:SWI48
8203 (plus:SWI48
8204 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8205 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8206 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8207 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8208 (plus:<DWI>
8209 (match_operand:<DWI> 6 "const_scalar_int_operand")
8210 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8211 [(match_dup 3) (const_int 0)]))))
8212 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8213 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8214 [(match_dup 3) (const_int 0)])
8215 (match_dup 1))
8216 (match_dup 2)))]
8217 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8218 && CONST_INT_P (operands[2])
8219 /* Check that operands[6] is operands[2] zero extended from
8220 <MODE>mode to <DWI>mode. */
8221 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8222 ? (CONST_INT_P (operands[6])
8223 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8224 & GET_MODE_MASK (<MODE>mode)))
8225 : (CONST_WIDE_INT_P (operands[6])
8226 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8227 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8228 == UINTVAL (operands[2]))
8229 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8230 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8231 [(set_attr "type" "alu")
8232 (set_attr "use_carry" "1")
8233 (set_attr "pent_pair" "pu")
8234 (set_attr "mode" "<MODE>")
8235 (set (attr "length_immediate")
8236 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8237 (const_string "1")
8238 (const_string "4")))])
8239
8240 (define_insn "@sub<mode>3_carry"
8241 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8242 (minus:SWI
8243 (minus:SWI
8244 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8245 (match_operator:SWI 4 "ix86_carry_flag_operator"
8246 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8247 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8248 (clobber (reg:CC FLAGS_REG))]
8249 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8250 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8251 [(set_attr "type" "alu")
8252 (set_attr "use_carry" "1")
8253 (set_attr "pent_pair" "pu")
8254 (set_attr "mode" "<MODE>")])
8255
8256 (define_peephole2
8257 [(set (match_operand:SWI 0 "general_reg_operand")
8258 (match_operand:SWI 1 "memory_operand"))
8259 (parallel [(set (match_dup 0)
8260 (minus:SWI
8261 (minus:SWI
8262 (match_dup 0)
8263 (match_operator:SWI 4 "ix86_carry_flag_operator"
8264 [(match_operand 3 "flags_reg_operand")
8265 (const_int 0)]))
8266 (match_operand:SWI 2 "memory_operand")))
8267 (clobber (reg:CC FLAGS_REG))])
8268 (set (match_dup 1) (match_dup 0))]
8269 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8270 && peep2_reg_dead_p (3, operands[0])
8271 && !reg_overlap_mentioned_p (operands[0], operands[1])
8272 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8273 [(set (match_dup 0) (match_dup 2))
8274 (parallel [(set (match_dup 1)
8275 (minus:SWI (minus:SWI (match_dup 1)
8276 (match_op_dup 4
8277 [(match_dup 3) (const_int 0)]))
8278 (match_dup 0)))
8279 (clobber (reg:CC FLAGS_REG))])])
8280
8281 (define_peephole2
8282 [(set (match_operand:SWI 0 "general_reg_operand")
8283 (match_operand:SWI 1 "memory_operand"))
8284 (parallel [(set (match_dup 0)
8285 (minus:SWI
8286 (minus:SWI
8287 (match_dup 0)
8288 (match_operator:SWI 4 "ix86_carry_flag_operator"
8289 [(match_operand 3 "flags_reg_operand")
8290 (const_int 0)]))
8291 (match_operand:SWI 2 "memory_operand")))
8292 (clobber (reg:CC FLAGS_REG))])
8293 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8294 (set (match_dup 1) (match_dup 5))]
8295 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8296 && peep2_reg_dead_p (3, operands[0])
8297 && peep2_reg_dead_p (4, operands[5])
8298 && !reg_overlap_mentioned_p (operands[0], operands[1])
8299 && !reg_overlap_mentioned_p (operands[0], operands[2])
8300 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8301 [(set (match_dup 0) (match_dup 2))
8302 (parallel [(set (match_dup 1)
8303 (minus:SWI (minus:SWI (match_dup 1)
8304 (match_op_dup 4
8305 [(match_dup 3) (const_int 0)]))
8306 (match_dup 0)))
8307 (clobber (reg:CC FLAGS_REG))])])
8308
8309 (define_insn "*sub<mode>3_carry_0"
8310 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8311 (minus:SWI
8312 (match_operand:SWI 1 "nonimmediate_operand" "0")
8313 (match_operator:SWI 2 "ix86_carry_flag_operator"
8314 [(reg FLAGS_REG) (const_int 0)])))
8315 (clobber (reg:CC FLAGS_REG))]
8316 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8317 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8318 [(set_attr "type" "alu")
8319 (set_attr "use_carry" "1")
8320 (set_attr "pent_pair" "pu")
8321 (set_attr "mode" "<MODE>")])
8322
8323 (define_insn "*sub<mode>3_carry_0r"
8324 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8325 (minus:SWI
8326 (match_operand:SWI 1 "nonimmediate_operand" "0")
8327 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8328 [(reg FLAGS_REG) (const_int 0)])))
8329 (clobber (reg:CC FLAGS_REG))]
8330 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8331 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8332 [(set_attr "type" "alu")
8333 (set_attr "use_carry" "1")
8334 (set_attr "pent_pair" "pu")
8335 (set_attr "mode" "<MODE>")])
8336
8337 (define_insn "*subsi3_carry_zext"
8338 [(set (match_operand:DI 0 "register_operand" "=r")
8339 (zero_extend:DI
8340 (minus:SI
8341 (minus:SI
8342 (match_operand:SI 1 "register_operand" "0")
8343 (match_operator:SI 3 "ix86_carry_flag_operator"
8344 [(reg FLAGS_REG) (const_int 0)]))
8345 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8346 (clobber (reg:CC FLAGS_REG))]
8347 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8348 "sbb{l}\t{%2, %k0|%k0, %2}"
8349 [(set_attr "type" "alu")
8350 (set_attr "use_carry" "1")
8351 (set_attr "pent_pair" "pu")
8352 (set_attr "mode" "SI")])
8353
8354 (define_insn "*subsi3_carry_zext_0"
8355 [(set (match_operand:DI 0 "register_operand" "=r")
8356 (zero_extend:DI
8357 (minus:SI
8358 (match_operand:SI 1 "register_operand" "0")
8359 (match_operator:SI 2 "ix86_carry_flag_operator"
8360 [(reg FLAGS_REG) (const_int 0)]))))
8361 (clobber (reg:CC FLAGS_REG))]
8362 "TARGET_64BIT"
8363 "sbb{l}\t{$0, %k0|%k0, 0}"
8364 [(set_attr "type" "alu")
8365 (set_attr "use_carry" "1")
8366 (set_attr "pent_pair" "pu")
8367 (set_attr "mode" "SI")])
8368
8369 (define_insn "*subsi3_carry_zext_0r"
8370 [(set (match_operand:DI 0 "register_operand" "=r")
8371 (zero_extend:DI
8372 (minus:SI
8373 (match_operand:SI 1 "register_operand" "0")
8374 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8375 [(reg FLAGS_REG) (const_int 0)]))))
8376 (clobber (reg:CC FLAGS_REG))]
8377 "TARGET_64BIT"
8378 "adc{l}\t{$-1, %k0|%k0, -1}"
8379 [(set_attr "type" "alu")
8380 (set_attr "use_carry" "1")
8381 (set_attr "pent_pair" "pu")
8382 (set_attr "mode" "SI")])
8383
8384 (define_insn "@sub<mode>3_carry_ccc"
8385 [(set (reg:CCC FLAGS_REG)
8386 (compare:CCC
8387 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8388 (plus:<DWI>
8389 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8390 (zero_extend:<DWI>
8391 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8392 (clobber (match_scratch:DWIH 0 "=r"))]
8393 ""
8394 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8395 [(set_attr "type" "alu")
8396 (set_attr "mode" "<MODE>")])
8397
8398 (define_insn "*sub<mode>3_carry_ccc_1"
8399 [(set (reg:CCC FLAGS_REG)
8400 (compare:CCC
8401 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8402 (plus:<DWI>
8403 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8404 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8405 (clobber (match_scratch:DWIH 0 "=r"))]
8406 ""
8407 {
8408 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8409 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8410 }
8411 [(set_attr "type" "alu")
8412 (set_attr "mode" "<MODE>")])
8413
8414 ;; The sign flag is set from the
8415 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8416 ;; result, the overflow flag likewise, but the overflow flag is also
8417 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8418 (define_insn "@sub<mode>3_carry_ccgz"
8419 [(set (reg:CCGZ FLAGS_REG)
8420 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8421 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8422 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8423 UNSPEC_SBB))
8424 (clobber (match_scratch:DWIH 0 "=r"))]
8425 ""
8426 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8427 [(set_attr "type" "alu")
8428 (set_attr "mode" "<MODE>")])
8429
8430 (define_insn "subborrow<mode>"
8431 [(set (reg:CCC FLAGS_REG)
8432 (compare:CCC
8433 (zero_extend:<DWI>
8434 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8435 (plus:<DWI>
8436 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8437 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8438 (zero_extend:<DWI>
8439 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8440 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8441 (minus:SWI48 (minus:SWI48
8442 (match_dup 1)
8443 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8444 [(match_dup 3) (const_int 0)]))
8445 (match_dup 2)))]
8446 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8447 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8448 [(set_attr "type" "alu")
8449 (set_attr "use_carry" "1")
8450 (set_attr "pent_pair" "pu")
8451 (set_attr "mode" "<MODE>")])
8452
8453 (define_peephole2
8454 [(set (match_operand:SWI48 0 "general_reg_operand")
8455 (match_operand:SWI48 1 "memory_operand"))
8456 (parallel [(set (reg:CCC FLAGS_REG)
8457 (compare:CCC
8458 (zero_extend:<DWI> (match_dup 0))
8459 (plus:<DWI>
8460 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8461 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8462 (zero_extend:<DWI>
8463 (match_operand:SWI48 2 "memory_operand")))))
8464 (set (match_dup 0)
8465 (minus:SWI48
8466 (minus:SWI48
8467 (match_dup 0)
8468 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8469 [(match_dup 3) (const_int 0)]))
8470 (match_dup 2)))])
8471 (set (match_dup 1) (match_dup 0))]
8472 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8473 && peep2_reg_dead_p (3, operands[0])
8474 && !reg_overlap_mentioned_p (operands[0], operands[1])
8475 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8476 [(set (match_dup 0) (match_dup 2))
8477 (parallel [(set (reg:CCC FLAGS_REG)
8478 (compare:CCC
8479 (zero_extend:<DWI> (match_dup 1))
8480 (plus:<DWI> (match_op_dup 4
8481 [(match_dup 3) (const_int 0)])
8482 (zero_extend:<DWI> (match_dup 0)))))
8483 (set (match_dup 1)
8484 (minus:SWI48 (minus:SWI48 (match_dup 1)
8485 (match_op_dup 5
8486 [(match_dup 3) (const_int 0)]))
8487 (match_dup 0)))])])
8488
8489 (define_peephole2
8490 [(set (match_operand:SWI48 6 "general_reg_operand")
8491 (match_operand:SWI48 7 "memory_operand"))
8492 (set (match_operand:SWI48 8 "general_reg_operand")
8493 (match_operand:SWI48 9 "memory_operand"))
8494 (parallel [(set (reg:CCC FLAGS_REG)
8495 (compare:CCC
8496 (zero_extend:<DWI>
8497 (match_operand:SWI48 0 "general_reg_operand"))
8498 (plus:<DWI>
8499 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8500 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8501 (zero_extend:<DWI>
8502 (match_operand:SWI48 2 "general_reg_operand")))))
8503 (set (match_dup 0)
8504 (minus:SWI48
8505 (minus:SWI48
8506 (match_dup 0)
8507 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8508 [(match_dup 3) (const_int 0)]))
8509 (match_dup 2)))])
8510 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8511 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8512 && peep2_reg_dead_p (4, operands[0])
8513 && peep2_reg_dead_p (3, operands[2])
8514 && !reg_overlap_mentioned_p (operands[0], operands[1])
8515 && !reg_overlap_mentioned_p (operands[2], operands[1])
8516 && !reg_overlap_mentioned_p (operands[6], operands[9])
8517 && (rtx_equal_p (operands[6], operands[0])
8518 ? (rtx_equal_p (operands[7], operands[1])
8519 && rtx_equal_p (operands[8], operands[2]))
8520 : (rtx_equal_p (operands[8], operands[0])
8521 && rtx_equal_p (operands[9], operands[1])
8522 && rtx_equal_p (operands[6], operands[2])))"
8523 [(set (match_dup 0) (match_dup 9))
8524 (parallel [(set (reg:CCC FLAGS_REG)
8525 (compare:CCC
8526 (zero_extend:<DWI> (match_dup 1))
8527 (plus:<DWI> (match_op_dup 4
8528 [(match_dup 3) (const_int 0)])
8529 (zero_extend:<DWI> (match_dup 0)))))
8530 (set (match_dup 1)
8531 (minus:SWI48 (minus:SWI48 (match_dup 1)
8532 (match_op_dup 5
8533 [(match_dup 3) (const_int 0)]))
8534 (match_dup 0)))])]
8535 {
8536 if (!rtx_equal_p (operands[6], operands[0]))
8537 operands[9] = operands[7];
8538 })
8539
8540 (define_peephole2
8541 [(set (match_operand:SWI48 6 "general_reg_operand")
8542 (match_operand:SWI48 7 "memory_operand"))
8543 (set (match_operand:SWI48 8 "general_reg_operand")
8544 (match_operand:SWI48 9 "memory_operand"))
8545 (parallel [(set (reg:CCC FLAGS_REG)
8546 (compare:CCC
8547 (zero_extend:<DWI>
8548 (match_operand:SWI48 0 "general_reg_operand"))
8549 (plus:<DWI>
8550 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8551 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8552 (zero_extend:<DWI>
8553 (match_operand:SWI48 2 "general_reg_operand")))))
8554 (set (match_dup 0)
8555 (minus:SWI48
8556 (minus:SWI48
8557 (match_dup 0)
8558 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8559 [(match_dup 3) (const_int 0)]))
8560 (match_dup 2)))])
8561 (set (match_operand:QI 10 "general_reg_operand")
8562 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8563 (set (match_operand:SWI48 11 "general_reg_operand")
8564 (zero_extend:SWI48 (match_dup 10)))
8565 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8566 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8567 && peep2_reg_dead_p (6, operands[0])
8568 && peep2_reg_dead_p (3, operands[2])
8569 && !reg_overlap_mentioned_p (operands[0], operands[1])
8570 && !reg_overlap_mentioned_p (operands[2], operands[1])
8571 && !reg_overlap_mentioned_p (operands[6], operands[9])
8572 && !reg_overlap_mentioned_p (operands[0], operands[10])
8573 && !reg_overlap_mentioned_p (operands[10], operands[1])
8574 && !reg_overlap_mentioned_p (operands[0], operands[11])
8575 && !reg_overlap_mentioned_p (operands[11], operands[1])
8576 && (rtx_equal_p (operands[6], operands[0])
8577 ? (rtx_equal_p (operands[7], operands[1])
8578 && rtx_equal_p (operands[8], operands[2]))
8579 : (rtx_equal_p (operands[8], operands[0])
8580 && rtx_equal_p (operands[9], operands[1])
8581 && rtx_equal_p (operands[6], operands[2])))"
8582 [(set (match_dup 0) (match_dup 9))
8583 (parallel [(set (reg:CCC FLAGS_REG)
8584 (compare:CCC
8585 (zero_extend:<DWI> (match_dup 1))
8586 (plus:<DWI> (match_op_dup 4
8587 [(match_dup 3) (const_int 0)])
8588 (zero_extend:<DWI> (match_dup 0)))))
8589 (set (match_dup 1)
8590 (minus:SWI48 (minus:SWI48 (match_dup 1)
8591 (match_op_dup 5
8592 [(match_dup 3) (const_int 0)]))
8593 (match_dup 0)))])
8594 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8595 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8596 {
8597 if (!rtx_equal_p (operands[6], operands[0]))
8598 operands[9] = operands[7];
8599 })
8600
8601 (define_expand "subborrow<mode>_0"
8602 [(parallel
8603 [(set (reg:CC FLAGS_REG)
8604 (compare:CC
8605 (match_operand:SWI48 1 "nonimmediate_operand")
8606 (match_operand:SWI48 2 "<general_operand>")))
8607 (set (match_operand:SWI48 0 "register_operand")
8608 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8609 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8610
8611 (define_expand "uaddc<mode>5"
8612 [(match_operand:SWI48 0 "register_operand")
8613 (match_operand:SWI48 1 "register_operand")
8614 (match_operand:SWI48 2 "register_operand")
8615 (match_operand:SWI48 3 "register_operand")
8616 (match_operand:SWI48 4 "nonmemory_operand")]
8617 ""
8618 {
8619 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8620 if (operands[4] == const0_rtx)
8621 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8622 else
8623 {
8624 ix86_expand_carry (operands[4]);
8625 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8626 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8627 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8628 cf, pat, pat2));
8629 }
8630 rtx cc = gen_reg_rtx (QImode);
8631 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8632 emit_insn (gen_rtx_SET (cc, pat));
8633 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8634 DONE;
8635 })
8636
8637 (define_expand "usubc<mode>5"
8638 [(match_operand:SWI48 0 "register_operand")
8639 (match_operand:SWI48 1 "register_operand")
8640 (match_operand:SWI48 2 "register_operand")
8641 (match_operand:SWI48 3 "register_operand")
8642 (match_operand:SWI48 4 "nonmemory_operand")]
8643 ""
8644 {
8645 rtx cf, pat, pat2;
8646 if (operands[4] == const0_rtx)
8647 {
8648 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8649 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8650 operands[3]));
8651 }
8652 else
8653 {
8654 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8655 ix86_expand_carry (operands[4]);
8656 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8657 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8658 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8659 cf, pat, pat2));
8660 }
8661 rtx cc = gen_reg_rtx (QImode);
8662 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8663 emit_insn (gen_rtx_SET (cc, pat));
8664 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8665 DONE;
8666 })
8667
8668 (define_mode_iterator CC_CCC [CC CCC])
8669
8670 ;; Pre-reload splitter to optimize
8671 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8672 ;; operand and no intervening flags modifications into nothing.
8673 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8674 [(set (reg:CCC FLAGS_REG)
8675 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8676 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8677 "ix86_pre_reload_split ()"
8678 "#"
8679 "&& 1"
8680 [(const_int 0)]
8681 "emit_note (NOTE_INSN_DELETED); DONE;")
8682
8683 ;; Set the carry flag from the carry flag.
8684 (define_insn_and_split "*setccc"
8685 [(set (reg:CCC FLAGS_REG)
8686 (reg:CCC FLAGS_REG))]
8687 "ix86_pre_reload_split ()"
8688 "#"
8689 "&& 1"
8690 [(const_int 0)]
8691 "emit_note (NOTE_INSN_DELETED); DONE;")
8692
8693 ;; Set the carry flag from the carry flag.
8694 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8695 [(set (reg:CCC FLAGS_REG)
8696 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8697 "ix86_pre_reload_split ()"
8698 "#"
8699 "&& 1"
8700 [(const_int 0)]
8701 "emit_note (NOTE_INSN_DELETED); DONE;")
8702
8703 ;; Set the carry flag from the carry flag.
8704 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8705 [(set (reg:CCC FLAGS_REG)
8706 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8707 (const_int 0)] UNSPEC_CC_NE))]
8708 "ix86_pre_reload_split ()"
8709 "#"
8710 "&& 1"
8711 [(const_int 0)]
8712 "emit_note (NOTE_INSN_DELETED); DONE;")
8713 \f
8714 ;; Overflow setting add instructions
8715
8716 (define_expand "addqi3_cconly_overflow"
8717 [(parallel
8718 [(set (reg:CCC FLAGS_REG)
8719 (compare:CCC
8720 (plus:QI
8721 (match_operand:QI 0 "nonimmediate_operand")
8722 (match_operand:QI 1 "general_operand"))
8723 (match_dup 0)))
8724 (clobber (scratch:QI))])]
8725 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8726
8727 (define_insn "*add<mode>3_cconly_overflow_1"
8728 [(set (reg:CCC FLAGS_REG)
8729 (compare:CCC
8730 (plus:SWI
8731 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8732 (match_operand:SWI 2 "<general_operand>" "<g>"))
8733 (match_dup 1)))
8734 (clobber (match_scratch:SWI 0 "=<r>"))]
8735 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8736 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8737 [(set_attr "type" "alu")
8738 (set_attr "mode" "<MODE>")])
8739
8740 (define_insn "*add<mode>3_cc_overflow_1"
8741 [(set (reg:CCC FLAGS_REG)
8742 (compare:CCC
8743 (plus:SWI
8744 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8745 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8746 (match_dup 1)))
8747 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8748 (plus:SWI (match_dup 1) (match_dup 2)))]
8749 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8750 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8751 [(set_attr "type" "alu")
8752 (set_attr "mode" "<MODE>")])
8753
8754 (define_peephole2
8755 [(parallel [(set (reg:CCC FLAGS_REG)
8756 (compare:CCC
8757 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
8758 (match_operand:SWI 1 "memory_operand"))
8759 (match_dup 0)))
8760 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
8761 (set (match_dup 1) (match_dup 0))]
8762 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8763 && peep2_reg_dead_p (2, operands[0])
8764 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8765 [(parallel [(set (reg:CCC FLAGS_REG)
8766 (compare:CCC
8767 (plus:SWI (match_dup 1) (match_dup 0))
8768 (match_dup 1)))
8769 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8770
8771 (define_peephole2
8772 [(set (match_operand:SWI 0 "general_reg_operand")
8773 (match_operand:SWI 1 "memory_operand"))
8774 (parallel [(set (reg:CCC FLAGS_REG)
8775 (compare:CCC
8776 (plus:SWI (match_dup 0)
8777 (match_operand:SWI 2 "memory_operand"))
8778 (match_dup 0)))
8779 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
8780 (set (match_dup 1) (match_dup 0))]
8781 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8782 && peep2_reg_dead_p (3, operands[0])
8783 && !reg_overlap_mentioned_p (operands[0], operands[1])
8784 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8785 [(set (match_dup 0) (match_dup 2))
8786 (parallel [(set (reg:CCC FLAGS_REG)
8787 (compare:CCC
8788 (plus:SWI (match_dup 1) (match_dup 0))
8789 (match_dup 1)))
8790 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8791
8792 (define_insn "*addsi3_zext_cc_overflow_1"
8793 [(set (reg:CCC FLAGS_REG)
8794 (compare:CCC
8795 (plus:SI
8796 (match_operand:SI 1 "nonimmediate_operand" "%0")
8797 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8798 (match_dup 1)))
8799 (set (match_operand:DI 0 "register_operand" "=r")
8800 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8801 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8802 "add{l}\t{%2, %k0|%k0, %2}"
8803 [(set_attr "type" "alu")
8804 (set_attr "mode" "SI")])
8805
8806 (define_insn "*add<mode>3_cconly_overflow_2"
8807 [(set (reg:CCC FLAGS_REG)
8808 (compare:CCC
8809 (plus:SWI
8810 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8811 (match_operand:SWI 2 "<general_operand>" "<g>"))
8812 (match_dup 2)))
8813 (clobber (match_scratch:SWI 0 "=<r>"))]
8814 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8815 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8816 [(set_attr "type" "alu")
8817 (set_attr "mode" "<MODE>")])
8818
8819 (define_insn "*add<mode>3_cc_overflow_2"
8820 [(set (reg:CCC FLAGS_REG)
8821 (compare:CCC
8822 (plus:SWI
8823 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8824 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8825 (match_dup 2)))
8826 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8827 (plus:SWI (match_dup 1) (match_dup 2)))]
8828 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8829 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8830 [(set_attr "type" "alu")
8831 (set_attr "mode" "<MODE>")])
8832
8833 (define_insn "*addsi3_zext_cc_overflow_2"
8834 [(set (reg:CCC FLAGS_REG)
8835 (compare:CCC
8836 (plus:SI
8837 (match_operand:SI 1 "nonimmediate_operand" "%0")
8838 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8839 (match_dup 2)))
8840 (set (match_operand:DI 0 "register_operand" "=r")
8841 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8842 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8843 "add{l}\t{%2, %k0|%k0, %2}"
8844 [(set_attr "type" "alu")
8845 (set_attr "mode" "SI")])
8846
8847 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
8848 [(set (reg:CCC FLAGS_REG)
8849 (compare:CCC
8850 (plus:<DWI>
8851 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
8852 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
8853 (match_dup 1)))
8854 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
8855 (plus:<DWI> (match_dup 1) (match_dup 2)))]
8856 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
8857 "#"
8858 "&& reload_completed"
8859 [(parallel [(set (reg:CCC FLAGS_REG)
8860 (compare:CCC
8861 (plus:DWIH (match_dup 1) (match_dup 2))
8862 (match_dup 1)))
8863 (set (match_dup 0)
8864 (plus:DWIH (match_dup 1) (match_dup 2)))])
8865 (parallel [(set (reg:CCC FLAGS_REG)
8866 (compare:CCC
8867 (zero_extend:<DWI>
8868 (plus:DWIH
8869 (plus:DWIH
8870 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8871 (match_dup 4))
8872 (match_dup 5)))
8873 (plus:<DWI>
8874 (match_dup 6)
8875 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
8876 (set (match_dup 3)
8877 (plus:DWIH
8878 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8879 (match_dup 4))
8880 (match_dup 5)))])]
8881 {
8882 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8883 if (operands[2] == const0_rtx)
8884 {
8885 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
8886 DONE;
8887 }
8888 if (CONST_INT_P (operands[5]))
8889 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
8890 operands[5], <MODE>mode);
8891 else
8892 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
8893 })
8894
8895 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
8896 ;; test, where the latter is preferrable if we have some carry consuming
8897 ;; instruction.
8898 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
8899 ;; + (1 - CF).
8900 (define_insn_and_split "*add<mode>3_eq"
8901 [(set (match_operand:SWI 0 "nonimmediate_operand")
8902 (plus:SWI
8903 (plus:SWI
8904 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
8905 (match_operand:SWI 1 "nonimmediate_operand"))
8906 (match_operand:SWI 2 "<general_operand>")))
8907 (clobber (reg:CC FLAGS_REG))]
8908 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8909 && ix86_pre_reload_split ()"
8910 "#"
8911 "&& 1"
8912 [(set (reg:CC FLAGS_REG)
8913 (compare:CC (match_dup 3) (const_int 1)))
8914 (parallel [(set (match_dup 0)
8915 (plus:SWI
8916 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
8917 (match_dup 1))
8918 (match_dup 2)))
8919 (clobber (reg:CC FLAGS_REG))])])
8920
8921 (define_insn_and_split "*add<mode>3_ne"
8922 [(set (match_operand:SWI 0 "nonimmediate_operand")
8923 (plus:SWI
8924 (plus:SWI
8925 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
8926 (match_operand:SWI 1 "nonimmediate_operand"))
8927 (match_operand:SWI 2 "<immediate_operand>")))
8928 (clobber (reg:CC FLAGS_REG))]
8929 "CONST_INT_P (operands[2])
8930 && (<MODE>mode != DImode
8931 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
8932 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8933 && ix86_pre_reload_split ()"
8934 "#"
8935 "&& 1"
8936 [(set (reg:CC FLAGS_REG)
8937 (compare:CC (match_dup 3) (const_int 1)))
8938 (parallel [(set (match_dup 0)
8939 (minus:SWI
8940 (minus:SWI (match_dup 1)
8941 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
8942 (match_dup 2)))
8943 (clobber (reg:CC FLAGS_REG))])]
8944 {
8945 operands[2] = gen_int_mode (~INTVAL (operands[2]),
8946 <MODE>mode == DImode ? SImode : <MODE>mode);
8947 })
8948
8949 (define_insn_and_split "*add<mode>3_eq_0"
8950 [(set (match_operand:SWI 0 "nonimmediate_operand")
8951 (plus:SWI
8952 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
8953 (match_operand:SWI 1 "<general_operand>")))
8954 (clobber (reg:CC FLAGS_REG))]
8955 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
8956 && ix86_pre_reload_split ()"
8957 "#"
8958 "&& 1"
8959 [(set (reg:CC FLAGS_REG)
8960 (compare:CC (match_dup 2) (const_int 1)))
8961 (parallel [(set (match_dup 0)
8962 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
8963 (match_dup 1)))
8964 (clobber (reg:CC FLAGS_REG))])]
8965 {
8966 if (!nonimmediate_operand (operands[1], <MODE>mode))
8967 operands[1] = force_reg (<MODE>mode, operands[1]);
8968 })
8969
8970 (define_insn_and_split "*add<mode>3_ne_0"
8971 [(set (match_operand:SWI 0 "nonimmediate_operand")
8972 (plus:SWI
8973 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
8974 (match_operand:SWI 1 "<general_operand>")))
8975 (clobber (reg:CC FLAGS_REG))]
8976 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
8977 && ix86_pre_reload_split ()"
8978 "#"
8979 "&& 1"
8980 [(set (reg:CC FLAGS_REG)
8981 (compare:CC (match_dup 2) (const_int 1)))
8982 (parallel [(set (match_dup 0)
8983 (minus:SWI (minus:SWI
8984 (match_dup 1)
8985 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
8986 (const_int -1)))
8987 (clobber (reg:CC FLAGS_REG))])]
8988 {
8989 if (!nonimmediate_operand (operands[1], <MODE>mode))
8990 operands[1] = force_reg (<MODE>mode, operands[1]);
8991 })
8992
8993 (define_insn_and_split "*sub<mode>3_eq"
8994 [(set (match_operand:SWI 0 "nonimmediate_operand")
8995 (minus:SWI
8996 (minus:SWI
8997 (match_operand:SWI 1 "nonimmediate_operand")
8998 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
8999 (const_int 0)))
9000 (match_operand:SWI 2 "<general_operand>")))
9001 (clobber (reg:CC FLAGS_REG))]
9002 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9003 && ix86_pre_reload_split ()"
9004 "#"
9005 "&& 1"
9006 [(set (reg:CC FLAGS_REG)
9007 (compare:CC (match_dup 3) (const_int 1)))
9008 (parallel [(set (match_dup 0)
9009 (minus:SWI
9010 (minus:SWI (match_dup 1)
9011 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9012 (match_dup 2)))
9013 (clobber (reg:CC FLAGS_REG))])])
9014
9015 (define_insn_and_split "*sub<mode>3_ne"
9016 [(set (match_operand:SWI 0 "nonimmediate_operand")
9017 (plus:SWI
9018 (minus:SWI
9019 (match_operand:SWI 1 "nonimmediate_operand")
9020 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9021 (const_int 0)))
9022 (match_operand:SWI 2 "<immediate_operand>")))
9023 (clobber (reg:CC FLAGS_REG))]
9024 "CONST_INT_P (operands[2])
9025 && (<MODE>mode != DImode
9026 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9027 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9028 && ix86_pre_reload_split ()"
9029 "#"
9030 "&& 1"
9031 [(set (reg:CC FLAGS_REG)
9032 (compare:CC (match_dup 3) (const_int 1)))
9033 (parallel [(set (match_dup 0)
9034 (plus:SWI
9035 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9036 (match_dup 1))
9037 (match_dup 2)))
9038 (clobber (reg:CC FLAGS_REG))])]
9039 {
9040 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9041 <MODE>mode == DImode ? SImode : <MODE>mode);
9042 })
9043
9044 (define_insn_and_split "*sub<mode>3_eq_1"
9045 [(set (match_operand:SWI 0 "nonimmediate_operand")
9046 (plus:SWI
9047 (minus:SWI
9048 (match_operand:SWI 1 "nonimmediate_operand")
9049 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9050 (const_int 0)))
9051 (match_operand:SWI 2 "<immediate_operand>")))
9052 (clobber (reg:CC FLAGS_REG))]
9053 "CONST_INT_P (operands[2])
9054 && (<MODE>mode != DImode
9055 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9056 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9057 && ix86_pre_reload_split ()"
9058 "#"
9059 "&& 1"
9060 [(set (reg:CC FLAGS_REG)
9061 (compare:CC (match_dup 3) (const_int 1)))
9062 (parallel [(set (match_dup 0)
9063 (minus:SWI
9064 (minus:SWI (match_dup 1)
9065 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9066 (match_dup 2)))
9067 (clobber (reg:CC FLAGS_REG))])]
9068 {
9069 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9070 <MODE>mode == DImode ? SImode : <MODE>mode);
9071 })
9072
9073 (define_insn_and_split "*sub<mode>3_eq_0"
9074 [(set (match_operand:SWI 0 "nonimmediate_operand")
9075 (minus:SWI
9076 (match_operand:SWI 1 "<general_operand>")
9077 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9078 (clobber (reg:CC FLAGS_REG))]
9079 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9080 && ix86_pre_reload_split ()"
9081 "#"
9082 "&& 1"
9083 [(set (reg:CC FLAGS_REG)
9084 (compare:CC (match_dup 2) (const_int 1)))
9085 (parallel [(set (match_dup 0)
9086 (minus:SWI (match_dup 1)
9087 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9088 (clobber (reg:CC FLAGS_REG))])]
9089 {
9090 if (!nonimmediate_operand (operands[1], <MODE>mode))
9091 operands[1] = force_reg (<MODE>mode, operands[1]);
9092 })
9093
9094 (define_insn_and_split "*sub<mode>3_ne_0"
9095 [(set (match_operand:SWI 0 "nonimmediate_operand")
9096 (minus:SWI
9097 (match_operand:SWI 1 "<general_operand>")
9098 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9099 (clobber (reg:CC FLAGS_REG))]
9100 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9101 && ix86_pre_reload_split ()"
9102 "#"
9103 "&& 1"
9104 [(set (reg:CC FLAGS_REG)
9105 (compare:CC (match_dup 2) (const_int 1)))
9106 (parallel [(set (match_dup 0)
9107 (plus:SWI (plus:SWI
9108 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9109 (match_dup 1))
9110 (const_int -1)))
9111 (clobber (reg:CC FLAGS_REG))])]
9112 {
9113 if (!nonimmediate_operand (operands[1], <MODE>mode))
9114 operands[1] = force_reg (<MODE>mode, operands[1]);
9115 })
9116
9117 ;; The patterns that match these are at the end of this file.
9118
9119 (define_expand "<insn>xf3"
9120 [(set (match_operand:XF 0 "register_operand")
9121 (plusminus:XF
9122 (match_operand:XF 1 "register_operand")
9123 (match_operand:XF 2 "register_operand")))]
9124 "TARGET_80387")
9125
9126 (define_expand "<insn>hf3"
9127 [(set (match_operand:HF 0 "register_operand")
9128 (plusminus:HF
9129 (match_operand:HF 1 "register_operand")
9130 (match_operand:HF 2 "nonimmediate_operand")))]
9131 "TARGET_AVX512FP16")
9132
9133 (define_expand "<insn><mode>3"
9134 [(set (match_operand:MODEF 0 "register_operand")
9135 (plusminus:MODEF
9136 (match_operand:MODEF 1 "register_operand")
9137 (match_operand:MODEF 2 "nonimmediate_operand")))]
9138 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9139 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9140 \f
9141 ;; Multiply instructions
9142
9143 (define_expand "mul<mode>3"
9144 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9145 (mult:SWIM248
9146 (match_operand:SWIM248 1 "register_operand")
9147 (match_operand:SWIM248 2 "<general_operand>")))
9148 (clobber (reg:CC FLAGS_REG))])])
9149
9150 (define_expand "mulqi3"
9151 [(parallel [(set (match_operand:QI 0 "register_operand")
9152 (mult:QI
9153 (match_operand:QI 1 "register_operand")
9154 (match_operand:QI 2 "nonimmediate_operand")))
9155 (clobber (reg:CC FLAGS_REG))])]
9156 "TARGET_QIMODE_MATH")
9157
9158 ;; On AMDFAM10
9159 ;; IMUL reg32/64, reg32/64, imm8 Direct
9160 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9161 ;; IMUL reg32/64, reg32/64, imm32 Direct
9162 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9163 ;; IMUL reg32/64, reg32/64 Direct
9164 ;; IMUL reg32/64, mem32/64 Direct
9165 ;;
9166 ;; On BDVER1, all above IMULs use DirectPath
9167 ;;
9168 ;; On AMDFAM10
9169 ;; IMUL reg16, reg16, imm8 VectorPath
9170 ;; IMUL reg16, mem16, imm8 VectorPath
9171 ;; IMUL reg16, reg16, imm16 VectorPath
9172 ;; IMUL reg16, mem16, imm16 VectorPath
9173 ;; IMUL reg16, reg16 Direct
9174 ;; IMUL reg16, mem16 Direct
9175 ;;
9176 ;; On BDVER1, all HI MULs use DoublePath
9177
9178 (define_insn "*mul<mode>3_1"
9179 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9180 (mult:SWIM248
9181 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9182 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9183 (clobber (reg:CC FLAGS_REG))]
9184 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9185 "@
9186 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9187 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9188 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9189 [(set_attr "type" "imul")
9190 (set_attr "prefix_0f" "0,0,1")
9191 (set (attr "athlon_decode")
9192 (cond [(eq_attr "cpu" "athlon")
9193 (const_string "vector")
9194 (eq_attr "alternative" "1")
9195 (const_string "vector")
9196 (and (eq_attr "alternative" "2")
9197 (ior (match_test "<MODE>mode == HImode")
9198 (match_operand 1 "memory_operand")))
9199 (const_string "vector")]
9200 (const_string "direct")))
9201 (set (attr "amdfam10_decode")
9202 (cond [(and (eq_attr "alternative" "0,1")
9203 (ior (match_test "<MODE>mode == HImode")
9204 (match_operand 1 "memory_operand")))
9205 (const_string "vector")]
9206 (const_string "direct")))
9207 (set (attr "bdver1_decode")
9208 (if_then_else
9209 (match_test "<MODE>mode == HImode")
9210 (const_string "double")
9211 (const_string "direct")))
9212 (set_attr "mode" "<MODE>")])
9213
9214 (define_insn "*mulsi3_1_zext"
9215 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9216 (zero_extend:DI
9217 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9218 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9219 (clobber (reg:CC FLAGS_REG))]
9220 "TARGET_64BIT
9221 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9222 "@
9223 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9224 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9225 imul{l}\t{%2, %k0|%k0, %2}"
9226 [(set_attr "type" "imul")
9227 (set_attr "prefix_0f" "0,0,1")
9228 (set (attr "athlon_decode")
9229 (cond [(eq_attr "cpu" "athlon")
9230 (const_string "vector")
9231 (eq_attr "alternative" "1")
9232 (const_string "vector")
9233 (and (eq_attr "alternative" "2")
9234 (match_operand 1 "memory_operand"))
9235 (const_string "vector")]
9236 (const_string "direct")))
9237 (set (attr "amdfam10_decode")
9238 (cond [(and (eq_attr "alternative" "0,1")
9239 (match_operand 1 "memory_operand"))
9240 (const_string "vector")]
9241 (const_string "direct")))
9242 (set_attr "bdver1_decode" "direct")
9243 (set_attr "mode" "SI")])
9244
9245 ;;On AMDFAM10 and BDVER1
9246 ;; MUL reg8 Direct
9247 ;; MUL mem8 Direct
9248
9249 (define_insn "*mulqi3_1"
9250 [(set (match_operand:QI 0 "register_operand" "=a")
9251 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9252 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9253 (clobber (reg:CC FLAGS_REG))]
9254 "TARGET_QIMODE_MATH
9255 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9256 "mul{b}\t%2"
9257 [(set_attr "type" "imul")
9258 (set_attr "length_immediate" "0")
9259 (set (attr "athlon_decode")
9260 (if_then_else (eq_attr "cpu" "athlon")
9261 (const_string "vector")
9262 (const_string "direct")))
9263 (set_attr "amdfam10_decode" "direct")
9264 (set_attr "bdver1_decode" "direct")
9265 (set_attr "mode" "QI")])
9266
9267 ;; Multiply with jump on overflow.
9268 (define_expand "mulv<mode>4"
9269 [(parallel [(set (reg:CCO FLAGS_REG)
9270 (eq:CCO (mult:<DWI>
9271 (sign_extend:<DWI>
9272 (match_operand:SWI248 1 "register_operand"))
9273 (match_dup 4))
9274 (sign_extend:<DWI>
9275 (mult:SWI248 (match_dup 1)
9276 (match_operand:SWI248 2
9277 "<general_operand>")))))
9278 (set (match_operand:SWI248 0 "register_operand")
9279 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9280 (set (pc) (if_then_else
9281 (eq (reg:CCO FLAGS_REG) (const_int 0))
9282 (label_ref (match_operand 3))
9283 (pc)))]
9284 ""
9285 {
9286 if (CONST_INT_P (operands[2]))
9287 operands[4] = operands[2];
9288 else
9289 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9290 })
9291
9292 (define_insn "*mulv<mode>4"
9293 [(set (reg:CCO FLAGS_REG)
9294 (eq:CCO (mult:<DWI>
9295 (sign_extend:<DWI>
9296 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9297 (sign_extend:<DWI>
9298 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9299 (sign_extend:<DWI>
9300 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9301 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9302 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9303 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9304 "@
9305 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9306 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9307 [(set_attr "type" "imul")
9308 (set_attr "prefix_0f" "0,1")
9309 (set (attr "athlon_decode")
9310 (cond [(eq_attr "cpu" "athlon")
9311 (const_string "vector")
9312 (eq_attr "alternative" "0")
9313 (const_string "vector")
9314 (and (eq_attr "alternative" "1")
9315 (match_operand 1 "memory_operand"))
9316 (const_string "vector")]
9317 (const_string "direct")))
9318 (set (attr "amdfam10_decode")
9319 (cond [(and (eq_attr "alternative" "1")
9320 (match_operand 1 "memory_operand"))
9321 (const_string "vector")]
9322 (const_string "direct")))
9323 (set_attr "bdver1_decode" "direct")
9324 (set_attr "mode" "<MODE>")])
9325
9326 (define_insn "*mulvhi4"
9327 [(set (reg:CCO FLAGS_REG)
9328 (eq:CCO (mult:SI
9329 (sign_extend:SI
9330 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9331 (sign_extend:SI
9332 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9333 (sign_extend:SI
9334 (mult:HI (match_dup 1) (match_dup 2)))))
9335 (set (match_operand:HI 0 "register_operand" "=r")
9336 (mult:HI (match_dup 1) (match_dup 2)))]
9337 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9338 "imul{w}\t{%2, %0|%0, %2}"
9339 [(set_attr "type" "imul")
9340 (set_attr "prefix_0f" "1")
9341 (set_attr "athlon_decode" "vector")
9342 (set_attr "amdfam10_decode" "direct")
9343 (set_attr "bdver1_decode" "double")
9344 (set_attr "mode" "HI")])
9345
9346 (define_insn "*mulv<mode>4_1"
9347 [(set (reg:CCO FLAGS_REG)
9348 (eq:CCO (mult:<DWI>
9349 (sign_extend:<DWI>
9350 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9351 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9352 (sign_extend:<DWI>
9353 (mult:SWI248 (match_dup 1)
9354 (match_operand:SWI248 2
9355 "<immediate_operand>" "K,<i>")))))
9356 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9357 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9358 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9359 && CONST_INT_P (operands[2])
9360 && INTVAL (operands[2]) == INTVAL (operands[3])"
9361 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9362 [(set_attr "type" "imul")
9363 (set (attr "prefix_0f")
9364 (if_then_else
9365 (match_test "<MODE>mode == HImode")
9366 (const_string "0")
9367 (const_string "*")))
9368 (set (attr "athlon_decode")
9369 (cond [(eq_attr "cpu" "athlon")
9370 (const_string "vector")
9371 (eq_attr "alternative" "1")
9372 (const_string "vector")]
9373 (const_string "direct")))
9374 (set (attr "amdfam10_decode")
9375 (cond [(ior (match_test "<MODE>mode == HImode")
9376 (match_operand 1 "memory_operand"))
9377 (const_string "vector")]
9378 (const_string "direct")))
9379 (set (attr "bdver1_decode")
9380 (if_then_else
9381 (match_test "<MODE>mode == HImode")
9382 (const_string "double")
9383 (const_string "direct")))
9384 (set_attr "mode" "<MODE>")
9385 (set (attr "length_immediate")
9386 (cond [(eq_attr "alternative" "0")
9387 (const_string "1")
9388 (match_test "<MODE_SIZE> == 8")
9389 (const_string "4")]
9390 (const_string "<MODE_SIZE>")))])
9391
9392 (define_expand "umulv<mode>4"
9393 [(parallel [(set (reg:CCO FLAGS_REG)
9394 (eq:CCO (mult:<DWI>
9395 (zero_extend:<DWI>
9396 (match_operand:SWI248 1
9397 "nonimmediate_operand"))
9398 (zero_extend:<DWI>
9399 (match_operand:SWI248 2
9400 "nonimmediate_operand")))
9401 (zero_extend:<DWI>
9402 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9403 (set (match_operand:SWI248 0 "register_operand")
9404 (mult:SWI248 (match_dup 1) (match_dup 2)))
9405 (clobber (scratch:SWI248))])
9406 (set (pc) (if_then_else
9407 (eq (reg:CCO FLAGS_REG) (const_int 0))
9408 (label_ref (match_operand 3))
9409 (pc)))]
9410 ""
9411 {
9412 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9413 operands[1] = force_reg (<MODE>mode, operands[1]);
9414 })
9415
9416 (define_insn "*umulv<mode>4"
9417 [(set (reg:CCO FLAGS_REG)
9418 (eq:CCO (mult:<DWI>
9419 (zero_extend:<DWI>
9420 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9421 (zero_extend:<DWI>
9422 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9423 (zero_extend:<DWI>
9424 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9425 (set (match_operand:SWI248 0 "register_operand" "=a")
9426 (mult:SWI248 (match_dup 1) (match_dup 2)))
9427 (clobber (match_scratch:SWI248 3 "=d"))]
9428 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9429 "mul{<imodesuffix>}\t%2"
9430 [(set_attr "type" "imul")
9431 (set_attr "length_immediate" "0")
9432 (set (attr "athlon_decode")
9433 (if_then_else (eq_attr "cpu" "athlon")
9434 (const_string "vector")
9435 (const_string "double")))
9436 (set_attr "amdfam10_decode" "double")
9437 (set_attr "bdver1_decode" "direct")
9438 (set_attr "mode" "<MODE>")])
9439
9440 (define_expand "<u>mulvqi4"
9441 [(parallel [(set (reg:CCO FLAGS_REG)
9442 (eq:CCO (mult:HI
9443 (any_extend:HI
9444 (match_operand:QI 1 "nonimmediate_operand"))
9445 (any_extend:HI
9446 (match_operand:QI 2 "nonimmediate_operand")))
9447 (any_extend:HI
9448 (mult:QI (match_dup 1) (match_dup 2)))))
9449 (set (match_operand:QI 0 "register_operand")
9450 (mult:QI (match_dup 1) (match_dup 2)))])
9451 (set (pc) (if_then_else
9452 (eq (reg:CCO FLAGS_REG) (const_int 0))
9453 (label_ref (match_operand 3))
9454 (pc)))]
9455 "TARGET_QIMODE_MATH"
9456 {
9457 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9458 operands[1] = force_reg (QImode, operands[1]);
9459 })
9460
9461 (define_insn "*<u>mulvqi4"
9462 [(set (reg:CCO FLAGS_REG)
9463 (eq:CCO (mult:HI
9464 (any_extend:HI
9465 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9466 (any_extend:HI
9467 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9468 (any_extend:HI
9469 (mult:QI (match_dup 1) (match_dup 2)))))
9470 (set (match_operand:QI 0 "register_operand" "=a")
9471 (mult:QI (match_dup 1) (match_dup 2)))]
9472 "TARGET_QIMODE_MATH
9473 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9474 "<sgnprefix>mul{b}\t%2"
9475 [(set_attr "type" "imul")
9476 (set_attr "length_immediate" "0")
9477 (set (attr "athlon_decode")
9478 (if_then_else (eq_attr "cpu" "athlon")
9479 (const_string "vector")
9480 (const_string "direct")))
9481 (set_attr "amdfam10_decode" "direct")
9482 (set_attr "bdver1_decode" "direct")
9483 (set_attr "mode" "QI")])
9484
9485 (define_expand "<u>mul<mode><dwi>3"
9486 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9487 (mult:<DWI>
9488 (any_extend:<DWI>
9489 (match_operand:DWIH 1 "nonimmediate_operand"))
9490 (any_extend:<DWI>
9491 (match_operand:DWIH 2 "register_operand"))))
9492 (clobber (reg:CC FLAGS_REG))])])
9493
9494 (define_expand "<u>mulqihi3"
9495 [(parallel [(set (match_operand:HI 0 "register_operand")
9496 (mult:HI
9497 (any_extend:HI
9498 (match_operand:QI 1 "nonimmediate_operand"))
9499 (any_extend:HI
9500 (match_operand:QI 2 "register_operand"))))
9501 (clobber (reg:CC FLAGS_REG))])]
9502 "TARGET_QIMODE_MATH")
9503
9504 (define_insn "*bmi2_umul<mode><dwi>3_1"
9505 [(set (match_operand:DWIH 0 "register_operand" "=r")
9506 (mult:DWIH
9507 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
9508 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9509 (set (match_operand:DWIH 1 "register_operand" "=r")
9510 (truncate:DWIH
9511 (lshiftrt:<DWI>
9512 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9513 (zero_extend:<DWI> (match_dup 3)))
9514 (match_operand:QI 4 "const_int_operand"))))]
9515 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
9516 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
9517 "mulx\t{%3, %0, %1|%1, %0, %3}"
9518 [(set_attr "type" "imulx")
9519 (set_attr "prefix" "vex")
9520 (set_attr "mode" "<MODE>")])
9521
9522 (define_insn "*umul<mode><dwi>3_1"
9523 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9524 (mult:<DWI>
9525 (zero_extend:<DWI>
9526 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
9527 (zero_extend:<DWI>
9528 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9529 (clobber (reg:CC FLAGS_REG))]
9530 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9531 "@
9532 #
9533 mul{<imodesuffix>}\t%2"
9534 [(set_attr "isa" "bmi2,*")
9535 (set_attr "type" "imulx,imul")
9536 (set_attr "length_immediate" "*,0")
9537 (set (attr "athlon_decode")
9538 (cond [(eq_attr "alternative" "1")
9539 (if_then_else (eq_attr "cpu" "athlon")
9540 (const_string "vector")
9541 (const_string "double"))]
9542 (const_string "*")))
9543 (set_attr "amdfam10_decode" "*,double")
9544 (set_attr "bdver1_decode" "*,direct")
9545 (set_attr "prefix" "vex,orig")
9546 (set_attr "mode" "<MODE>")])
9547
9548 ;; Convert mul to the mulx pattern to avoid flags dependency.
9549 (define_split
9550 [(set (match_operand:<DWI> 0 "register_operand")
9551 (mult:<DWI>
9552 (zero_extend:<DWI>
9553 (match_operand:DWIH 1 "register_operand"))
9554 (zero_extend:<DWI>
9555 (match_operand:DWIH 2 "nonimmediate_operand"))))
9556 (clobber (reg:CC FLAGS_REG))]
9557 "TARGET_BMI2 && reload_completed
9558 && REGNO (operands[1]) == DX_REG"
9559 [(parallel [(set (match_dup 3)
9560 (mult:DWIH (match_dup 1) (match_dup 2)))
9561 (set (match_dup 4)
9562 (truncate:DWIH
9563 (lshiftrt:<DWI>
9564 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
9565 (zero_extend:<DWI> (match_dup 2)))
9566 (match_dup 5))))])]
9567 {
9568 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9569
9570 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9571 })
9572
9573 (define_insn "*mul<mode><dwi>3_1"
9574 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9575 (mult:<DWI>
9576 (sign_extend:<DWI>
9577 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
9578 (sign_extend:<DWI>
9579 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9580 (clobber (reg:CC FLAGS_REG))]
9581 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9582 "imul{<imodesuffix>}\t%2"
9583 [(set_attr "type" "imul")
9584 (set_attr "length_immediate" "0")
9585 (set (attr "athlon_decode")
9586 (if_then_else (eq_attr "cpu" "athlon")
9587 (const_string "vector")
9588 (const_string "double")))
9589 (set_attr "amdfam10_decode" "double")
9590 (set_attr "bdver1_decode" "direct")
9591 (set_attr "mode" "<MODE>")])
9592
9593 (define_insn "*<u>mulqihi3_1"
9594 [(set (match_operand:HI 0 "register_operand" "=a")
9595 (mult:HI
9596 (any_extend:HI
9597 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9598 (any_extend:HI
9599 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9600 (clobber (reg:CC FLAGS_REG))]
9601 "TARGET_QIMODE_MATH
9602 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9603 "<sgnprefix>mul{b}\t%2"
9604 [(set_attr "type" "imul")
9605 (set_attr "length_immediate" "0")
9606 (set (attr "athlon_decode")
9607 (if_then_else (eq_attr "cpu" "athlon")
9608 (const_string "vector")
9609 (const_string "direct")))
9610 (set_attr "amdfam10_decode" "direct")
9611 (set_attr "bdver1_decode" "direct")
9612 (set_attr "mode" "QI")])
9613
9614 ;; Highpart multiplication patterns
9615 (define_insn "<s>mul<mode>3_highpart"
9616 [(set (match_operand:DWIH 0 "register_operand" "=d")
9617 (any_mul_highpart:DWIH
9618 (match_operand:DWIH 1 "register_operand" "%a")
9619 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9620 (clobber (match_scratch:DWIH 3 "=1"))
9621 (clobber (reg:CC FLAGS_REG))]
9622 ""
9623 "<sgnprefix>mul{<imodesuffix>}\t%2"
9624 [(set_attr "type" "imul")
9625 (set_attr "length_immediate" "0")
9626 (set (attr "athlon_decode")
9627 (if_then_else (eq_attr "cpu" "athlon")
9628 (const_string "vector")
9629 (const_string "double")))
9630 (set_attr "amdfam10_decode" "double")
9631 (set_attr "bdver1_decode" "direct")
9632 (set_attr "mode" "<MODE>")])
9633
9634 (define_insn "*<s>mulsi3_highpart_zext"
9635 [(set (match_operand:DI 0 "register_operand" "=d")
9636 (zero_extend:DI
9637 (any_mul_highpart:SI
9638 (match_operand:SI 1 "register_operand" "%a")
9639 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9640 (clobber (match_scratch:SI 3 "=1"))
9641 (clobber (reg:CC FLAGS_REG))]
9642 "TARGET_64BIT"
9643 "<sgnprefix>mul{l}\t%2"
9644 [(set_attr "type" "imul")
9645 (set_attr "length_immediate" "0")
9646 (set (attr "athlon_decode")
9647 (if_then_else (eq_attr "cpu" "athlon")
9648 (const_string "vector")
9649 (const_string "double")))
9650 (set_attr "amdfam10_decode" "double")
9651 (set_attr "bdver1_decode" "direct")
9652 (set_attr "mode" "SI")])
9653
9654 (define_insn "*<s>muldi3_highpart_1"
9655 [(set (match_operand:DI 0 "register_operand" "=d")
9656 (truncate:DI
9657 (lshiftrt:TI
9658 (mult:TI
9659 (any_extend:TI
9660 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9661 (any_extend:TI
9662 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9663 (const_int 64))))
9664 (clobber (match_scratch:DI 3 "=1"))
9665 (clobber (reg:CC FLAGS_REG))]
9666 "TARGET_64BIT
9667 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9668 "<sgnprefix>mul{q}\t%2"
9669 [(set_attr "type" "imul")
9670 (set_attr "length_immediate" "0")
9671 (set (attr "athlon_decode")
9672 (if_then_else (eq_attr "cpu" "athlon")
9673 (const_string "vector")
9674 (const_string "double")))
9675 (set_attr "amdfam10_decode" "double")
9676 (set_attr "bdver1_decode" "direct")
9677 (set_attr "mode" "DI")])
9678
9679 (define_insn "*<s>mulsi3_highpart_zext"
9680 [(set (match_operand:DI 0 "register_operand" "=d")
9681 (zero_extend:DI (truncate:SI
9682 (lshiftrt:DI
9683 (mult:DI (any_extend:DI
9684 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9685 (any_extend:DI
9686 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9687 (const_int 32)))))
9688 (clobber (match_scratch:SI 3 "=1"))
9689 (clobber (reg:CC FLAGS_REG))]
9690 "TARGET_64BIT
9691 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9692 "<sgnprefix>mul{l}\t%2"
9693 [(set_attr "type" "imul")
9694 (set_attr "length_immediate" "0")
9695 (set (attr "athlon_decode")
9696 (if_then_else (eq_attr "cpu" "athlon")
9697 (const_string "vector")
9698 (const_string "double")))
9699 (set_attr "amdfam10_decode" "double")
9700 (set_attr "bdver1_decode" "direct")
9701 (set_attr "mode" "SI")])
9702
9703 (define_insn "*<s>mulsi3_highpart_1"
9704 [(set (match_operand:SI 0 "register_operand" "=d")
9705 (truncate:SI
9706 (lshiftrt:DI
9707 (mult:DI
9708 (any_extend:DI
9709 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9710 (any_extend:DI
9711 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9712 (const_int 32))))
9713 (clobber (match_scratch:SI 3 "=1"))
9714 (clobber (reg:CC FLAGS_REG))]
9715 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9716 "<sgnprefix>mul{l}\t%2"
9717 [(set_attr "type" "imul")
9718 (set_attr "length_immediate" "0")
9719 (set (attr "athlon_decode")
9720 (if_then_else (eq_attr "cpu" "athlon")
9721 (const_string "vector")
9722 (const_string "double")))
9723 (set_attr "amdfam10_decode" "double")
9724 (set_attr "bdver1_decode" "direct")
9725 (set_attr "mode" "SI")])
9726
9727 ;; Highpart multiplication peephole2s to tweak register allocation.
9728 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
9729 (define_peephole2
9730 [(set (match_operand:SWI48 0 "general_reg_operand")
9731 (match_operand:SWI48 1 "immediate_operand"))
9732 (set (match_operand:SWI48 2 "general_reg_operand")
9733 (match_operand:SWI48 3 "general_reg_operand"))
9734 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
9735 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
9736 (clobber (match_dup 2))
9737 (clobber (reg:CC FLAGS_REG))])]
9738 "REGNO (operands[3]) != AX_REG
9739 && REGNO (operands[0]) != REGNO (operands[2])
9740 && REGNO (operands[0]) != REGNO (operands[3])
9741 && (REGNO (operands[0]) == REGNO (operands[4])
9742 || peep2_reg_dead_p (3, operands[0]))"
9743 [(set (match_dup 2) (match_dup 1))
9744 (parallel [(set (match_dup 4)
9745 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
9746 (clobber (match_dup 2))
9747 (clobber (reg:CC FLAGS_REG))])])
9748
9749 (define_peephole2
9750 [(set (match_operand:SI 0 "general_reg_operand")
9751 (match_operand:SI 1 "immediate_operand"))
9752 (set (match_operand:SI 2 "general_reg_operand")
9753 (match_operand:SI 3 "general_reg_operand"))
9754 (parallel [(set (match_operand:DI 4 "general_reg_operand")
9755 (zero_extend:DI
9756 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
9757 (clobber (match_dup 2))
9758 (clobber (reg:CC FLAGS_REG))])]
9759 "TARGET_64BIT
9760 && REGNO (operands[3]) != AX_REG
9761 && REGNO (operands[0]) != REGNO (operands[2])
9762 && REGNO (operands[2]) != REGNO (operands[3])
9763 && REGNO (operands[0]) != REGNO (operands[3])
9764 && (REGNO (operands[0]) == REGNO (operands[4])
9765 || peep2_reg_dead_p (3, operands[0]))"
9766 [(set (match_dup 2) (match_dup 1))
9767 (parallel [(set (match_dup 4)
9768 (zero_extend:DI
9769 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
9770 (clobber (match_dup 2))
9771 (clobber (reg:CC FLAGS_REG))])])
9772
9773 ;; The patterns that match these are at the end of this file.
9774
9775 (define_expand "mulxf3"
9776 [(set (match_operand:XF 0 "register_operand")
9777 (mult:XF (match_operand:XF 1 "register_operand")
9778 (match_operand:XF 2 "register_operand")))]
9779 "TARGET_80387")
9780
9781 (define_expand "mulhf3"
9782 [(set (match_operand:HF 0 "register_operand")
9783 (mult:HF (match_operand:HF 1 "register_operand")
9784 (match_operand:HF 2 "nonimmediate_operand")))]
9785 "TARGET_AVX512FP16")
9786
9787 (define_expand "mul<mode>3"
9788 [(set (match_operand:MODEF 0 "register_operand")
9789 (mult:MODEF (match_operand:MODEF 1 "register_operand")
9790 (match_operand:MODEF 2 "nonimmediate_operand")))]
9791 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9792 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9793 \f
9794 ;; Divide instructions
9795
9796 ;; The patterns that match these are at the end of this file.
9797
9798 (define_expand "divxf3"
9799 [(set (match_operand:XF 0 "register_operand")
9800 (div:XF (match_operand:XF 1 "register_operand")
9801 (match_operand:XF 2 "register_operand")))]
9802 "TARGET_80387")
9803
9804 /* There is no more precision loss than Newton-Rhapson approximation
9805 when using HFmode rcp/rsqrt, so do the transformation directly under
9806 TARGET_RECIP_DIV and fast-math. */
9807 (define_expand "divhf3"
9808 [(set (match_operand:HF 0 "register_operand")
9809 (div:HF (match_operand:HF 1 "register_operand")
9810 (match_operand:HF 2 "nonimmediate_operand")))]
9811 "TARGET_AVX512FP16"
9812 {
9813 if (TARGET_RECIP_DIV
9814 && optimize_insn_for_speed_p ()
9815 && flag_finite_math_only && !flag_trapping_math
9816 && flag_unsafe_math_optimizations)
9817 {
9818 rtx op = gen_reg_rtx (HFmode);
9819 operands[2] = force_reg (HFmode, operands[2]);
9820 emit_insn (gen_rcphf2 (op, operands[2]));
9821 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
9822 DONE;
9823 }
9824 })
9825
9826 (define_expand "div<mode>3"
9827 [(set (match_operand:MODEF 0 "register_operand")
9828 (div:MODEF (match_operand:MODEF 1 "register_operand")
9829 (match_operand:MODEF 2 "nonimmediate_operand")))]
9830 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9831 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9832 {
9833 if (<MODE>mode == SFmode
9834 && TARGET_SSE && TARGET_SSE_MATH
9835 && TARGET_RECIP_DIV
9836 && optimize_insn_for_speed_p ()
9837 && flag_finite_math_only && !flag_trapping_math
9838 && flag_unsafe_math_optimizations)
9839 {
9840 ix86_emit_swdivsf (operands[0], operands[1],
9841 operands[2], SFmode);
9842 DONE;
9843 }
9844 })
9845 \f
9846 ;; Divmod instructions.
9847
9848 (define_code_iterator any_div [div udiv])
9849 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
9850
9851 (define_expand "<u>divmod<mode>4"
9852 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9853 (any_div:SWIM248
9854 (match_operand:SWIM248 1 "register_operand")
9855 (match_operand:SWIM248 2 "nonimmediate_operand")))
9856 (set (match_operand:SWIM248 3 "register_operand")
9857 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
9858 (clobber (reg:CC FLAGS_REG))])])
9859
9860 ;; Split with 8bit unsigned divide:
9861 ;; if (dividend an divisor are in [0-255])
9862 ;; use 8bit unsigned integer divide
9863 ;; else
9864 ;; use original integer divide
9865 (define_split
9866 [(set (match_operand:SWI48 0 "register_operand")
9867 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
9868 (match_operand:SWI48 3 "nonimmediate_operand")))
9869 (set (match_operand:SWI48 1 "register_operand")
9870 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
9871 (clobber (reg:CC FLAGS_REG))]
9872 "TARGET_USE_8BIT_IDIV
9873 && TARGET_QIMODE_MATH
9874 && can_create_pseudo_p ()
9875 && !optimize_insn_for_size_p ()"
9876 [(const_int 0)]
9877 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
9878
9879 (define_split
9880 [(set (match_operand:DI 0 "register_operand")
9881 (zero_extend:DI
9882 (any_div:SI (match_operand:SI 2 "register_operand")
9883 (match_operand:SI 3 "nonimmediate_operand"))))
9884 (set (match_operand:SI 1 "register_operand")
9885 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
9886 (clobber (reg:CC FLAGS_REG))]
9887 "TARGET_64BIT
9888 && TARGET_USE_8BIT_IDIV
9889 && TARGET_QIMODE_MATH
9890 && can_create_pseudo_p ()
9891 && !optimize_insn_for_size_p ()"
9892 [(const_int 0)]
9893 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
9894
9895 (define_split
9896 [(set (match_operand:DI 1 "register_operand")
9897 (zero_extend:DI
9898 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
9899 (match_operand:SI 3 "nonimmediate_operand"))))
9900 (set (match_operand:SI 0 "register_operand")
9901 (any_div:SI (match_dup 2) (match_dup 3)))
9902 (clobber (reg:CC FLAGS_REG))]
9903 "TARGET_64BIT
9904 && TARGET_USE_8BIT_IDIV
9905 && TARGET_QIMODE_MATH
9906 && can_create_pseudo_p ()
9907 && !optimize_insn_for_size_p ()"
9908 [(const_int 0)]
9909 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
9910
9911 (define_insn_and_split "divmod<mode>4_1"
9912 [(set (match_operand:SWI48 0 "register_operand" "=a")
9913 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
9914 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
9915 (set (match_operand:SWI48 1 "register_operand" "=&d")
9916 (mod:SWI48 (match_dup 2) (match_dup 3)))
9917 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
9918 (clobber (reg:CC FLAGS_REG))]
9919 ""
9920 "#"
9921 "reload_completed"
9922 [(parallel [(set (match_dup 1)
9923 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
9924 (clobber (reg:CC FLAGS_REG))])
9925 (parallel [(set (match_dup 0)
9926 (div:SWI48 (match_dup 2) (match_dup 3)))
9927 (set (match_dup 1)
9928 (mod:SWI48 (match_dup 2) (match_dup 3)))
9929 (use (match_dup 1))
9930 (clobber (reg:CC FLAGS_REG))])]
9931 {
9932 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
9933
9934 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
9935 operands[4] = operands[2];
9936 else
9937 {
9938 /* Avoid use of cltd in favor of a mov+shift. */
9939 emit_move_insn (operands[1], operands[2]);
9940 operands[4] = operands[1];
9941 }
9942 }
9943 [(set_attr "type" "multi")
9944 (set_attr "mode" "<MODE>")])
9945
9946 (define_insn_and_split "udivmod<mode>4_1"
9947 [(set (match_operand:SWI48 0 "register_operand" "=a")
9948 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
9949 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
9950 (set (match_operand:SWI48 1 "register_operand" "=&d")
9951 (umod:SWI48 (match_dup 2) (match_dup 3)))
9952 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
9953 (clobber (reg:CC FLAGS_REG))]
9954 ""
9955 "#"
9956 "reload_completed"
9957 [(set (match_dup 1) (const_int 0))
9958 (parallel [(set (match_dup 0)
9959 (udiv:SWI48 (match_dup 2) (match_dup 3)))
9960 (set (match_dup 1)
9961 (umod:SWI48 (match_dup 2) (match_dup 3)))
9962 (use (match_dup 1))
9963 (clobber (reg:CC FLAGS_REG))])]
9964 ""
9965 [(set_attr "type" "multi")
9966 (set_attr "mode" "<MODE>")])
9967
9968 (define_insn_and_split "divmodsi4_zext_1"
9969 [(set (match_operand:DI 0 "register_operand" "=a")
9970 (zero_extend:DI
9971 (div:SI (match_operand:SI 2 "register_operand" "0")
9972 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
9973 (set (match_operand:SI 1 "register_operand" "=&d")
9974 (mod:SI (match_dup 2) (match_dup 3)))
9975 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
9976 (clobber (reg:CC FLAGS_REG))]
9977 "TARGET_64BIT"
9978 "#"
9979 "&& reload_completed"
9980 [(parallel [(set (match_dup 1)
9981 (ashiftrt:SI (match_dup 4) (match_dup 5)))
9982 (clobber (reg:CC FLAGS_REG))])
9983 (parallel [(set (match_dup 0)
9984 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
9985 (set (match_dup 1)
9986 (mod:SI (match_dup 2) (match_dup 3)))
9987 (use (match_dup 1))
9988 (clobber (reg:CC FLAGS_REG))])]
9989 {
9990 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
9991
9992 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
9993 operands[4] = operands[2];
9994 else
9995 {
9996 /* Avoid use of cltd in favor of a mov+shift. */
9997 emit_move_insn (operands[1], operands[2]);
9998 operands[4] = operands[1];
9999 }
10000 }
10001 [(set_attr "type" "multi")
10002 (set_attr "mode" "SI")])
10003
10004 (define_insn_and_split "udivmodsi4_zext_1"
10005 [(set (match_operand:DI 0 "register_operand" "=a")
10006 (zero_extend:DI
10007 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10008 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10009 (set (match_operand:SI 1 "register_operand" "=&d")
10010 (umod:SI (match_dup 2) (match_dup 3)))
10011 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10012 (clobber (reg:CC FLAGS_REG))]
10013 "TARGET_64BIT"
10014 "#"
10015 "&& reload_completed"
10016 [(set (match_dup 1) (const_int 0))
10017 (parallel [(set (match_dup 0)
10018 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10019 (set (match_dup 1)
10020 (umod:SI (match_dup 2) (match_dup 3)))
10021 (use (match_dup 1))
10022 (clobber (reg:CC FLAGS_REG))])]
10023 ""
10024 [(set_attr "type" "multi")
10025 (set_attr "mode" "SI")])
10026
10027 (define_insn_and_split "divmodsi4_zext_2"
10028 [(set (match_operand:DI 1 "register_operand" "=&d")
10029 (zero_extend:DI
10030 (mod:SI (match_operand:SI 2 "register_operand" "0")
10031 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10032 (set (match_operand:SI 0 "register_operand" "=a")
10033 (div:SI (match_dup 2) (match_dup 3)))
10034 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10035 (clobber (reg:CC FLAGS_REG))]
10036 "TARGET_64BIT"
10037 "#"
10038 "&& reload_completed"
10039 [(parallel [(set (match_dup 6)
10040 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10041 (clobber (reg:CC FLAGS_REG))])
10042 (parallel [(set (match_dup 1)
10043 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10044 (set (match_dup 0)
10045 (div:SI (match_dup 2) (match_dup 3)))
10046 (use (match_dup 6))
10047 (clobber (reg:CC FLAGS_REG))])]
10048 {
10049 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10050 operands[6] = gen_lowpart (SImode, operands[1]);
10051
10052 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10053 operands[4] = operands[2];
10054 else
10055 {
10056 /* Avoid use of cltd in favor of a mov+shift. */
10057 emit_move_insn (operands[6], operands[2]);
10058 operands[4] = operands[6];
10059 }
10060 }
10061 [(set_attr "type" "multi")
10062 (set_attr "mode" "SI")])
10063
10064 (define_insn_and_split "udivmodsi4_zext_2"
10065 [(set (match_operand:DI 1 "register_operand" "=&d")
10066 (zero_extend:DI
10067 (umod:SI (match_operand:SI 2 "register_operand" "0")
10068 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10069 (set (match_operand:SI 0 "register_operand" "=a")
10070 (udiv:SI (match_dup 2) (match_dup 3)))
10071 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10072 (clobber (reg:CC FLAGS_REG))]
10073 "TARGET_64BIT"
10074 "#"
10075 "&& reload_completed"
10076 [(set (match_dup 4) (const_int 0))
10077 (parallel [(set (match_dup 1)
10078 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10079 (set (match_dup 0)
10080 (udiv:SI (match_dup 2) (match_dup 3)))
10081 (use (match_dup 4))
10082 (clobber (reg:CC FLAGS_REG))])]
10083 "operands[4] = gen_lowpart (SImode, operands[1]);"
10084 [(set_attr "type" "multi")
10085 (set_attr "mode" "SI")])
10086
10087 (define_insn_and_split "*divmod<mode>4"
10088 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10089 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10090 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10091 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10092 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10093 (clobber (reg:CC FLAGS_REG))]
10094 ""
10095 "#"
10096 "reload_completed"
10097 [(parallel [(set (match_dup 1)
10098 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10099 (clobber (reg:CC FLAGS_REG))])
10100 (parallel [(set (match_dup 0)
10101 (div:SWIM248 (match_dup 2) (match_dup 3)))
10102 (set (match_dup 1)
10103 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10104 (use (match_dup 1))
10105 (clobber (reg:CC FLAGS_REG))])]
10106 {
10107 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10108
10109 if (<MODE>mode != HImode
10110 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10111 operands[4] = operands[2];
10112 else
10113 {
10114 /* Avoid use of cltd in favor of a mov+shift. */
10115 emit_move_insn (operands[1], operands[2]);
10116 operands[4] = operands[1];
10117 }
10118 }
10119 [(set_attr "type" "multi")
10120 (set_attr "mode" "<MODE>")])
10121
10122 (define_insn_and_split "*udivmod<mode>4"
10123 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10124 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10125 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10126 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10127 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10128 (clobber (reg:CC FLAGS_REG))]
10129 ""
10130 "#"
10131 "reload_completed"
10132 [(set (match_dup 1) (const_int 0))
10133 (parallel [(set (match_dup 0)
10134 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10135 (set (match_dup 1)
10136 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10137 (use (match_dup 1))
10138 (clobber (reg:CC FLAGS_REG))])]
10139 ""
10140 [(set_attr "type" "multi")
10141 (set_attr "mode" "<MODE>")])
10142
10143 ;; Optimize division or modulo by constant power of 2, if the constant
10144 ;; materializes only after expansion.
10145 (define_insn_and_split "*udivmod<mode>4_pow2"
10146 [(set (match_operand:SWI48 0 "register_operand" "=r")
10147 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10148 (match_operand:SWI48 3 "const_int_operand")))
10149 (set (match_operand:SWI48 1 "register_operand" "=r")
10150 (umod:SWI48 (match_dup 2) (match_dup 3)))
10151 (clobber (reg:CC FLAGS_REG))]
10152 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10153 "#"
10154 "&& reload_completed"
10155 [(set (match_dup 1) (match_dup 2))
10156 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10157 (clobber (reg:CC FLAGS_REG))])
10158 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10159 (clobber (reg:CC FLAGS_REG))])]
10160 {
10161 int v = exact_log2 (UINTVAL (operands[3]));
10162 operands[4] = GEN_INT (v);
10163 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10164 }
10165 [(set_attr "type" "multi")
10166 (set_attr "mode" "<MODE>")])
10167
10168 (define_insn_and_split "*divmodsi4_zext_1"
10169 [(set (match_operand:DI 0 "register_operand" "=a")
10170 (zero_extend:DI
10171 (div:SI (match_operand:SI 2 "register_operand" "0")
10172 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10173 (set (match_operand:SI 1 "register_operand" "=&d")
10174 (mod:SI (match_dup 2) (match_dup 3)))
10175 (clobber (reg:CC FLAGS_REG))]
10176 "TARGET_64BIT"
10177 "#"
10178 "&& reload_completed"
10179 [(parallel [(set (match_dup 1)
10180 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10181 (clobber (reg:CC FLAGS_REG))])
10182 (parallel [(set (match_dup 0)
10183 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10184 (set (match_dup 1)
10185 (mod:SI (match_dup 2) (match_dup 3)))
10186 (use (match_dup 1))
10187 (clobber (reg:CC FLAGS_REG))])]
10188 {
10189 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10190
10191 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10192 operands[4] = operands[2];
10193 else
10194 {
10195 /* Avoid use of cltd in favor of a mov+shift. */
10196 emit_move_insn (operands[1], operands[2]);
10197 operands[4] = operands[1];
10198 }
10199 }
10200 [(set_attr "type" "multi")
10201 (set_attr "mode" "SI")])
10202
10203 (define_insn_and_split "*udivmodsi4_zext_1"
10204 [(set (match_operand:DI 0 "register_operand" "=a")
10205 (zero_extend:DI
10206 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10207 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10208 (set (match_operand:SI 1 "register_operand" "=&d")
10209 (umod:SI (match_dup 2) (match_dup 3)))
10210 (clobber (reg:CC FLAGS_REG))]
10211 "TARGET_64BIT"
10212 "#"
10213 "&& reload_completed"
10214 [(set (match_dup 1) (const_int 0))
10215 (parallel [(set (match_dup 0)
10216 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10217 (set (match_dup 1)
10218 (umod:SI (match_dup 2) (match_dup 3)))
10219 (use (match_dup 1))
10220 (clobber (reg:CC FLAGS_REG))])]
10221 ""
10222 [(set_attr "type" "multi")
10223 (set_attr "mode" "SI")])
10224
10225 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10226 [(set (match_operand:DI 0 "register_operand" "=r")
10227 (zero_extend:DI
10228 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10229 (match_operand:SI 3 "const_int_operand"))))
10230 (set (match_operand:SI 1 "register_operand" "=r")
10231 (umod:SI (match_dup 2) (match_dup 3)))
10232 (clobber (reg:CC FLAGS_REG))]
10233 "TARGET_64BIT
10234 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10235 "#"
10236 "&& reload_completed"
10237 [(set (match_dup 1) (match_dup 2))
10238 (parallel [(set (match_dup 0)
10239 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10240 (clobber (reg:CC FLAGS_REG))])
10241 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10242 (clobber (reg:CC FLAGS_REG))])]
10243 {
10244 int v = exact_log2 (UINTVAL (operands[3]));
10245 operands[4] = GEN_INT (v);
10246 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10247 }
10248 [(set_attr "type" "multi")
10249 (set_attr "mode" "SI")])
10250
10251 (define_insn_and_split "*divmodsi4_zext_2"
10252 [(set (match_operand:DI 1 "register_operand" "=&d")
10253 (zero_extend:DI
10254 (mod:SI (match_operand:SI 2 "register_operand" "0")
10255 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10256 (set (match_operand:SI 0 "register_operand" "=a")
10257 (div:SI (match_dup 2) (match_dup 3)))
10258 (clobber (reg:CC FLAGS_REG))]
10259 "TARGET_64BIT"
10260 "#"
10261 "&& reload_completed"
10262 [(parallel [(set (match_dup 6)
10263 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10264 (clobber (reg:CC FLAGS_REG))])
10265 (parallel [(set (match_dup 1)
10266 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10267 (set (match_dup 0)
10268 (div:SI (match_dup 2) (match_dup 3)))
10269 (use (match_dup 6))
10270 (clobber (reg:CC FLAGS_REG))])]
10271 {
10272 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10273 operands[6] = gen_lowpart (SImode, operands[1]);
10274
10275 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10276 operands[4] = operands[2];
10277 else
10278 {
10279 /* Avoid use of cltd in favor of a mov+shift. */
10280 emit_move_insn (operands[6], operands[2]);
10281 operands[4] = operands[6];
10282 }
10283 }
10284 [(set_attr "type" "multi")
10285 (set_attr "mode" "SI")])
10286
10287 (define_insn_and_split "*udivmodsi4_zext_2"
10288 [(set (match_operand:DI 1 "register_operand" "=&d")
10289 (zero_extend:DI
10290 (umod:SI (match_operand:SI 2 "register_operand" "0")
10291 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10292 (set (match_operand:SI 0 "register_operand" "=a")
10293 (udiv:SI (match_dup 2) (match_dup 3)))
10294 (clobber (reg:CC FLAGS_REG))]
10295 "TARGET_64BIT"
10296 "#"
10297 "&& reload_completed"
10298 [(set (match_dup 4) (const_int 0))
10299 (parallel [(set (match_dup 1)
10300 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10301 (set (match_dup 0)
10302 (udiv:SI (match_dup 2) (match_dup 3)))
10303 (use (match_dup 4))
10304 (clobber (reg:CC FLAGS_REG))])]
10305 "operands[4] = gen_lowpart (SImode, operands[1]);"
10306 [(set_attr "type" "multi")
10307 (set_attr "mode" "SI")])
10308
10309 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10310 [(set (match_operand:DI 1 "register_operand" "=r")
10311 (zero_extend:DI
10312 (umod:SI (match_operand:SI 2 "register_operand" "0")
10313 (match_operand:SI 3 "const_int_operand"))))
10314 (set (match_operand:SI 0 "register_operand" "=r")
10315 (udiv:SI (match_dup 2) (match_dup 3)))
10316 (clobber (reg:CC FLAGS_REG))]
10317 "TARGET_64BIT
10318 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10319 "#"
10320 "&& reload_completed"
10321 [(set (match_dup 1) (match_dup 2))
10322 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10323 (clobber (reg:CC FLAGS_REG))])
10324 (parallel [(set (match_dup 1)
10325 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10326 (clobber (reg:CC FLAGS_REG))])]
10327 {
10328 int v = exact_log2 (UINTVAL (operands[3]));
10329 operands[4] = GEN_INT (v);
10330 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10331 }
10332 [(set_attr "type" "multi")
10333 (set_attr "mode" "SI")])
10334
10335 (define_insn "*<u>divmod<mode>4_noext"
10336 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10337 (any_div:SWIM248
10338 (match_operand:SWIM248 2 "register_operand" "0")
10339 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10340 (set (match_operand:SWIM248 1 "register_operand" "=d")
10341 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10342 (use (match_operand:SWIM248 4 "register_operand" "1"))
10343 (clobber (reg:CC FLAGS_REG))]
10344 ""
10345 "<sgnprefix>div{<imodesuffix>}\t%3"
10346 [(set_attr "type" "idiv")
10347 (set_attr "mode" "<MODE>")])
10348
10349 (define_insn "*<u>divmodsi4_noext_zext_1"
10350 [(set (match_operand:DI 0 "register_operand" "=a")
10351 (zero_extend:DI
10352 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10353 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10354 (set (match_operand:SI 1 "register_operand" "=d")
10355 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10356 (use (match_operand:SI 4 "register_operand" "1"))
10357 (clobber (reg:CC FLAGS_REG))]
10358 "TARGET_64BIT"
10359 "<sgnprefix>div{l}\t%3"
10360 [(set_attr "type" "idiv")
10361 (set_attr "mode" "SI")])
10362
10363 (define_insn "*<u>divmodsi4_noext_zext_2"
10364 [(set (match_operand:DI 1 "register_operand" "=d")
10365 (zero_extend:DI
10366 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10367 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10368 (set (match_operand:SI 0 "register_operand" "=a")
10369 (any_div:SI (match_dup 2) (match_dup 3)))
10370 (use (match_operand:SI 4 "register_operand" "1"))
10371 (clobber (reg:CC FLAGS_REG))]
10372 "TARGET_64BIT"
10373 "<sgnprefix>div{l}\t%3"
10374 [(set_attr "type" "idiv")
10375 (set_attr "mode" "SI")])
10376
10377 ;; Avoid sign-extension (using cdq) for constant numerators.
10378 (define_insn_and_split "*divmodsi4_const"
10379 [(set (match_operand:SI 0 "register_operand" "=&a")
10380 (div:SI (match_operand:SI 2 "const_int_operand")
10381 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10382 (set (match_operand:SI 1 "register_operand" "=&d")
10383 (mod:SI (match_dup 2) (match_dup 3)))
10384 (clobber (reg:CC FLAGS_REG))]
10385 "!optimize_function_for_size_p (cfun)"
10386 "#"
10387 "&& reload_completed"
10388 [(set (match_dup 0) (match_dup 2))
10389 (set (match_dup 1) (match_dup 4))
10390 (parallel [(set (match_dup 0)
10391 (div:SI (match_dup 0) (match_dup 3)))
10392 (set (match_dup 1)
10393 (mod:SI (match_dup 0) (match_dup 3)))
10394 (use (match_dup 1))
10395 (clobber (reg:CC FLAGS_REG))])]
10396 {
10397 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10398 }
10399 [(set_attr "type" "multi")
10400 (set_attr "mode" "SI")])
10401
10402 (define_expand "divmodqi4"
10403 [(parallel [(set (match_operand:QI 0 "register_operand")
10404 (div:QI
10405 (match_operand:QI 1 "register_operand")
10406 (match_operand:QI 2 "nonimmediate_operand")))
10407 (set (match_operand:QI 3 "register_operand")
10408 (mod:QI (match_dup 1) (match_dup 2)))
10409 (clobber (reg:CC FLAGS_REG))])]
10410 "TARGET_QIMODE_MATH"
10411 {
10412 rtx div, mod;
10413 rtx tmp0, tmp1;
10414
10415 tmp0 = gen_reg_rtx (HImode);
10416 tmp1 = gen_reg_rtx (HImode);
10417
10418 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10419 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10420 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10421
10422 /* Extract remainder from AH. */
10423 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10424 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10425 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10426
10427 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10428 set_unique_reg_note (insn, REG_EQUAL, mod);
10429
10430 /* Extract quotient from AL. */
10431 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10432
10433 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10434 set_unique_reg_note (insn, REG_EQUAL, div);
10435
10436 DONE;
10437 })
10438
10439 (define_expand "udivmodqi4"
10440 [(parallel [(set (match_operand:QI 0 "register_operand")
10441 (udiv:QI
10442 (match_operand:QI 1 "register_operand")
10443 (match_operand:QI 2 "nonimmediate_operand")))
10444 (set (match_operand:QI 3 "register_operand")
10445 (umod:QI (match_dup 1) (match_dup 2)))
10446 (clobber (reg:CC FLAGS_REG))])]
10447 "TARGET_QIMODE_MATH"
10448 {
10449 rtx div, mod;
10450 rtx tmp0, tmp1;
10451
10452 tmp0 = gen_reg_rtx (HImode);
10453 tmp1 = gen_reg_rtx (HImode);
10454
10455 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10456 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10457 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10458
10459 /* Extract remainder from AH. */
10460 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10461 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10462 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10463
10464 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10465 set_unique_reg_note (insn, REG_EQUAL, mod);
10466
10467 /* Extract quotient from AL. */
10468 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10469
10470 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10471 set_unique_reg_note (insn, REG_EQUAL, div);
10472
10473 DONE;
10474 })
10475
10476 ;; Divide AX by r/m8, with result stored in
10477 ;; AL <- Quotient
10478 ;; AH <- Remainder
10479 ;; Change div/mod to HImode and extend the second argument to HImode
10480 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10481 ;; combine may fail.
10482 (define_insn "<u>divmodhiqi3"
10483 [(set (match_operand:HI 0 "register_operand" "=a")
10484 (ior:HI
10485 (ashift:HI
10486 (zero_extend:HI
10487 (truncate:QI
10488 (mod:HI (match_operand:HI 1 "register_operand" "0")
10489 (any_extend:HI
10490 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10491 (const_int 8))
10492 (zero_extend:HI
10493 (truncate:QI
10494 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10495 (clobber (reg:CC FLAGS_REG))]
10496 "TARGET_QIMODE_MATH"
10497 "<sgnprefix>div{b}\t%2"
10498 [(set_attr "type" "idiv")
10499 (set_attr "mode" "QI")])
10500
10501 ;; We cannot use div/idiv for double division, because it causes
10502 ;; "division by zero" on the overflow and that's not what we expect
10503 ;; from truncate. Because true (non truncating) double division is
10504 ;; never generated, we can't create this insn anyway.
10505 ;
10506 ;(define_insn ""
10507 ; [(set (match_operand:SI 0 "register_operand" "=a")
10508 ; (truncate:SI
10509 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10510 ; (zero_extend:DI
10511 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10512 ; (set (match_operand:SI 3 "register_operand" "=d")
10513 ; (truncate:SI
10514 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10515 ; (clobber (reg:CC FLAGS_REG))]
10516 ; ""
10517 ; "div{l}\t{%2, %0|%0, %2}"
10518 ; [(set_attr "type" "idiv")])
10519 \f
10520 ;;- Logical AND instructions
10521
10522 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10523 ;; Note that this excludes ah.
10524
10525 (define_expand "@test<mode>_ccno_1"
10526 [(set (reg:CCNO FLAGS_REG)
10527 (compare:CCNO
10528 (and:SWI48
10529 (match_operand:SWI48 0 "nonimmediate_operand")
10530 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10531 (const_int 0)))])
10532
10533 (define_expand "testqi_ccz_1"
10534 [(set (reg:CCZ FLAGS_REG)
10535 (compare:CCZ
10536 (and:QI
10537 (match_operand:QI 0 "nonimmediate_operand")
10538 (match_operand:QI 1 "nonmemory_operand"))
10539 (const_int 0)))])
10540
10541 (define_insn "*testdi_1"
10542 [(set (reg FLAGS_REG)
10543 (compare
10544 (and:DI
10545 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10546 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10547 (const_int 0)))]
10548 "TARGET_64BIT
10549 && ix86_match_ccmode
10550 (insn,
10551 /* If we are going to emit testl instead of testq, and the operands[1]
10552 constant might have the SImode sign bit set, make sure the sign
10553 flag isn't tested, because the instruction will set the sign flag
10554 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10555 conservatively assume it might have bit 31 set. */
10556 (satisfies_constraint_Z (operands[1])
10557 && (!CONST_INT_P (operands[1])
10558 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10559 ? CCZmode : CCNOmode)"
10560 "@
10561 test{l}\t{%k1, %k0|%k0, %k1}
10562 test{q}\t{%1, %0|%0, %1}"
10563 [(set_attr "type" "test")
10564 (set_attr "mode" "SI,DI")])
10565
10566 (define_insn "*testqi_1_maybe_si"
10567 [(set (reg FLAGS_REG)
10568 (compare
10569 (and:QI
10570 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10571 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10572 (const_int 0)))]
10573 "ix86_match_ccmode (insn,
10574 CONST_INT_P (operands[1])
10575 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10576 {
10577 if (get_attr_mode (insn) == MODE_SI)
10578 {
10579 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10580 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10581 return "test{l}\t{%1, %k0|%k0, %1}";
10582 }
10583 return "test{b}\t{%1, %0|%0, %1}";
10584 }
10585 [(set_attr "type" "test")
10586 (set (attr "mode")
10587 (cond [(eq_attr "alternative" "2")
10588 (const_string "SI")
10589 (and (match_test "optimize_insn_for_size_p ()")
10590 (and (match_operand 0 "ext_QIreg_operand")
10591 (match_operand 1 "const_0_to_127_operand")))
10592 (const_string "SI")
10593 ]
10594 (const_string "QI")))
10595 (set_attr "pent_pair" "uv,np,np")])
10596
10597 (define_insn "*test<mode>_1"
10598 [(set (reg FLAGS_REG)
10599 (compare
10600 (and:SWI124
10601 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10602 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10603 (const_int 0)))]
10604 "ix86_match_ccmode (insn, CCNOmode)"
10605 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10606 [(set_attr "type" "test")
10607 (set_attr "mode" "<MODE>")
10608 (set_attr "pent_pair" "uv,uv,np")])
10609
10610 (define_expand "testqi_ext_1_ccno"
10611 [(set (reg:CCNO FLAGS_REG)
10612 (compare:CCNO
10613 (and:QI
10614 (subreg:QI
10615 (zero_extract:HI
10616 (match_operand:HI 0 "register_operand")
10617 (const_int 8)
10618 (const_int 8)) 0)
10619 (match_operand:QI 1 "const_int_operand"))
10620 (const_int 0)))])
10621
10622 (define_insn "*testqi_ext<mode>_1"
10623 [(set (reg FLAGS_REG)
10624 (compare
10625 (and:QI
10626 (subreg:QI
10627 (match_operator:SWI248 2 "extract_operator"
10628 [(match_operand 0 "int248_register_operand" "Q,Q")
10629 (const_int 8)
10630 (const_int 8)]) 0)
10631 (match_operand:QI 1 "general_x64constmem_operand" "QnBc,m"))
10632 (const_int 0)))]
10633 "ix86_match_ccmode (insn, CCNOmode)"
10634 "test{b}\t{%1, %h0|%h0, %1}"
10635 [(set_attr "isa" "*,nox64")
10636 (set_attr "type" "test")
10637 (set_attr "mode" "QI")])
10638
10639 (define_insn "*testqi_ext<mode>_2"
10640 [(set (reg FLAGS_REG)
10641 (compare
10642 (and:QI
10643 (subreg:QI
10644 (match_operator:SWI248 2 "extract_operator"
10645 [(match_operand 0 "int248_register_operand" "Q")
10646 (const_int 8)
10647 (const_int 8)]) 0)
10648 (subreg:QI
10649 (match_operator:SWI248 3 "extract_operator"
10650 [(match_operand 1 "int248_register_operand" "Q")
10651 (const_int 8)
10652 (const_int 8)]) 0))
10653 (const_int 0)))]
10654 "ix86_match_ccmode (insn, CCNOmode)"
10655 "test{b}\t{%h1, %h0|%h0, %h1}"
10656 [(set_attr "type" "test")
10657 (set_attr "mode" "QI")])
10658
10659 ;; Provide a *testti instruction that STV can implement using ptest.
10660 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10661 (define_insn_and_split "*testti_doubleword"
10662 [(set (reg:CCZ FLAGS_REG)
10663 (compare:CCZ
10664 (and:TI (match_operand:TI 0 "register_operand")
10665 (match_operand:TI 1 "general_operand"))
10666 (const_int 0)))]
10667 "TARGET_64BIT
10668 && ix86_pre_reload_split ()"
10669 "#"
10670 "&& 1"
10671 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10672 (clobber (reg:CC FLAGS_REG))])
10673 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10674 {
10675 operands[2] = gen_reg_rtx (TImode);
10676 if (!x86_64_hilo_general_operand (operands[1], TImode))
10677 operands[1] = force_reg (TImode, operands[1]);
10678 })
10679
10680 ;; Combine likes to form bit extractions for some tests. Humor it.
10681 (define_insn_and_split "*testqi_ext_3"
10682 [(set (match_operand 0 "flags_reg_operand")
10683 (match_operator 1 "compare_operator"
10684 [(zero_extract:SWI248
10685 (match_operand 2 "int_nonimmediate_operand" "rm")
10686 (match_operand 3 "const_int_operand")
10687 (match_operand 4 "const_int_operand"))
10688 (const_int 0)]))]
10689 "/* Ensure that resulting mask is zero or sign extended operand. */
10690 INTVAL (operands[4]) >= 0
10691 && ((INTVAL (operands[3]) > 0
10692 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
10693 || (<MODE>mode == DImode
10694 && INTVAL (operands[3]) > 32
10695 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
10696 && ix86_match_ccmode (insn,
10697 /* If zero_extract mode precision is the same
10698 as len, the SF of the zero_extract
10699 comparison will be the most significant
10700 extracted bit, but this could be matched
10701 after splitting only for pos 0 len all bits
10702 trivial extractions. Require CCZmode. */
10703 (GET_MODE_PRECISION (<MODE>mode)
10704 == INTVAL (operands[3]))
10705 /* Otherwise, require CCZmode if we'd use a mask
10706 with the most significant bit set and can't
10707 widen it to wider mode. *testdi_1 also
10708 requires CCZmode if the mask has bit
10709 31 set and all bits above it clear. */
10710 || (INTVAL (operands[3]) + INTVAL (operands[4])
10711 >= 32)
10712 /* We can't widen also if val is not a REG. */
10713 || (INTVAL (operands[3]) + INTVAL (operands[4])
10714 == GET_MODE_PRECISION (GET_MODE (operands[2]))
10715 && !register_operand (operands[2],
10716 GET_MODE (operands[2])))
10717 /* And we shouldn't widen if
10718 TARGET_PARTIAL_REG_STALL. */
10719 || (TARGET_PARTIAL_REG_STALL
10720 && (INTVAL (operands[3]) + INTVAL (operands[4])
10721 >= (paradoxical_subreg_p (operands[2])
10722 && (GET_MODE_CLASS
10723 (GET_MODE (SUBREG_REG (operands[2])))
10724 == MODE_INT)
10725 ? GET_MODE_PRECISION
10726 (GET_MODE (SUBREG_REG (operands[2])))
10727 : GET_MODE_PRECISION
10728 (GET_MODE (operands[2])))))
10729 ? CCZmode : CCNOmode)"
10730 "#"
10731 "&& 1"
10732 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10733 {
10734 rtx val = operands[2];
10735 HOST_WIDE_INT len = INTVAL (operands[3]);
10736 HOST_WIDE_INT pos = INTVAL (operands[4]);
10737 machine_mode mode = GET_MODE (val);
10738
10739 if (SUBREG_P (val))
10740 {
10741 machine_mode submode = GET_MODE (SUBREG_REG (val));
10742
10743 /* Narrow paradoxical subregs to prevent partial register stalls. */
10744 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
10745 && GET_MODE_CLASS (submode) == MODE_INT
10746 && (GET_MODE (operands[0]) == CCZmode
10747 || pos + len < GET_MODE_PRECISION (submode)
10748 || REG_P (SUBREG_REG (val))))
10749 {
10750 val = SUBREG_REG (val);
10751 mode = submode;
10752 }
10753 }
10754
10755 /* Small HImode tests can be converted to QImode. */
10756 if (pos + len <= 8
10757 && register_operand (val, HImode))
10758 {
10759 rtx nval = gen_lowpart (QImode, val);
10760 if (!MEM_P (nval)
10761 || GET_MODE (operands[0]) == CCZmode
10762 || pos + len < 8)
10763 {
10764 val = nval;
10765 mode = QImode;
10766 }
10767 }
10768
10769 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
10770
10771 /* If the mask is going to have the sign bit set in the mode
10772 we want to do the comparison in and user isn't interested just
10773 in the zero flag, then we must widen the target mode. */
10774 if (pos + len == GET_MODE_PRECISION (mode)
10775 && GET_MODE (operands[0]) != CCZmode)
10776 {
10777 gcc_assert (pos + len < 32 && !MEM_P (val));
10778 mode = SImode;
10779 val = gen_lowpart (mode, val);
10780 }
10781
10782 wide_int mask
10783 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
10784
10785 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
10786 })
10787
10788 ;; Split and;cmp (as optimized by combine) into not;test
10789 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
10790 (define_insn_and_split "*test<mode>_not"
10791 [(set (reg:CCZ FLAGS_REG)
10792 (compare:CCZ
10793 (and:SWI
10794 (not:SWI (match_operand:SWI 0 "register_operand"))
10795 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
10796 (const_int 0)))]
10797 "ix86_pre_reload_split ()
10798 && (!TARGET_BMI || !REG_P (operands[1]))"
10799 "#"
10800 "&& 1"
10801 [(set (match_dup 2) (not:SWI (match_dup 0)))
10802 (set (reg:CCZ FLAGS_REG)
10803 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
10804 (const_int 0)))]
10805 "operands[2] = gen_reg_rtx (<MODE>mode);")
10806
10807 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
10808 (define_insn_and_split "*test<mode>_not_doubleword"
10809 [(set (reg:CCZ FLAGS_REG)
10810 (compare:CCZ
10811 (and:DWI
10812 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
10813 (match_operand:DWI 1 "nonimmediate_operand"))
10814 (const_int 0)))]
10815 "ix86_pre_reload_split ()"
10816 "#"
10817 "&& 1"
10818 [(parallel
10819 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
10820 (clobber (reg:CC FLAGS_REG))])
10821 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10822 {
10823 operands[0] = force_reg (<MODE>mode, operands[0]);
10824 operands[2] = gen_reg_rtx (<MODE>mode);
10825 })
10826
10827 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
10828 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
10829 ;; this is relatively important trick.
10830 ;; Do the conversion only post-reload to avoid limiting of the register class
10831 ;; to QI regs.
10832 (define_split
10833 [(set (match_operand 0 "flags_reg_operand")
10834 (match_operator 1 "compare_operator"
10835 [(and (match_operand 2 "QIreg_operand")
10836 (match_operand 3 "const_int_operand"))
10837 (const_int 0)]))]
10838 "reload_completed
10839 && GET_MODE (operands[2]) != QImode
10840 && ((ix86_match_ccmode (insn, CCZmode)
10841 && !(INTVAL (operands[3]) & ~(255 << 8)))
10842 || (ix86_match_ccmode (insn, CCNOmode)
10843 && !(INTVAL (operands[3]) & ~(127 << 8))))"
10844 [(set (match_dup 0)
10845 (match_op_dup 1
10846 [(and:QI
10847 (subreg:QI
10848 (zero_extract:HI (match_dup 2)
10849 (const_int 8)
10850 (const_int 8)) 0)
10851 (match_dup 3))
10852 (const_int 0)]))]
10853 {
10854 operands[2] = gen_lowpart (HImode, operands[2]);
10855 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
10856 })
10857
10858 (define_split
10859 [(set (match_operand 0 "flags_reg_operand")
10860 (match_operator 1 "compare_operator"
10861 [(and (match_operand 2 "nonimmediate_operand")
10862 (match_operand 3 "const_int_operand"))
10863 (const_int 0)]))]
10864 "reload_completed
10865 && GET_MODE (operands[2]) != QImode
10866 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
10867 && ((ix86_match_ccmode (insn, CCZmode)
10868 && !(INTVAL (operands[3]) & ~255))
10869 || (ix86_match_ccmode (insn, CCNOmode)
10870 && !(INTVAL (operands[3]) & ~127)))"
10871 [(set (match_dup 0)
10872 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
10873 (const_int 0)]))]
10874 {
10875 operands[2] = gen_lowpart (QImode, operands[2]);
10876 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
10877 })
10878
10879 ;; %%% This used to optimize known byte-wide and operations to memory,
10880 ;; and sometimes to QImode registers. If this is considered useful,
10881 ;; it should be done with splitters.
10882
10883 (define_expand "and<mode>3"
10884 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
10885 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
10886 (match_operand:SDWIM 2 "<general_szext_operand>")))]
10887 ""
10888 {
10889 machine_mode mode = <MODE>mode;
10890
10891 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
10892 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
10893 operands[2] = force_reg (<MODE>mode, operands[2]);
10894
10895 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
10896 && const_int_operand (operands[2], <MODE>mode)
10897 && register_operand (operands[0], <MODE>mode)
10898 && !(TARGET_ZERO_EXTEND_WITH_AND
10899 && optimize_function_for_speed_p (cfun)))
10900 {
10901 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
10902
10903 if (ival == GET_MODE_MASK (SImode))
10904 mode = SImode;
10905 else if (ival == GET_MODE_MASK (HImode))
10906 mode = HImode;
10907 else if (ival == GET_MODE_MASK (QImode))
10908 mode = QImode;
10909 }
10910
10911 if (mode != <MODE>mode)
10912 emit_insn (gen_extend_insn
10913 (operands[0], gen_lowpart (mode, operands[1]),
10914 <MODE>mode, mode, 1));
10915 else
10916 ix86_expand_binary_operator (AND, <MODE>mode, operands);
10917
10918 DONE;
10919 })
10920
10921 (define_insn_and_split "*and<dwi>3_doubleword"
10922 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
10923 (and:<DWI>
10924 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
10925 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
10926 (clobber (reg:CC FLAGS_REG))]
10927 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
10928 "#"
10929 "&& reload_completed"
10930 [(const_int:DWIH 0)]
10931 {
10932 bool emit_insn_deleted_note_p = false;
10933
10934 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
10935
10936 if (operands[2] == const0_rtx)
10937 emit_move_insn (operands[0], const0_rtx);
10938 else if (operands[2] == constm1_rtx)
10939 emit_insn_deleted_note_p = true;
10940 else
10941 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
10942
10943 if (operands[5] == const0_rtx)
10944 emit_move_insn (operands[3], const0_rtx);
10945 else if (operands[5] == constm1_rtx)
10946 {
10947 if (emit_insn_deleted_note_p)
10948 emit_note (NOTE_INSN_DELETED);
10949 }
10950 else
10951 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
10952
10953 DONE;
10954 })
10955
10956 (define_insn "*anddi_1"
10957 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
10958 (and:DI
10959 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
10960 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
10961 (clobber (reg:CC FLAGS_REG))]
10962 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
10963 "@
10964 and{l}\t{%k2, %k0|%k0, %k2}
10965 and{q}\t{%2, %0|%0, %2}
10966 and{q}\t{%2, %0|%0, %2}
10967 #
10968 #"
10969 [(set_attr "isa" "x64,x64,x64,x64,avx512bw")
10970 (set_attr "type" "alu,alu,alu,imovx,msklog")
10971 (set_attr "length_immediate" "*,*,*,0,*")
10972 (set (attr "prefix_rex")
10973 (if_then_else
10974 (and (eq_attr "type" "imovx")
10975 (and (match_test "INTVAL (operands[2]) == 0xff")
10976 (match_operand 1 "ext_QIreg_operand")))
10977 (const_string "1")
10978 (const_string "*")))
10979 (set_attr "mode" "SI,DI,DI,SI,DI")])
10980
10981 (define_insn_and_split "*anddi_1_btr"
10982 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10983 (and:DI
10984 (match_operand:DI 1 "nonimmediate_operand" "%0")
10985 (match_operand:DI 2 "const_int_operand" "n")))
10986 (clobber (reg:CC FLAGS_REG))]
10987 "TARGET_64BIT && TARGET_USE_BT
10988 && ix86_binary_operator_ok (AND, DImode, operands)
10989 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
10990 "#"
10991 "&& reload_completed"
10992 [(parallel [(set (zero_extract:DI (match_dup 0)
10993 (const_int 1)
10994 (match_dup 3))
10995 (const_int 0))
10996 (clobber (reg:CC FLAGS_REG))])]
10997 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
10998 [(set_attr "type" "alu1")
10999 (set_attr "prefix_0f" "1")
11000 (set_attr "znver1_decode" "double")
11001 (set_attr "mode" "DI")])
11002
11003 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11004 (define_split
11005 [(set (match_operand:DI 0 "register_operand")
11006 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11007 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11008 (clobber (reg:CC FLAGS_REG))]
11009 "TARGET_64BIT"
11010 [(parallel [(set (match_dup 0)
11011 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11012 (clobber (reg:CC FLAGS_REG))])]
11013 {
11014 if (GET_CODE (operands[2]) == SYMBOL_REF
11015 || GET_CODE (operands[2]) == LABEL_REF)
11016 {
11017 operands[2] = shallow_copy_rtx (operands[2]);
11018 PUT_MODE (operands[2], SImode);
11019 }
11020 else if (GET_CODE (operands[2]) == CONST)
11021 {
11022 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11023 operands[2] = copy_rtx (operands[2]);
11024 PUT_MODE (operands[2], SImode);
11025 PUT_MODE (XEXP (operands[2], 0), SImode);
11026 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11027 }
11028 else
11029 operands[2] = gen_lowpart (SImode, operands[2]);
11030 })
11031
11032 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11033 (define_insn "*andsi_1_zext"
11034 [(set (match_operand:DI 0 "register_operand" "=r")
11035 (zero_extend:DI
11036 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11037 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11038 (clobber (reg:CC FLAGS_REG))]
11039 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11040 "and{l}\t{%2, %k0|%k0, %2}"
11041 [(set_attr "type" "alu")
11042 (set_attr "mode" "SI")])
11043
11044 (define_insn "*and<mode>_1"
11045 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11046 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11047 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11048 (clobber (reg:CC FLAGS_REG))]
11049 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11050 "@
11051 and{<imodesuffix>}\t{%2, %0|%0, %2}
11052 and{<imodesuffix>}\t{%2, %0|%0, %2}
11053 #
11054 #"
11055 [(set (attr "isa")
11056 (cond [(eq_attr "alternative" "3")
11057 (if_then_else (eq_attr "mode" "SI")
11058 (const_string "avx512bw")
11059 (const_string "avx512f"))
11060 ]
11061 (const_string "*")))
11062 (set_attr "type" "alu,alu,imovx,msklog")
11063 (set_attr "length_immediate" "*,*,0,*")
11064 (set (attr "prefix_rex")
11065 (if_then_else
11066 (and (eq_attr "type" "imovx")
11067 (and (match_test "INTVAL (operands[2]) == 0xff")
11068 (match_operand 1 "ext_QIreg_operand")))
11069 (const_string "1")
11070 (const_string "*")))
11071 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11072
11073 (define_insn "*andqi_1"
11074 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11075 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11076 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11077 (clobber (reg:CC FLAGS_REG))]
11078 "ix86_binary_operator_ok (AND, QImode, operands)"
11079 "@
11080 and{b}\t{%2, %0|%0, %2}
11081 and{b}\t{%2, %0|%0, %2}
11082 and{l}\t{%k2, %k0|%k0, %k2}
11083 #"
11084 [(set_attr "type" "alu,alu,alu,msklog")
11085 (set (attr "mode")
11086 (cond [(eq_attr "alternative" "2")
11087 (const_string "SI")
11088 (and (eq_attr "alternative" "3")
11089 (match_test "!TARGET_AVX512DQ"))
11090 (const_string "HI")
11091 ]
11092 (const_string "QI")))
11093 ;; Potential partial reg stall on alternative 2.
11094 (set (attr "preferred_for_speed")
11095 (cond [(eq_attr "alternative" "2")
11096 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11097 (symbol_ref "true")))])
11098
11099 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11100 (define_insn_and_split "*and<mode>_1_slp"
11101 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11102 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11103 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11104 (clobber (reg:CC FLAGS_REG))]
11105 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11106 "@
11107 and{<imodesuffix>}\t{%2, %0|%0, %2}
11108 #"
11109 "&& reload_completed"
11110 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11111 (parallel
11112 [(set (strict_low_part (match_dup 0))
11113 (and:SWI12 (match_dup 0) (match_dup 2)))
11114 (clobber (reg:CC FLAGS_REG))])]
11115 ""
11116 [(set_attr "type" "alu")
11117 (set_attr "mode" "<MODE>")])
11118
11119 (define_split
11120 [(set (match_operand:SWI248 0 "register_operand")
11121 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11122 (match_operand:SWI248 2 "const_int_operand")))
11123 (clobber (reg:CC FLAGS_REG))]
11124 "reload_completed
11125 && (!REG_P (operands[1])
11126 || REGNO (operands[0]) != REGNO (operands[1]))"
11127 [(const_int 0)]
11128 {
11129 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11130 machine_mode mode;
11131
11132 if (ival == GET_MODE_MASK (SImode))
11133 mode = SImode;
11134 else if (ival == GET_MODE_MASK (HImode))
11135 mode = HImode;
11136 else if (ival == GET_MODE_MASK (QImode))
11137 mode = QImode;
11138 else
11139 gcc_unreachable ();
11140
11141 /* Zero extend to SImode to avoid partial register stalls. */
11142 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11143 operands[0] = gen_lowpart (SImode, operands[0]);
11144
11145 emit_insn (gen_extend_insn
11146 (operands[0], gen_lowpart (mode, operands[1]),
11147 GET_MODE (operands[0]), mode, 1));
11148 DONE;
11149 })
11150
11151 (define_split
11152 [(set (match_operand:SWI48 0 "register_operand")
11153 (and:SWI48 (match_dup 0)
11154 (const_int -65536)))
11155 (clobber (reg:CC FLAGS_REG))]
11156 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11157 || optimize_function_for_size_p (cfun)"
11158 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11159 "operands[1] = gen_lowpart (HImode, operands[0]);")
11160
11161 (define_split
11162 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11163 (and:SWI248 (match_dup 0)
11164 (const_int -256)))
11165 (clobber (reg:CC FLAGS_REG))]
11166 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11167 && reload_completed"
11168 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11169 "operands[1] = gen_lowpart (QImode, operands[0]);")
11170
11171 (define_split
11172 [(set (match_operand:SWI248 0 "QIreg_operand")
11173 (and:SWI248 (match_dup 0)
11174 (const_int -65281)))
11175 (clobber (reg:CC FLAGS_REG))]
11176 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11177 && reload_completed"
11178 [(parallel
11179 [(set (zero_extract:HI (match_dup 0)
11180 (const_int 8)
11181 (const_int 8))
11182 (subreg:HI
11183 (xor:QI
11184 (subreg:QI
11185 (zero_extract:HI (match_dup 0)
11186 (const_int 8)
11187 (const_int 8)) 0)
11188 (subreg:QI
11189 (zero_extract:HI (match_dup 0)
11190 (const_int 8)
11191 (const_int 8)) 0)) 0))
11192 (clobber (reg:CC FLAGS_REG))])]
11193 "operands[0] = gen_lowpart (HImode, operands[0]);")
11194
11195 (define_insn "*anddi_2"
11196 [(set (reg FLAGS_REG)
11197 (compare
11198 (and:DI
11199 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11200 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11201 (const_int 0)))
11202 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11203 (and:DI (match_dup 1) (match_dup 2)))]
11204 "TARGET_64BIT
11205 && ix86_match_ccmode
11206 (insn,
11207 /* If we are going to emit andl instead of andq, and the operands[2]
11208 constant might have the SImode sign bit set, make sure the sign
11209 flag isn't tested, because the instruction will set the sign flag
11210 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11211 conservatively assume it might have bit 31 set. */
11212 (satisfies_constraint_Z (operands[2])
11213 && (!CONST_INT_P (operands[2])
11214 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11215 ? CCZmode : CCNOmode)
11216 && ix86_binary_operator_ok (AND, DImode, operands)"
11217 "@
11218 and{l}\t{%k2, %k0|%k0, %k2}
11219 and{q}\t{%2, %0|%0, %2}
11220 and{q}\t{%2, %0|%0, %2}"
11221 [(set_attr "type" "alu")
11222 (set_attr "mode" "SI,DI,DI")])
11223
11224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11225 (define_insn "*andsi_2_zext"
11226 [(set (reg FLAGS_REG)
11227 (compare (and:SI
11228 (match_operand:SI 1 "nonimmediate_operand" "%0")
11229 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11230 (const_int 0)))
11231 (set (match_operand:DI 0 "register_operand" "=r")
11232 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11233 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11234 && ix86_binary_operator_ok (AND, SImode, operands)"
11235 "and{l}\t{%2, %k0|%k0, %2}"
11236 [(set_attr "type" "alu")
11237 (set_attr "mode" "SI")])
11238
11239 (define_insn "*andqi_2_maybe_si"
11240 [(set (reg FLAGS_REG)
11241 (compare (and:QI
11242 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11243 (match_operand:QI 2 "general_operand" "qn,m,n"))
11244 (const_int 0)))
11245 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11246 (and:QI (match_dup 1) (match_dup 2)))]
11247 "ix86_binary_operator_ok (AND, QImode, operands)
11248 && ix86_match_ccmode (insn,
11249 CONST_INT_P (operands[2])
11250 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11251 {
11252 if (get_attr_mode (insn) == MODE_SI)
11253 {
11254 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11255 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11256 return "and{l}\t{%2, %k0|%k0, %2}";
11257 }
11258 return "and{b}\t{%2, %0|%0, %2}";
11259 }
11260 [(set_attr "type" "alu")
11261 (set (attr "mode")
11262 (cond [(eq_attr "alternative" "2")
11263 (const_string "SI")
11264 (and (match_test "optimize_insn_for_size_p ()")
11265 (and (match_operand 0 "ext_QIreg_operand")
11266 (match_operand 2 "const_0_to_127_operand")))
11267 (const_string "SI")
11268 ]
11269 (const_string "QI")))
11270 ;; Potential partial reg stall on alternative 2.
11271 (set (attr "preferred_for_speed")
11272 (cond [(eq_attr "alternative" "2")
11273 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11274 (symbol_ref "true")))])
11275
11276 (define_insn "*and<mode>_2"
11277 [(set (reg FLAGS_REG)
11278 (compare (and:SWI124
11279 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11280 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11281 (const_int 0)))
11282 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11283 (and:SWI124 (match_dup 1) (match_dup 2)))]
11284 "ix86_match_ccmode (insn, CCNOmode)
11285 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11286 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11287 [(set_attr "type" "alu")
11288 (set_attr "mode" "<MODE>")])
11289
11290 (define_insn "*andqi_ext<mode>_0"
11291 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
11292 (and:QI
11293 (subreg:QI
11294 (match_operator:SWI248 3 "extract_operator"
11295 [(match_operand 2 "int248_register_operand" "Q,Q")
11296 (const_int 8)
11297 (const_int 8)]) 0)
11298 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
11299 (clobber (reg:CC FLAGS_REG))]
11300 ""
11301 "and{b}\t{%h2, %0|%0, %h2}"
11302 [(set_attr "isa" "*,nox64")
11303 (set_attr "type" "alu")
11304 (set_attr "mode" "QI")])
11305
11306 (define_expand "andqi_ext_1"
11307 [(parallel
11308 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11309 (const_int 8)
11310 (const_int 8))
11311 (subreg:HI
11312 (and:QI
11313 (subreg:QI
11314 (zero_extract:HI (match_operand:HI 1 "register_operand")
11315 (const_int 8)
11316 (const_int 8)) 0)
11317 (match_operand:QI 2 "const_int_operand")) 0))
11318 (clobber (reg:CC FLAGS_REG))])])
11319
11320 (define_insn "*andqi_ext<mode>_1"
11321 [(set (zero_extract:SWI248
11322 (match_operand 0 "int248_register_operand" "+Q,Q")
11323 (const_int 8)
11324 (const_int 8))
11325 (subreg:SWI248
11326 (and:QI
11327 (subreg:QI
11328 (match_operator:SWI248 3 "extract_operator"
11329 [(match_operand 1 "int248_register_operand" "0,0")
11330 (const_int 8)
11331 (const_int 8)]) 0)
11332 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
11333 (clobber (reg:CC FLAGS_REG))]
11334 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11335 rtx_equal_p (operands[0], operands[1])"
11336 "and{b}\t{%2, %h0|%h0, %2}"
11337 [(set_attr "isa" "*,nox64")
11338 (set_attr "type" "alu")
11339 (set_attr "mode" "QI")])
11340
11341 ;; Generated by peephole translating test to and. This shows up
11342 ;; often in fp comparisons.
11343 (define_insn "*andqi_ext<mode>_1_cc"
11344 [(set (reg FLAGS_REG)
11345 (compare
11346 (and:QI
11347 (subreg:QI
11348 (match_operator:SWI248 3 "extract_operator"
11349 [(match_operand 1 "int248_register_operand" "0,0")
11350 (const_int 8)
11351 (const_int 8)]) 0)
11352 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
11353 (const_int 0)))
11354 (set (zero_extract:SWI248
11355 (match_operand 0 "int248_register_operand" "+Q,Q")
11356 (const_int 8)
11357 (const_int 8))
11358 (subreg:SWI248
11359 (and:QI
11360 (subreg:QI
11361 (match_op_dup 3
11362 [(match_dup 1)
11363 (const_int 8)
11364 (const_int 8)]) 0)
11365 (match_dup 2)) 0))]
11366 "ix86_match_ccmode (insn, CCNOmode)
11367 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11368 && rtx_equal_p (operands[0], operands[1])"
11369 "and{b}\t{%2, %h0|%h0, %2}"
11370 [(set_attr "isa" "*,nox64")
11371 (set_attr "type" "alu")
11372 (set_attr "mode" "QI")])
11373
11374 (define_insn "*andqi_ext<mode>_2"
11375 [(set (zero_extract:SWI248
11376 (match_operand 0 "int248_register_operand" "+Q")
11377 (const_int 8)
11378 (const_int 8))
11379 (subreg:SWI248
11380 (and:QI
11381 (subreg:QI
11382 (match_operator:SWI248 3 "extract_operator"
11383 [(match_operand 1 "int248_register_operand" "%0")
11384 (const_int 8)
11385 (const_int 8)]) 0)
11386 (subreg:QI
11387 (match_operator:SWI248 4 "extract_operator"
11388 [(match_operand 2 "int248_register_operand" "Q")
11389 (const_int 8)
11390 (const_int 8)]) 0)) 0))
11391 (clobber (reg:CC FLAGS_REG))]
11392 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11393 rtx_equal_p (operands[0], operands[1])
11394 || rtx_equal_p (operands[0], operands[2])"
11395 "and{b}\t{%h2, %h0|%h0, %h2}"
11396 [(set_attr "type" "alu")
11397 (set_attr "mode" "QI")])
11398
11399 ;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
11400
11401 ;; Convert wide AND instructions with immediate operand to shorter QImode
11402 ;; equivalents when possible.
11403 ;; Don't do the splitting with memory operands, since it introduces risk
11404 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
11405 ;; for size, but that can (should?) be handled by generic code instead.
11406 (define_split
11407 [(set (match_operand:SWI248 0 "QIreg_operand")
11408 (and:SWI248 (match_operand:SWI248 1 "register_operand")
11409 (match_operand:SWI248 2 "const_int_operand")))
11410 (clobber (reg:CC FLAGS_REG))]
11411 "reload_completed
11412 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11413 && !(~INTVAL (operands[2]) & ~(255 << 8))"
11414 [(parallel
11415 [(set (zero_extract:HI (match_dup 0)
11416 (const_int 8)
11417 (const_int 8))
11418 (subreg:HI
11419 (and:QI
11420 (subreg:QI
11421 (zero_extract:HI (match_dup 1)
11422 (const_int 8)
11423 (const_int 8)) 0)
11424 (match_dup 2)) 0))
11425 (clobber (reg:CC FLAGS_REG))])]
11426 {
11427 operands[0] = gen_lowpart (HImode, operands[0]);
11428 operands[1] = gen_lowpart (HImode, operands[1]);
11429 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11430 })
11431
11432 ;; Since AND can be encoded with sign extended immediate, this is only
11433 ;; profitable when 7th bit is not set.
11434 (define_split
11435 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11436 (and:SWI248 (match_operand:SWI248 1 "general_operand")
11437 (match_operand:SWI248 2 "const_int_operand")))
11438 (clobber (reg:CC FLAGS_REG))]
11439 "reload_completed
11440 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11441 && !(~INTVAL (operands[2]) & ~255)
11442 && !(INTVAL (operands[2]) & 128)"
11443 [(parallel [(set (strict_low_part (match_dup 0))
11444 (and:QI (match_dup 1)
11445 (match_dup 2)))
11446 (clobber (reg:CC FLAGS_REG))])]
11447 {
11448 operands[0] = gen_lowpart (QImode, operands[0]);
11449 operands[1] = gen_lowpart (QImode, operands[1]);
11450 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11451 })
11452
11453 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11454 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11455 (and:<DWI>
11456 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11457 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11458 (clobber (reg:CC FLAGS_REG))]
11459 "TARGET_BMI"
11460 "#"
11461 "&& reload_completed"
11462 [(parallel [(set (match_dup 0)
11463 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11464 (clobber (reg:CC FLAGS_REG))])
11465 (parallel [(set (match_dup 3)
11466 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11467 (clobber (reg:CC FLAGS_REG))])]
11468 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11469
11470 (define_insn_and_split "*andn<mode>3_doubleword"
11471 [(set (match_operand:DWI 0 "register_operand")
11472 (and:DWI
11473 (not:DWI (match_operand:DWI 1 "register_operand"))
11474 (match_operand:DWI 2 "nonimmediate_operand")))
11475 (clobber (reg:CC FLAGS_REG))]
11476 "!TARGET_BMI
11477 && ix86_pre_reload_split ()"
11478 "#"
11479 "&& 1"
11480 [(set (match_dup 3) (not:DWI (match_dup 1)))
11481 (parallel [(set (match_dup 0)
11482 (and:DWI (match_dup 3) (match_dup 2)))
11483 (clobber (reg:CC FLAGS_REG))])]
11484 "operands[3] = gen_reg_rtx (<MODE>mode);")
11485
11486 (define_insn "*andn<mode>_1"
11487 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11488 (and:SWI48
11489 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11490 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11491 (clobber (reg:CC FLAGS_REG))]
11492 "TARGET_BMI || TARGET_AVX512BW"
11493 "@
11494 andn\t{%2, %1, %0|%0, %1, %2}
11495 andn\t{%2, %1, %0|%0, %1, %2}
11496 #"
11497 [(set_attr "isa" "bmi,bmi,avx512bw")
11498 (set_attr "type" "bitmanip,bitmanip,msklog")
11499 (set_attr "btver2_decode" "direct, double,*")
11500 (set_attr "mode" "<MODE>")])
11501
11502 (define_insn "*andn<mode>_1"
11503 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11504 (and:SWI12
11505 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11506 (match_operand:SWI12 2 "register_operand" "r,k")))
11507 (clobber (reg:CC FLAGS_REG))]
11508 "TARGET_BMI || TARGET_AVX512BW"
11509 "@
11510 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
11511 #"
11512 [(set_attr "isa" "bmi,avx512f")
11513 (set_attr "type" "bitmanip,msklog")
11514 (set_attr "btver2_decode" "direct,*")
11515 (set (attr "mode")
11516 (cond [(eq_attr "alternative" "0")
11517 (const_string "SI")
11518 (and (eq_attr "alternative" "1")
11519 (match_test "!TARGET_AVX512DQ"))
11520 (const_string "HI")
11521 ]
11522 (const_string "<MODE>")))])
11523
11524 (define_insn "*andn_<mode>_ccno"
11525 [(set (reg FLAGS_REG)
11526 (compare
11527 (and:SWI48
11528 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
11529 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
11530 (const_int 0)))
11531 (clobber (match_scratch:SWI48 0 "=r,r"))]
11532 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
11533 "andn\t{%2, %1, %0|%0, %1, %2}"
11534 [(set_attr "type" "bitmanip")
11535 (set_attr "btver2_decode" "direct, double")
11536 (set_attr "mode" "<MODE>")])
11537
11538 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
11539 (define_split
11540 [(set (match_operand:SI 0 "register_operand")
11541 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
11542 (match_operand:SI 2 "nonimmediate_operand")))
11543 (clobber (reg:CC FLAGS_REG))]
11544 "reload_completed
11545 && optimize_insn_for_size_p () && optimize_size > 1
11546 && REGNO (operands[0]) == REGNO (operands[1])
11547 && LEGACY_INT_REG_P (operands[0])
11548 && !REX_INT_REG_P (operands[2])
11549 && !reg_overlap_mentioned_p (operands[0], operands[2])"
11550 [(set (match_dup 0) (not:SI (match_dup 1)))
11551 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
11552 (clobber (reg:CC FLAGS_REG))])])
11553
11554 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
11555 (define_split
11556 [(set (match_operand 0 "flags_reg_operand")
11557 (match_operator 1 "compare_operator"
11558 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
11559 (match_operand:SI 3 "nonimmediate_operand"))
11560 (const_int 0)]))
11561 (clobber (match_dup 2))]
11562 "reload_completed
11563 && optimize_insn_for_size_p () && optimize_size > 1
11564 && LEGACY_INT_REG_P (operands[2])
11565 && !REX_INT_REG_P (operands[3])
11566 && !reg_overlap_mentioned_p (operands[2], operands[3])"
11567 [(set (match_dup 2) (not:SI (match_dup 2)))
11568 (set (match_dup 0) (match_op_dup 1
11569 [(and:SI (match_dup 3) (match_dup 2))
11570 (const_int 0)]))])
11571
11572 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
11573 (define_split
11574 [(set (match_operand:SWI48 0 "register_operand")
11575 (xor:SWI48
11576 (xor:SWI48
11577 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11578 (match_operand:SWI48 2 "nonimmediate_operand"))
11579 (match_dup 1))
11580 (match_operand:SWI48 3 "nonimmediate_operand")))
11581 (clobber (reg:CC FLAGS_REG))]
11582 "TARGET_BMI"
11583 [(parallel
11584 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11585 (clobber (reg:CC FLAGS_REG))])
11586 (parallel
11587 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11588 (clobber (reg:CC FLAGS_REG))])]
11589 "operands[4] = gen_reg_rtx (<MODE>mode);")
11590
11591 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
11592 (define_split
11593 [(set (match_operand:SWI48 0 "register_operand")
11594 (xor:SWI48
11595 (xor:SWI48
11596 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11597 (match_operand:SWI48 2 "register_operand"))
11598 (match_dup 2))
11599 (match_operand:SWI48 3 "nonimmediate_operand")))
11600 (clobber (reg:CC FLAGS_REG))]
11601 "TARGET_BMI"
11602 [(parallel
11603 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11604 (clobber (reg:CC FLAGS_REG))])
11605 (parallel
11606 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11607 (clobber (reg:CC FLAGS_REG))])]
11608 "operands[4] = gen_reg_rtx (<MODE>mode);")
11609
11610 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
11611 (define_split
11612 [(set (match_operand:SWI48 0 "register_operand")
11613 (xor:SWI48
11614 (xor:SWI48
11615 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11616 (match_operand:SWI48 2 "nonimmediate_operand"))
11617 (match_operand:SWI48 3 "nonimmediate_operand"))
11618 (match_dup 1)))
11619 (clobber (reg:CC FLAGS_REG))]
11620 "TARGET_BMI"
11621 [(parallel
11622 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11623 (clobber (reg:CC FLAGS_REG))])
11624 (parallel
11625 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11626 (clobber (reg:CC FLAGS_REG))])]
11627 "operands[4] = gen_reg_rtx (<MODE>mode);")
11628
11629 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
11630 (define_split
11631 [(set (match_operand:SWI48 0 "register_operand")
11632 (xor:SWI48
11633 (xor:SWI48
11634 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11635 (match_operand:SWI48 2 "register_operand"))
11636 (match_operand:SWI48 3 "nonimmediate_operand"))
11637 (match_dup 2)))
11638 (clobber (reg:CC FLAGS_REG))]
11639 "TARGET_BMI"
11640 [(parallel
11641 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11642 (clobber (reg:CC FLAGS_REG))])
11643 (parallel
11644 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11645 (clobber (reg:CC FLAGS_REG))])]
11646 "operands[4] = gen_reg_rtx (<MODE>mode);")
11647 \f
11648 ;; Logical inclusive and exclusive OR instructions
11649
11650 ;; %%% This used to optimize known byte-wide and operations to memory.
11651 ;; If this is considered useful, it should be done with splitters.
11652
11653 (define_expand "<code><mode>3"
11654 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11655 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11656 (match_operand:SDWIM 2 "<general_operand>")))]
11657 ""
11658 {
11659 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11660 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11661 operands[2] = force_reg (<MODE>mode, operands[2]);
11662
11663 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
11664 DONE;
11665 })
11666
11667 (define_insn_and_split "*<code><dwi>3_doubleword"
11668 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11669 (any_or:<DWI>
11670 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11671 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11672 (clobber (reg:CC FLAGS_REG))]
11673 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
11674 "#"
11675 "&& reload_completed"
11676 [(const_int:DWIH 0)]
11677 {
11678 /* This insn may disappear completely when operands[2] == const0_rtx
11679 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
11680 bool emit_insn_deleted_note_p = false;
11681
11682 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11683
11684 if (operands[2] == const0_rtx)
11685 emit_insn_deleted_note_p = true;
11686 else if (operands[2] == constm1_rtx)
11687 {
11688 if (<CODE> == IOR)
11689 emit_move_insn (operands[0], constm1_rtx);
11690 else
11691 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
11692 }
11693 else
11694 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
11695
11696 if (operands[5] == const0_rtx)
11697 {
11698 if (emit_insn_deleted_note_p)
11699 emit_note (NOTE_INSN_DELETED);
11700 }
11701 else if (operands[5] == constm1_rtx)
11702 {
11703 if (<CODE> == IOR)
11704 emit_move_insn (operands[3], constm1_rtx);
11705 else
11706 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
11707 }
11708 else
11709 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
11710
11711 DONE;
11712 })
11713
11714 (define_insn "*<code><mode>_1"
11715 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11716 (any_or:SWI248
11717 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11718 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
11719 (clobber (reg:CC FLAGS_REG))]
11720 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11721 "@
11722 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11723 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11724 #"
11725 [(set (attr "isa")
11726 (cond [(eq_attr "alternative" "2")
11727 (if_then_else (eq_attr "mode" "SI,DI")
11728 (const_string "avx512bw")
11729 (const_string "avx512f"))
11730 ]
11731 (const_string "*")))
11732 (set_attr "type" "alu, alu, msklog")
11733 (set_attr "mode" "<MODE>")])
11734
11735 (define_insn_and_split "*notxor<mode>_1"
11736 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11737 (not:SWI248
11738 (xor:SWI248
11739 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11740 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
11741 (clobber (reg:CC FLAGS_REG))]
11742 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
11743 "#"
11744 "&& reload_completed"
11745 [(parallel
11746 [(set (match_dup 0)
11747 (xor:SWI248 (match_dup 1) (match_dup 2)))
11748 (clobber (reg:CC FLAGS_REG))])
11749 (set (match_dup 0)
11750 (not:SWI248 (match_dup 0)))]
11751 {
11752 if (MASK_REG_P (operands[0]))
11753 {
11754 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
11755 DONE;
11756 }
11757 }
11758 [(set (attr "isa")
11759 (cond [(eq_attr "alternative" "2")
11760 (if_then_else (eq_attr "mode" "SI,DI")
11761 (const_string "avx512bw")
11762 (const_string "avx512f"))
11763 ]
11764 (const_string "*")))
11765 (set_attr "type" "alu, alu, msklog")
11766 (set_attr "mode" "<MODE>")])
11767
11768 (define_insn_and_split "*iordi_1_bts"
11769 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11770 (ior:DI
11771 (match_operand:DI 1 "nonimmediate_operand" "%0")
11772 (match_operand:DI 2 "const_int_operand" "n")))
11773 (clobber (reg:CC FLAGS_REG))]
11774 "TARGET_64BIT && TARGET_USE_BT
11775 && ix86_binary_operator_ok (IOR, DImode, operands)
11776 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
11777 "#"
11778 "&& reload_completed"
11779 [(parallel [(set (zero_extract:DI (match_dup 0)
11780 (const_int 1)
11781 (match_dup 3))
11782 (const_int 1))
11783 (clobber (reg:CC FLAGS_REG))])]
11784 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
11785 [(set_attr "type" "alu1")
11786 (set_attr "prefix_0f" "1")
11787 (set_attr "znver1_decode" "double")
11788 (set_attr "mode" "DI")])
11789
11790 (define_insn_and_split "*xordi_1_btc"
11791 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11792 (xor:DI
11793 (match_operand:DI 1 "nonimmediate_operand" "%0")
11794 (match_operand:DI 2 "const_int_operand" "n")))
11795 (clobber (reg:CC FLAGS_REG))]
11796 "TARGET_64BIT && TARGET_USE_BT
11797 && ix86_binary_operator_ok (XOR, DImode, operands)
11798 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
11799 "#"
11800 "&& reload_completed"
11801 [(parallel [(set (zero_extract:DI (match_dup 0)
11802 (const_int 1)
11803 (match_dup 3))
11804 (not:DI (zero_extract:DI (match_dup 0)
11805 (const_int 1)
11806 (match_dup 3))))
11807 (clobber (reg:CC FLAGS_REG))])]
11808 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
11809 [(set_attr "type" "alu1")
11810 (set_attr "prefix_0f" "1")
11811 (set_attr "znver1_decode" "double")
11812 (set_attr "mode" "DI")])
11813
11814 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
11815 (define_insn_and_split "*xor2andn"
11816 [(set (match_operand:SWI248 0 "register_operand")
11817 (xor:SWI248
11818 (and:SWI248
11819 (xor:SWI248
11820 (match_operand:SWI248 1 "nonimmediate_operand")
11821 (match_operand:SWI248 2 "nonimmediate_operand"))
11822 (match_operand:SWI248 3 "nonimmediate_operand"))
11823 (match_dup 1)))
11824 (clobber (reg:CC FLAGS_REG))]
11825 "TARGET_BMI && ix86_pre_reload_split ()"
11826 "#"
11827 "&& 1"
11828 [(parallel [(set (match_dup 4)
11829 (and:SWI248
11830 (not:SWI248
11831 (match_dup 3))
11832 (match_dup 1)))
11833 (clobber (reg:CC FLAGS_REG))])
11834 (parallel [(set (match_dup 5)
11835 (and:SWI248
11836 (match_dup 3)
11837 (match_dup 2)))
11838 (clobber (reg:CC FLAGS_REG))])
11839 (parallel [(set (match_dup 0)
11840 (ior:SWI248
11841 (match_dup 4)
11842 (match_dup 5)))
11843 (clobber (reg:CC FLAGS_REG))])]
11844 {
11845 operands[1] = force_reg (<MODE>mode, operands[1]);
11846 operands[3] = force_reg (<MODE>mode, operands[3]);
11847 operands[4] = gen_reg_rtx (<MODE>mode);
11848 operands[5] = gen_reg_rtx (<MODE>mode);
11849 })
11850
11851 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11852 (define_insn "*<code>si_1_zext"
11853 [(set (match_operand:DI 0 "register_operand" "=r")
11854 (zero_extend:DI
11855 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11856 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11857 (clobber (reg:CC FLAGS_REG))]
11858 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11859 "<logic>{l}\t{%2, %k0|%k0, %2}"
11860 [(set_attr "type" "alu")
11861 (set_attr "mode" "SI")])
11862
11863 (define_insn "*<code>si_1_zext_imm"
11864 [(set (match_operand:DI 0 "register_operand" "=r")
11865 (any_or:DI
11866 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
11867 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
11868 (clobber (reg:CC FLAGS_REG))]
11869 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11870 "<logic>{l}\t{%2, %k0|%k0, %2}"
11871 [(set_attr "type" "alu")
11872 (set_attr "mode" "SI")])
11873
11874 (define_insn "*<code>qi_1"
11875 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11876 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11877 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11878 (clobber (reg:CC FLAGS_REG))]
11879 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
11880 "@
11881 <logic>{b}\t{%2, %0|%0, %2}
11882 <logic>{b}\t{%2, %0|%0, %2}
11883 <logic>{l}\t{%k2, %k0|%k0, %k2}
11884 #"
11885 [(set_attr "isa" "*,*,*,avx512f")
11886 (set_attr "type" "alu,alu,alu,msklog")
11887 (set (attr "mode")
11888 (cond [(eq_attr "alternative" "2")
11889 (const_string "SI")
11890 (and (eq_attr "alternative" "3")
11891 (match_test "!TARGET_AVX512DQ"))
11892 (const_string "HI")
11893 ]
11894 (const_string "QI")))
11895 ;; Potential partial reg stall on alternative 2.
11896 (set (attr "preferred_for_speed")
11897 (cond [(eq_attr "alternative" "2")
11898 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11899 (symbol_ref "true")))])
11900
11901 (define_insn_and_split "*notxorqi_1"
11902 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11903 (not:QI
11904 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11905 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
11906 (clobber (reg:CC FLAGS_REG))]
11907 "ix86_binary_operator_ok (XOR, QImode, operands)"
11908 "#"
11909 "&& reload_completed"
11910 [(parallel
11911 [(set (match_dup 0)
11912 (xor:QI (match_dup 1) (match_dup 2)))
11913 (clobber (reg:CC FLAGS_REG))])
11914 (set (match_dup 0)
11915 (not:QI (match_dup 0)))]
11916 {
11917 if (mask_reg_operand (operands[0], QImode))
11918 {
11919 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
11920 DONE;
11921 }
11922 }
11923 [(set_attr "isa" "*,*,*,avx512f")
11924 (set_attr "type" "alu,alu,alu,msklog")
11925 (set (attr "mode")
11926 (cond [(eq_attr "alternative" "2")
11927 (const_string "SI")
11928 (and (eq_attr "alternative" "3")
11929 (match_test "!TARGET_AVX512DQ"))
11930 (const_string "HI")
11931 ]
11932 (const_string "QI")))
11933 ;; Potential partial reg stall on alternative 2.
11934 (set (attr "preferred_for_speed")
11935 (cond [(eq_attr "alternative" "2")
11936 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11937 (symbol_ref "true")))])
11938
11939 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11940 (define_insn_and_split "*<code><mode>_1_slp"
11941 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11942 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11943 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11944 (clobber (reg:CC FLAGS_REG))]
11945 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11946 "@
11947 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11948 #"
11949 "&& reload_completed"
11950 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11951 (parallel
11952 [(set (strict_low_part (match_dup 0))
11953 (any_or:SWI12 (match_dup 0) (match_dup 2)))
11954 (clobber (reg:CC FLAGS_REG))])]
11955 ""
11956 [(set_attr "type" "alu")
11957 (set_attr "mode" "<MODE>")])
11958
11959 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
11960 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
11961 ;; This eliminates sign extension after logic operation.
11962
11963 (define_split
11964 [(set (match_operand:SWI248 0 "register_operand")
11965 (sign_extend:SWI248
11966 (any_logic:QI (match_operand:QI 1 "memory_operand")
11967 (match_operand:QI 2 "const_int_operand"))))]
11968 ""
11969 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
11970 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
11971 "operands[3] = gen_reg_rtx (<MODE>mode);")
11972
11973 (define_split
11974 [(set (match_operand:SWI48 0 "register_operand")
11975 (sign_extend:SWI48
11976 (any_logic:HI (match_operand:HI 1 "memory_operand")
11977 (match_operand:HI 2 "const_int_operand"))))]
11978 ""
11979 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
11980 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
11981 "operands[3] = gen_reg_rtx (<MODE>mode);")
11982
11983 (define_split
11984 [(set (match_operand:DI 0 "register_operand")
11985 (sign_extend:DI
11986 (any_logic:SI (match_operand:SI 1 "memory_operand")
11987 (match_operand:SI 2 "const_int_operand"))))]
11988 "TARGET_64BIT"
11989 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
11990 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
11991 "operands[3] = gen_reg_rtx (DImode);")
11992
11993 (define_insn "*<code><mode>_2"
11994 [(set (reg FLAGS_REG)
11995 (compare (any_or:SWI
11996 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
11997 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
11998 (const_int 0)))
11999 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12000 (any_or:SWI (match_dup 1) (match_dup 2)))]
12001 "ix86_match_ccmode (insn, CCNOmode)
12002 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12003 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12004 [(set_attr "type" "alu")
12005 (set_attr "mode" "<MODE>")])
12006
12007 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12008 ;; ??? Special case for immediate operand is missing - it is tricky.
12009 (define_insn "*<code>si_2_zext"
12010 [(set (reg FLAGS_REG)
12011 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12012 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12013 (const_int 0)))
12014 (set (match_operand:DI 0 "register_operand" "=r")
12015 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12016 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12017 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12018 "<logic>{l}\t{%2, %k0|%k0, %2}"
12019 [(set_attr "type" "alu")
12020 (set_attr "mode" "SI")])
12021
12022 (define_insn "*<code>si_2_zext_imm"
12023 [(set (reg FLAGS_REG)
12024 (compare (any_or:SI
12025 (match_operand:SI 1 "nonimmediate_operand" "%0")
12026 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12027 (const_int 0)))
12028 (set (match_operand:DI 0 "register_operand" "=r")
12029 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12030 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12031 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12032 "<logic>{l}\t{%2, %k0|%k0, %2}"
12033 [(set_attr "type" "alu")
12034 (set_attr "mode" "SI")])
12035
12036 (define_insn "*<code><mode>_3"
12037 [(set (reg FLAGS_REG)
12038 (compare (any_or:SWI
12039 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12040 (match_operand:SWI 2 "<general_operand>" "<g>"))
12041 (const_int 0)))
12042 (clobber (match_scratch:SWI 0 "=<r>"))]
12043 "ix86_match_ccmode (insn, CCNOmode)
12044 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12045 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12046 [(set_attr "type" "alu")
12047 (set_attr "mode" "<MODE>")])
12048
12049 (define_insn "*<code>qi_ext<mode>_0"
12050 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
12051 (any_or:QI
12052 (subreg:QI
12053 (match_operator:SWI248 3 "extract_operator"
12054 [(match_operand 2 "int248_register_operand" "Q,Q")
12055 (const_int 8)
12056 (const_int 8)]) 0)
12057 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
12058 (clobber (reg:CC FLAGS_REG))]
12059 ""
12060 "<logic>{b}\t{%h2, %0|%0, %h2}"
12061 [(set_attr "isa" "*,nox64")
12062 (set_attr "type" "alu")
12063 (set_attr "mode" "QI")])
12064
12065 (define_insn "*<code>qi_ext<mode>_1"
12066 [(set (zero_extract:SWI248
12067 (match_operand 0 "int248_register_operand" "+Q,Q")
12068 (const_int 8)
12069 (const_int 8))
12070 (subreg:SWI248
12071 (any_or:QI
12072 (subreg:QI
12073 (match_operator:SWI248 3 "extract_operator"
12074 [(match_operand 1 "int248_register_operand" "0,0")
12075 (const_int 8)
12076 (const_int 8)]) 0)
12077 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
12078 (clobber (reg:CC FLAGS_REG))]
12079 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12080 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12081 && rtx_equal_p (operands[0], operands[1])"
12082 "<logic>{b}\t{%2, %h0|%h0, %2}"
12083 [(set_attr "isa" "*,nox64")
12084 (set_attr "type" "alu")
12085 (set_attr "mode" "QI")])
12086
12087 (define_insn "*<code>qi_ext<mode>_2"
12088 [(set (zero_extract:SWI248
12089 (match_operand 0 "int248_register_operand" "+Q")
12090 (const_int 8)
12091 (const_int 8))
12092 (subreg:SWI248
12093 (any_or:QI
12094 (subreg:QI
12095 (match_operator:SWI248 3 "extract_operator"
12096 [(match_operand 1 "int248_register_operand" "%0")
12097 (const_int 8)
12098 (const_int 8)]) 0)
12099 (subreg:QI
12100 (match_operator:SWI248 4 "extract_operator"
12101 [(match_operand 2 "int248_register_operand" "Q")
12102 (const_int 8)
12103 (const_int 8)]) 0)) 0))
12104 (clobber (reg:CC FLAGS_REG))]
12105 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12106 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12107 && (rtx_equal_p (operands[0], operands[1])
12108 || rtx_equal_p (operands[0], operands[2]))"
12109 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12110 [(set_attr "type" "alu")
12111 (set_attr "mode" "QI")])
12112
12113 (define_insn "*<code>qi_ext<mode>_3"
12114 [(set (zero_extract:SWI248
12115 (match_operand 0 "int248_register_operand" "+Q")
12116 (const_int 8)
12117 (const_int 8))
12118 (zero_extract:SWI248
12119 (any_logic:SWI248
12120 (match_operand 1 "int248_register_operand" "%0")
12121 (match_operand 2 "int248_register_operand" "Q"))
12122 (const_int 8)
12123 (const_int 8)))
12124 (clobber (reg:CC FLAGS_REG))]
12125 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12126 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12127 && (rtx_equal_p (operands[0], operands[1])
12128 || rtx_equal_p (operands[0], operands[2]))"
12129 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12130 [(set_attr "type" "alu")
12131 (set_attr "mode" "QI")])
12132
12133 ;; Convert wide OR instructions with immediate operand to shorter QImode
12134 ;; equivalents when possible.
12135 ;; Don't do the splitting with memory operands, since it introduces risk
12136 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12137 ;; for size, but that can (should?) be handled by generic code instead.
12138 (define_split
12139 [(set (match_operand:SWI248 0 "QIreg_operand")
12140 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12141 (match_operand:SWI248 2 "const_int_operand")))
12142 (clobber (reg:CC FLAGS_REG))]
12143 "reload_completed
12144 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12145 && !(INTVAL (operands[2]) & ~(255 << 8))"
12146 [(parallel
12147 [(set (zero_extract:HI (match_dup 0)
12148 (const_int 8)
12149 (const_int 8))
12150 (subreg:HI
12151 (any_or:QI
12152 (subreg:QI
12153 (zero_extract:HI (match_dup 1)
12154 (const_int 8)
12155 (const_int 8)) 0)
12156 (match_dup 2)) 0))
12157 (clobber (reg:CC FLAGS_REG))])]
12158 {
12159 /* Handle the case where INTVAL (operands[2]) == 0. */
12160 if (operands[2] == const0_rtx)
12161 {
12162 if (!rtx_equal_p (operands[0], operands[1]))
12163 emit_move_insn (operands[0], operands[1]);
12164 else
12165 emit_note (NOTE_INSN_DELETED);
12166 DONE;
12167 }
12168 operands[0] = gen_lowpart (HImode, operands[0]);
12169 operands[1] = gen_lowpart (HImode, operands[1]);
12170 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12171 })
12172
12173 ;; Since OR can be encoded with sign extended immediate, this is only
12174 ;; profitable when 7th bit is set.
12175 (define_split
12176 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12177 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12178 (match_operand:SWI248 2 "const_int_operand")))
12179 (clobber (reg:CC FLAGS_REG))]
12180 "reload_completed
12181 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12182 && !(INTVAL (operands[2]) & ~255)
12183 && (INTVAL (operands[2]) & 128)"
12184 [(parallel [(set (strict_low_part (match_dup 0))
12185 (any_or:QI (match_dup 1)
12186 (match_dup 2)))
12187 (clobber (reg:CC FLAGS_REG))])]
12188 {
12189 operands[0] = gen_lowpart (QImode, operands[0]);
12190 operands[1] = gen_lowpart (QImode, operands[1]);
12191 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12192 })
12193
12194 (define_expand "xorqi_ext_1_cc"
12195 [(parallel
12196 [(set (reg:CCNO FLAGS_REG)
12197 (compare:CCNO
12198 (xor:QI
12199 (subreg:QI
12200 (zero_extract:HI (match_operand:HI 1 "register_operand")
12201 (const_int 8)
12202 (const_int 8)) 0)
12203 (match_operand:QI 2 "const_int_operand"))
12204 (const_int 0)))
12205 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12206 (const_int 8)
12207 (const_int 8))
12208 (subreg:HI
12209 (xor:QI
12210 (subreg:QI
12211 (zero_extract:HI (match_dup 1)
12212 (const_int 8)
12213 (const_int 8)) 0)
12214 (match_dup 2)) 0))])])
12215
12216 (define_insn "*xorqi_ext<mode>_1_cc"
12217 [(set (reg FLAGS_REG)
12218 (compare
12219 (xor:QI
12220 (subreg:QI
12221 (match_operator:SWI248 3 "extract_operator"
12222 [(match_operand 1 "int248_register_operand" "0,0")
12223 (const_int 8)
12224 (const_int 8)]) 0)
12225 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
12226 (const_int 0)))
12227 (set (zero_extract:SWI248
12228 (match_operand 0 "int248_register_operand" "+Q,Q")
12229 (const_int 8)
12230 (const_int 8))
12231 (subreg:SWI248
12232 (xor:QI
12233 (subreg:QI
12234 (match_op_dup 3
12235 [(match_dup 1)
12236 (const_int 8)
12237 (const_int 8)]) 0)
12238 (match_dup 2)) 0))]
12239 "ix86_match_ccmode (insn, CCNOmode)
12240 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12241 && rtx_equal_p (operands[0], operands[1])"
12242 "xor{b}\t{%2, %h0|%h0, %2}"
12243 [(set_attr "isa" "*,nox64")
12244 (set_attr "type" "alu")
12245 (set_attr "mode" "QI")])
12246
12247 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12248 (define_peephole2
12249 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12250 (const_int 0))
12251 (clobber (reg:CC FLAGS_REG))])
12252 (parallel [(set (match_dup 0)
12253 (any_or_plus:SWI (match_dup 0)
12254 (match_operand:SWI 1 "<general_operand>")))
12255 (clobber (reg:CC FLAGS_REG))])]
12256 ""
12257 [(set (match_dup 0) (match_dup 1))])
12258
12259 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12260 (define_insn_and_split "*concat<mode><dwi>3_1"
12261 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12262 (any_or_plus:<DWI>
12263 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12264 (match_operand:QI 2 "const_int_operand"))
12265 (zero_extend:<DWI>
12266 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12267 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12268 "#"
12269 "&& reload_completed"
12270 [(const_int 0)]
12271 {
12272 split_double_concat (<DWI>mode, operands[0], operands[3],
12273 gen_lowpart (<MODE>mode, operands[1]));
12274 DONE;
12275 })
12276
12277 (define_insn_and_split "*concat<mode><dwi>3_2"
12278 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12279 (any_or_plus:<DWI>
12280 (zero_extend:<DWI>
12281 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12282 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12283 (match_operand:QI 3 "const_int_operand"))))]
12284 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12285 "#"
12286 "&& reload_completed"
12287 [(const_int 0)]
12288 {
12289 split_double_concat (<DWI>mode, operands[0], operands[1],
12290 gen_lowpart (<MODE>mode, operands[2]));
12291 DONE;
12292 })
12293
12294 (define_insn_and_split "*concat<mode><dwi>3_3"
12295 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12296 (any_or_plus:<DWI>
12297 (ashift:<DWI>
12298 (zero_extend:<DWI>
12299 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12300 (match_operand:QI 2 "const_int_operand"))
12301 (zero_extend:<DWI>
12302 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m"))))]
12303 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12304 "#"
12305 "&& reload_completed"
12306 [(const_int 0)]
12307 {
12308 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12309 DONE;
12310 })
12311
12312 (define_insn_and_split "*concat<mode><dwi>3_4"
12313 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12314 (any_or_plus:<DWI>
12315 (zero_extend:<DWI>
12316 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12317 (ashift:<DWI>
12318 (zero_extend:<DWI>
12319 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12320 (match_operand:QI 3 "const_int_operand"))))]
12321 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12322 "#"
12323 "&& reload_completed"
12324 [(const_int 0)]
12325 {
12326 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12327 DONE;
12328 })
12329
12330 (define_insn_and_split "*concat<half><mode>3_5"
12331 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12332 (any_or_plus:DWI
12333 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12334 (match_operand:QI 2 "const_int_operand"))
12335 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12336 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12337 && (<MODE>mode == DImode
12338 ? CONST_INT_P (operands[3])
12339 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12340 : CONST_INT_P (operands[3])
12341 ? INTVAL (operands[3]) >= 0
12342 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12343 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12344 && !(CONST_INT_P (operands[3])
12345 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12346 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12347 0)),
12348 VOIDmode))"
12349 "#"
12350 "&& reload_completed"
12351 [(const_int 0)]
12352 {
12353 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12354 split_double_concat (<MODE>mode, operands[0], op3,
12355 gen_lowpart (<HALF>mode, operands[1]));
12356 DONE;
12357 }
12358 [(set_attr "isa" "*,nox64,x64")])
12359
12360 (define_insn_and_split "*concat<mode><dwi>3_6"
12361 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12362 (any_or_plus:<DWI>
12363 (ashift:<DWI>
12364 (zero_extend:<DWI>
12365 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12366 (match_operand:QI 2 "const_int_operand"))
12367 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12368 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12369 && (<DWI>mode == DImode
12370 ? CONST_INT_P (operands[3])
12371 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12372 : CONST_INT_P (operands[3])
12373 ? INTVAL (operands[3]) >= 0
12374 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12375 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12376 && !(CONST_INT_P (operands[3])
12377 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12378 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12379 0)),
12380 VOIDmode))"
12381 "#"
12382 "&& reload_completed"
12383 [(const_int 0)]
12384 {
12385 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12386 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12387 DONE;
12388 }
12389 [(set_attr "isa" "*,nox64,x64,*")])
12390
12391 (define_insn_and_split "*concat<mode><dwi>3_7"
12392 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12393 (any_or_plus:<DWI>
12394 (zero_extend:<DWI>
12395 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12396 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12397 "<DWI>mode == DImode
12398 ? CONST_INT_P (operands[2])
12399 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12400 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12401 : CONST_WIDE_INT_P (operands[2])
12402 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12403 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12404 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12405 1)),
12406 VOIDmode)"
12407 "#"
12408 "&& reload_completed"
12409 [(const_int 0)]
12410 {
12411 rtx op2;
12412 if (<DWI>mode == DImode)
12413 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12414 else
12415 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12416 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12417 DONE;
12418 }
12419 [(set_attr "isa" "*,nox64,x64,*")])
12420 \f
12421 ;; Negation instructions
12422
12423 (define_expand "neg<mode>2"
12424 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12425 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12426 ""
12427 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12428
12429 (define_insn_and_split "*neg<dwi>2_doubleword"
12430 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12431 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12432 (clobber (reg:CC FLAGS_REG))]
12433 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12434 "#"
12435 "&& reload_completed"
12436 [(parallel
12437 [(set (reg:CCC FLAGS_REG)
12438 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12439 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12440 (parallel
12441 [(set (match_dup 2)
12442 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12443 (match_dup 3))
12444 (const_int 0)))
12445 (clobber (reg:CC FLAGS_REG))])
12446 (parallel
12447 [(set (match_dup 2)
12448 (neg:DWIH (match_dup 2)))
12449 (clobber (reg:CC FLAGS_REG))])]
12450 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12451
12452 ;; Convert:
12453 ;; mov %esi, %edx
12454 ;; negl %eax
12455 ;; adcl $0, %edx
12456 ;; negl %edx
12457 ;; to:
12458 ;; xorl %edx, %edx
12459 ;; negl %eax
12460 ;; sbbl %esi, %edx
12461
12462 (define_peephole2
12463 [(set (match_operand:SWI48 0 "general_reg_operand")
12464 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12465 (parallel
12466 [(set (reg:CCC FLAGS_REG)
12467 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12468 (const_int 0)] UNSPEC_CC_NE))
12469 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12470 (parallel
12471 [(set (match_dup 0)
12472 (plus:SWI48 (plus:SWI48
12473 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12474 (match_dup 0))
12475 (const_int 0)))
12476 (clobber (reg:CC FLAGS_REG))])
12477 (parallel
12478 [(set (match_dup 0)
12479 (neg:SWI48 (match_dup 0)))
12480 (clobber (reg:CC FLAGS_REG))])]
12481 "REGNO (operands[0]) != REGNO (operands[2])
12482 && !reg_mentioned_p (operands[0], operands[1])
12483 && !reg_mentioned_p (operands[2], operands[1])"
12484 [(parallel
12485 [(set (reg:CCC FLAGS_REG)
12486 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12487 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12488 (parallel
12489 [(set (match_dup 0)
12490 (minus:SWI48 (minus:SWI48
12491 (match_dup 0)
12492 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12493 (match_dup 1)))
12494 (clobber (reg:CC FLAGS_REG))])]
12495 "ix86_expand_clear (operands[0]);")
12496
12497 ;; Convert:
12498 ;; xorl %edx, %edx
12499 ;; negl %eax
12500 ;; adcl $0, %edx
12501 ;; negl %edx
12502 ;; to:
12503 ;; negl %eax
12504 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12505
12506 (define_peephole2
12507 [(parallel
12508 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12509 (clobber (reg:CC FLAGS_REG))])
12510 (parallel
12511 [(set (reg:CCC FLAGS_REG)
12512 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12513 (const_int 0)] UNSPEC_CC_NE))
12514 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12515 (parallel
12516 [(set (match_dup 0)
12517 (plus:SWI48 (plus:SWI48
12518 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12519 (match_dup 0))
12520 (const_int 0)))
12521 (clobber (reg:CC FLAGS_REG))])
12522 (parallel
12523 [(set (match_dup 0)
12524 (neg:SWI48 (match_dup 0)))
12525 (clobber (reg:CC FLAGS_REG))])]
12526 "REGNO (operands[0]) != REGNO (operands[1])"
12527 [(parallel
12528 [(set (reg:CCC FLAGS_REG)
12529 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12530 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12531 (parallel
12532 [(set (match_dup 0)
12533 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12534 (const_int -1)
12535 (const_int 0)))
12536 (clobber (reg:CC FLAGS_REG))])])
12537
12538 (define_insn "*neg<mode>_1"
12539 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12540 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12541 (clobber (reg:CC FLAGS_REG))]
12542 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12543 "neg{<imodesuffix>}\t%0"
12544 [(set_attr "type" "negnot")
12545 (set_attr "mode" "<MODE>")])
12546
12547 (define_insn "*negsi_1_zext"
12548 [(set (match_operand:DI 0 "register_operand" "=r")
12549 (zero_extend:DI
12550 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12551 (clobber (reg:CC FLAGS_REG))]
12552 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12553 "neg{l}\t%k0"
12554 [(set_attr "type" "negnot")
12555 (set_attr "mode" "SI")])
12556
12557 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12558 (define_insn_and_split "*neg<mode>_1_slp"
12559 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12560 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12561 (clobber (reg:CC FLAGS_REG))]
12562 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12563 "@
12564 neg{<imodesuffix>}\t%0
12565 #"
12566 "&& reload_completed"
12567 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12568 (parallel
12569 [(set (strict_low_part (match_dup 0))
12570 (neg:SWI12 (match_dup 0)))
12571 (clobber (reg:CC FLAGS_REG))])]
12572 ""
12573 [(set_attr "type" "negnot")
12574 (set_attr "mode" "<MODE>")])
12575
12576 (define_insn "*neg<mode>_2"
12577 [(set (reg FLAGS_REG)
12578 (compare
12579 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12580 (const_int 0)))
12581 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12582 (neg:SWI (match_dup 1)))]
12583 "ix86_match_ccmode (insn, CCGOCmode)
12584 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12585 "neg{<imodesuffix>}\t%0"
12586 [(set_attr "type" "negnot")
12587 (set_attr "mode" "<MODE>")])
12588
12589 (define_insn "*negsi_2_zext"
12590 [(set (reg FLAGS_REG)
12591 (compare
12592 (neg:SI (match_operand:SI 1 "register_operand" "0"))
12593 (const_int 0)))
12594 (set (match_operand:DI 0 "register_operand" "=r")
12595 (zero_extend:DI
12596 (neg:SI (match_dup 1))))]
12597 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12598 && ix86_unary_operator_ok (NEG, SImode, operands)"
12599 "neg{l}\t%k0"
12600 [(set_attr "type" "negnot")
12601 (set_attr "mode" "SI")])
12602
12603 (define_insn "*neg<mode>_ccc_1"
12604 [(set (reg:CCC FLAGS_REG)
12605 (unspec:CCC
12606 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12607 (const_int 0)] UNSPEC_CC_NE))
12608 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12609 (neg:SWI (match_dup 1)))]
12610 ""
12611 "neg{<imodesuffix>}\t%0"
12612 [(set_attr "type" "negnot")
12613 (set_attr "mode" "<MODE>")])
12614
12615 (define_insn "*neg<mode>_ccc_2"
12616 [(set (reg:CCC FLAGS_REG)
12617 (unspec:CCC
12618 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12619 (const_int 0)] UNSPEC_CC_NE))
12620 (clobber (match_scratch:SWI 0 "=<r>"))]
12621 ""
12622 "neg{<imodesuffix>}\t%0"
12623 [(set_attr "type" "negnot")
12624 (set_attr "mode" "<MODE>")])
12625
12626 (define_expand "x86_neg<mode>_ccc"
12627 [(parallel
12628 [(set (reg:CCC FLAGS_REG)
12629 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12630 (const_int 0)] UNSPEC_CC_NE))
12631 (set (match_operand:SWI48 0 "register_operand")
12632 (neg:SWI48 (match_dup 1)))])])
12633
12634 (define_insn "*negqi_ext<mode>_2"
12635 [(set (zero_extract:SWI248
12636 (match_operand 0 "int248_register_operand" "+Q")
12637 (const_int 8)
12638 (const_int 8))
12639 (subreg:SWI248
12640 (neg:QI
12641 (subreg:QI
12642 (match_operator:SWI248 2 "extract_operator"
12643 [(match_operand 1 "int248_register_operand" "0")
12644 (const_int 8)
12645 (const_int 8)]) 0)) 0))
12646 (clobber (reg:CC FLAGS_REG))]
12647 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
12648 rtx_equal_p (operands[0], operands[1])"
12649 "neg{b}\t%h0"
12650 [(set_attr "type" "negnot")
12651 (set_attr "mode" "QI")])
12652
12653 ;; Negate with jump on overflow.
12654 (define_expand "negv<mode>3"
12655 [(parallel [(set (reg:CCO FLAGS_REG)
12656 (unspec:CCO
12657 [(match_operand:SWI 1 "register_operand")
12658 (match_dup 3)] UNSPEC_CC_NE))
12659 (set (match_operand:SWI 0 "register_operand")
12660 (neg:SWI (match_dup 1)))])
12661 (set (pc) (if_then_else
12662 (eq (reg:CCO FLAGS_REG) (const_int 0))
12663 (label_ref (match_operand 2))
12664 (pc)))]
12665 ""
12666 {
12667 operands[3]
12668 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
12669 <MODE>mode);
12670 })
12671
12672 (define_insn "*negv<mode>3"
12673 [(set (reg:CCO FLAGS_REG)
12674 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
12675 (match_operand:SWI 2 "const_int_operand")]
12676 UNSPEC_CC_NE))
12677 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12678 (neg:SWI (match_dup 1)))]
12679 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
12680 && mode_signbit_p (<MODE>mode, operands[2])"
12681 "neg{<imodesuffix>}\t%0"
12682 [(set_attr "type" "negnot")
12683 (set_attr "mode" "<MODE>")])
12684
12685 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
12686 (define_peephole2
12687 [(set (match_operand:SWI 0 "general_reg_operand")
12688 (match_operand:SWI 1 "general_reg_operand"))
12689 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
12690 (clobber (reg:CC FLAGS_REG))])
12691 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
12692 ""
12693 [(set (match_dup 0) (match_dup 1))
12694 (parallel [(set (reg:CCZ FLAGS_REG)
12695 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
12696 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
12697
12698 ;; Special expand pattern to handle integer mode abs
12699
12700 (define_expand "abs<mode>2"
12701 [(parallel
12702 [(set (match_operand:SDWIM 0 "register_operand")
12703 (abs:SDWIM
12704 (match_operand:SDWIM 1 "general_operand")))
12705 (clobber (reg:CC FLAGS_REG))])]
12706 "TARGET_CMOVE
12707 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
12708 {
12709 if (TARGET_EXPAND_ABS)
12710 {
12711 machine_mode mode = <MODE>mode;
12712 operands[1] = force_reg (mode, operands[1]);
12713
12714 /* Generate rtx abs using:
12715 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
12716
12717 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
12718 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
12719 shift_amount, NULL_RTX,
12720 0, OPTAB_DIRECT);
12721 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
12722 operands[0], 0, OPTAB_DIRECT);
12723 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
12724 operands[0], 0, OPTAB_DIRECT);
12725 if (!rtx_equal_p (minus_dst, operands[0]))
12726 emit_move_insn (operands[0], minus_dst);
12727 DONE;
12728 }
12729 })
12730
12731 (define_insn_and_split "*abs<dwi>2_doubleword"
12732 [(set (match_operand:<DWI> 0 "register_operand")
12733 (abs:<DWI>
12734 (match_operand:<DWI> 1 "general_operand")))
12735 (clobber (reg:CC FLAGS_REG))]
12736 "TARGET_CMOVE
12737 && ix86_pre_reload_split ()"
12738 "#"
12739 "&& 1"
12740 [(parallel
12741 [(set (reg:CCC FLAGS_REG)
12742 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12743 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12744 (parallel
12745 [(set (match_dup 5)
12746 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12747 (match_dup 4))
12748 (const_int 0)))
12749 (clobber (reg:CC FLAGS_REG))])
12750 (parallel
12751 [(set (reg:CCGOC FLAGS_REG)
12752 (compare:CCGOC
12753 (neg:DWIH (match_dup 5))
12754 (const_int 0)))
12755 (set (match_dup 5)
12756 (neg:DWIH (match_dup 5)))])
12757 (set (match_dup 0)
12758 (if_then_else:DWIH
12759 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12760 (match_dup 2)
12761 (match_dup 1)))
12762 (set (match_dup 3)
12763 (if_then_else:DWIH
12764 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12765 (match_dup 5)
12766 (match_dup 4)))]
12767 {
12768 operands[1] = force_reg (<DWI>mode, operands[1]);
12769 operands[2] = gen_reg_rtx (<DWI>mode);
12770
12771 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12772 })
12773
12774 (define_insn_and_split "*nabs<dwi>2_doubleword"
12775 [(set (match_operand:<DWI> 0 "register_operand")
12776 (neg:<DWI>
12777 (abs:<DWI>
12778 (match_operand:<DWI> 1 "general_operand"))))
12779 (clobber (reg:CC FLAGS_REG))]
12780 "TARGET_CMOVE
12781 && ix86_pre_reload_split ()"
12782 "#"
12783 "&& 1"
12784 [(parallel
12785 [(set (reg:CCC FLAGS_REG)
12786 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12787 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12788 (parallel
12789 [(set (match_dup 5)
12790 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12791 (match_dup 4))
12792 (const_int 0)))
12793 (clobber (reg:CC FLAGS_REG))])
12794 (parallel
12795 [(set (reg:CCGOC FLAGS_REG)
12796 (compare:CCGOC
12797 (neg:DWIH (match_dup 5))
12798 (const_int 0)))
12799 (set (match_dup 5)
12800 (neg:DWIH (match_dup 5)))])
12801 (set (match_dup 0)
12802 (if_then_else:DWIH
12803 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12804 (match_dup 2)
12805 (match_dup 1)))
12806 (set (match_dup 3)
12807 (if_then_else:DWIH
12808 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12809 (match_dup 5)
12810 (match_dup 4)))]
12811 {
12812 operands[1] = force_reg (<DWI>mode, operands[1]);
12813 operands[2] = gen_reg_rtx (<DWI>mode);
12814
12815 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12816 })
12817
12818 (define_insn_and_split "*abs<mode>2_1"
12819 [(set (match_operand:SWI 0 "register_operand")
12820 (abs:SWI
12821 (match_operand:SWI 1 "general_operand")))
12822 (clobber (reg:CC FLAGS_REG))]
12823 "TARGET_CMOVE
12824 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
12825 && ix86_pre_reload_split ()"
12826 "#"
12827 "&& 1"
12828 [(parallel
12829 [(set (reg:CCGOC FLAGS_REG)
12830 (compare:CCGOC
12831 (neg:SWI (match_dup 1))
12832 (const_int 0)))
12833 (set (match_dup 2)
12834 (neg:SWI (match_dup 1)))])
12835 (set (match_dup 0)
12836 (if_then_else:SWI
12837 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12838 (match_dup 2)
12839 (match_dup 1)))]
12840 {
12841 operands[1] = force_reg (<MODE>mode, operands[1]);
12842 operands[2] = gen_reg_rtx (<MODE>mode);
12843 })
12844
12845 (define_insn_and_split "*nabs<mode>2_1"
12846 [(set (match_operand:SWI 0 "register_operand")
12847 (neg:SWI
12848 (abs:SWI
12849 (match_operand:SWI 1 "general_operand"))))
12850 (clobber (reg:CC FLAGS_REG))]
12851 "TARGET_CMOVE
12852 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
12853 && ix86_pre_reload_split ()"
12854 "#"
12855 "&& 1"
12856 [(parallel
12857 [(set (reg:CCGOC FLAGS_REG)
12858 (compare:CCGOC
12859 (neg:SWI (match_dup 1))
12860 (const_int 0)))
12861 (set (match_dup 2)
12862 (neg:SWI (match_dup 1)))])
12863 (set (match_dup 0)
12864 (if_then_else:SWI
12865 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12866 (match_dup 2)
12867 (match_dup 1)))]
12868 {
12869 operands[1] = force_reg (<MODE>mode, operands[1]);
12870 operands[2] = gen_reg_rtx (<MODE>mode);
12871 })
12872
12873 (define_expand "<code>tf2"
12874 [(set (match_operand:TF 0 "register_operand")
12875 (absneg:TF (match_operand:TF 1 "register_operand")))]
12876 "TARGET_SSE"
12877 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
12878
12879 (define_insn_and_split "*<code>tf2_1"
12880 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
12881 (absneg:TF
12882 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
12883 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
12884 "TARGET_SSE"
12885 "#"
12886 "&& reload_completed"
12887 [(set (match_dup 0)
12888 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
12889 {
12890 if (TARGET_AVX)
12891 {
12892 if (MEM_P (operands[1]))
12893 std::swap (operands[1], operands[2]);
12894 }
12895 else
12896 {
12897 if (operands_match_p (operands[0], operands[2]))
12898 std::swap (operands[1], operands[2]);
12899 }
12900 }
12901 [(set_attr "isa" "noavx,noavx,avx,avx")])
12902
12903 (define_insn_and_split "*nabstf2_1"
12904 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
12905 (neg:TF
12906 (abs:TF
12907 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
12908 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
12909 "TARGET_SSE"
12910 "#"
12911 "&& reload_completed"
12912 [(set (match_dup 0)
12913 (ior:TF (match_dup 1) (match_dup 2)))]
12914 {
12915 if (TARGET_AVX)
12916 {
12917 if (MEM_P (operands[1]))
12918 std::swap (operands[1], operands[2]);
12919 }
12920 else
12921 {
12922 if (operands_match_p (operands[0], operands[2]))
12923 std::swap (operands[1], operands[2]);
12924 }
12925 }
12926 [(set_attr "isa" "noavx,noavx,avx,avx")])
12927
12928 (define_expand "<code>hf2"
12929 [(set (match_operand:HF 0 "register_operand")
12930 (absneg:HF (match_operand:HF 1 "register_operand")))]
12931 "TARGET_AVX512FP16"
12932 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
12933
12934 (define_expand "<code><mode>2"
12935 [(set (match_operand:X87MODEF 0 "register_operand")
12936 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
12937 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12938 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
12939
12940 ;; Changing of sign for FP values is doable using integer unit too.
12941 (define_insn "*<code><mode>2_i387_1"
12942 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
12943 (absneg:X87MODEF
12944 (match_operand:X87MODEF 1 "register_operand" "0,0")))
12945 (clobber (reg:CC FLAGS_REG))]
12946 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12947 "#")
12948
12949 (define_split
12950 [(set (match_operand:X87MODEF 0 "fp_register_operand")
12951 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
12952 (clobber (reg:CC FLAGS_REG))]
12953 "TARGET_80387 && reload_completed"
12954 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
12955
12956 (define_split
12957 [(set (match_operand:X87MODEF 0 "general_reg_operand")
12958 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
12959 (clobber (reg:CC FLAGS_REG))]
12960 "TARGET_80387 && reload_completed"
12961 [(const_int 0)]
12962 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
12963
12964 (define_insn_and_split "*<code>hf2_1"
12965 [(set (match_operand:HF 0 "register_operand" "=Yv")
12966 (absneg:HF
12967 (match_operand:HF 1 "register_operand" "Yv")))
12968 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
12969 (clobber (reg:CC FLAGS_REG))]
12970 "TARGET_AVX512FP16"
12971 "#"
12972 "&& reload_completed"
12973 [(set (match_dup 0)
12974 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
12975 {
12976 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
12977 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
12978 })
12979
12980 (define_insn "*<code><mode>2_1"
12981 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
12982 (absneg:MODEF
12983 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
12984 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
12985 (clobber (reg:CC FLAGS_REG))]
12986 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12987 "#"
12988 [(set_attr "isa" "noavx,noavx,avx,*,*")
12989 (set (attr "enabled")
12990 (if_then_else
12991 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
12992 (if_then_else
12993 (eq_attr "alternative" "3,4")
12994 (symbol_ref "TARGET_MIX_SSE_I387")
12995 (const_string "*"))
12996 (if_then_else
12997 (eq_attr "alternative" "3,4")
12998 (symbol_ref "true")
12999 (symbol_ref "false"))))])
13000
13001 (define_split
13002 [(set (match_operand:MODEF 0 "sse_reg_operand")
13003 (absneg:MODEF
13004 (match_operand:MODEF 1 "sse_reg_operand")))
13005 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13006 (clobber (reg:CC FLAGS_REG))]
13007 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13008 && reload_completed"
13009 [(set (match_dup 0)
13010 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13011 {
13012 machine_mode mode = <MODE>mode;
13013 machine_mode vmode = <ssevecmodef>mode;
13014
13015 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13016 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13017
13018 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13019 std::swap (operands[1], operands[2]);
13020 })
13021
13022 (define_split
13023 [(set (match_operand:MODEF 0 "fp_register_operand")
13024 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13025 (use (match_operand 2))
13026 (clobber (reg:CC FLAGS_REG))]
13027 "TARGET_80387 && reload_completed"
13028 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13029
13030 (define_split
13031 [(set (match_operand:MODEF 0 "general_reg_operand")
13032 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13033 (use (match_operand 2))
13034 (clobber (reg:CC FLAGS_REG))]
13035 "TARGET_80387 && reload_completed"
13036 [(const_int 0)]
13037 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13038
13039 (define_insn_and_split "*nabs<mode>2_1"
13040 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13041 (neg:MODEF
13042 (abs:MODEF
13043 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13044 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13045 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13046 "#"
13047 "&& reload_completed"
13048 [(set (match_dup 0)
13049 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13050 {
13051 machine_mode mode = <MODE>mode;
13052 machine_mode vmode = <ssevecmodef>mode;
13053
13054 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13055 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13056
13057 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13058 std::swap (operands[1], operands[2]);
13059 }
13060 [(set_attr "isa" "noavx,noavx,avx")])
13061
13062 ;; Conditionalize these after reload. If they match before reload, we
13063 ;; lose the clobber and ability to use integer instructions.
13064
13065 (define_insn "*<code><mode>2_i387"
13066 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13067 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13068 "TARGET_80387 && reload_completed"
13069 "<absneg_mnemonic>"
13070 [(set_attr "type" "fsgn")
13071 (set_attr "mode" "<MODE>")])
13072
13073 ;; Copysign instructions
13074
13075 (define_expand "copysign<mode>3"
13076 [(match_operand:SSEMODEF 0 "register_operand")
13077 (match_operand:SSEMODEF 1 "nonmemory_operand")
13078 (match_operand:SSEMODEF 2 "register_operand")]
13079 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13080 || (TARGET_SSE && (<MODE>mode == TFmode))
13081 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13082 "ix86_expand_copysign (operands); DONE;")
13083
13084 (define_expand "xorsign<mode>3"
13085 [(match_operand:MODEFH 0 "register_operand")
13086 (match_operand:MODEFH 1 "register_operand")
13087 (match_operand:MODEFH 2 "register_operand")]
13088 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13089 || <MODE>mode == HFmode"
13090 {
13091 if (rtx_equal_p (operands[1], operands[2]))
13092 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13093 else
13094 ix86_expand_xorsign (operands);
13095 DONE;
13096 })
13097 \f
13098 ;; One complement instructions
13099
13100 (define_expand "one_cmpl<mode>2"
13101 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13102 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13103 ""
13104 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13105
13106 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13107 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13108 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13109 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13110 "#"
13111 "&& reload_completed"
13112 [(set (match_dup 0)
13113 (not:DWIH (match_dup 1)))
13114 (set (match_dup 2)
13115 (not:DWIH (match_dup 3)))]
13116 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13117
13118 (define_insn "*one_cmpl<mode>2_1"
13119 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13120 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13121 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13122 "@
13123 not{<imodesuffix>}\t%0
13124 #"
13125 [(set (attr "isa")
13126 (cond [(eq_attr "alternative" "1")
13127 (if_then_else (eq_attr "mode" "SI,DI")
13128 (const_string "avx512bw")
13129 (const_string "avx512f"))
13130 ]
13131 (const_string "*")))
13132 (set_attr "type" "negnot,msklog")
13133 (set_attr "mode" "<MODE>")])
13134
13135 (define_insn "*one_cmplsi2_1_zext"
13136 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13137 (zero_extend:DI
13138 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13139 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13140 "@
13141 not{l}\t%k0
13142 #"
13143 [(set_attr "isa" "x64,avx512bw")
13144 (set_attr "type" "negnot,msklog")
13145 (set_attr "mode" "SI,SI")])
13146
13147 (define_insn "*one_cmplqi2_1"
13148 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13149 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13150 "ix86_unary_operator_ok (NOT, QImode, operands)"
13151 "@
13152 not{b}\t%0
13153 not{l}\t%k0
13154 #"
13155 [(set_attr "isa" "*,*,avx512f")
13156 (set_attr "type" "negnot,negnot,msklog")
13157 (set (attr "mode")
13158 (cond [(eq_attr "alternative" "1")
13159 (const_string "SI")
13160 (and (eq_attr "alternative" "2")
13161 (match_test "!TARGET_AVX512DQ"))
13162 (const_string "HI")
13163 ]
13164 (const_string "QI")))
13165 ;; Potential partial reg stall on alternative 1.
13166 (set (attr "preferred_for_speed")
13167 (cond [(eq_attr "alternative" "1")
13168 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13169 (symbol_ref "true")))])
13170
13171 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13172 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13173 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13174 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13175 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13176 "@
13177 not{<imodesuffix>}\t%0
13178 #"
13179 "&& reload_completed"
13180 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13181 (set (strict_low_part (match_dup 0))
13182 (not:SWI12 (match_dup 0)))]
13183 ""
13184 [(set_attr "type" "negnot")
13185 (set_attr "mode" "<MODE>")])
13186
13187 (define_insn "*one_cmpl<mode>2_2"
13188 [(set (reg FLAGS_REG)
13189 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13190 (const_int 0)))
13191 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13192 (not:SWI (match_dup 1)))]
13193 "ix86_match_ccmode (insn, CCNOmode)
13194 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13195 "#"
13196 [(set_attr "type" "alu1")
13197 (set_attr "mode" "<MODE>")])
13198
13199 (define_split
13200 [(set (match_operand 0 "flags_reg_operand")
13201 (match_operator 2 "compare_operator"
13202 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13203 (const_int 0)]))
13204 (set (match_operand:SWI 1 "nonimmediate_operand")
13205 (not:SWI (match_dup 3)))]
13206 "ix86_match_ccmode (insn, CCNOmode)"
13207 [(parallel [(set (match_dup 0)
13208 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13209 (const_int 0)]))
13210 (set (match_dup 1)
13211 (xor:SWI (match_dup 3) (const_int -1)))])])
13212
13213 (define_insn "*one_cmplsi2_2_zext"
13214 [(set (reg FLAGS_REG)
13215 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13216 (const_int 0)))
13217 (set (match_operand:DI 0 "register_operand" "=r")
13218 (zero_extend:DI (not:SI (match_dup 1))))]
13219 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13220 && ix86_unary_operator_ok (NOT, SImode, operands)"
13221 "#"
13222 [(set_attr "type" "alu1")
13223 (set_attr "mode" "SI")])
13224
13225 (define_split
13226 [(set (match_operand 0 "flags_reg_operand")
13227 (match_operator 2 "compare_operator"
13228 [(not:SI (match_operand:SI 3 "register_operand"))
13229 (const_int 0)]))
13230 (set (match_operand:DI 1 "register_operand")
13231 (zero_extend:DI (not:SI (match_dup 3))))]
13232 "ix86_match_ccmode (insn, CCNOmode)"
13233 [(parallel [(set (match_dup 0)
13234 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13235 (const_int 0)]))
13236 (set (match_dup 1)
13237 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13238 \f
13239 ;; Shift instructions
13240
13241 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13242 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13243 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13244 ;; from the assembler input.
13245 ;;
13246 ;; This instruction shifts the target reg/mem as usual, but instead of
13247 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13248 ;; is a left shift double, bits are taken from the high order bits of
13249 ;; reg, else if the insn is a shift right double, bits are taken from the
13250 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13251 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13252 ;;
13253 ;; Since sh[lr]d does not change the `reg' operand, that is done
13254 ;; separately, making all shifts emit pairs of shift double and normal
13255 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13256 ;; support a 63 bit shift, each shift where the count is in a reg expands
13257 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13258 ;;
13259 ;; If the shift count is a constant, we need never emit more than one
13260 ;; shift pair, instead using moves and sign extension for counts greater
13261 ;; than 31.
13262
13263 (define_expand "ashl<mode>3"
13264 [(set (match_operand:SDWIM 0 "<shift_operand>")
13265 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13266 (match_operand:QI 2 "nonmemory_operand")))]
13267 ""
13268 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13269
13270 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13271 [(set (match_operand:<DWI> 0 "register_operand")
13272 (ashift:<DWI>
13273 (match_operand:<DWI> 1 "register_operand")
13274 (subreg:QI
13275 (and
13276 (match_operand 2 "int248_register_operand" "c")
13277 (match_operand 3 "const_int_operand")) 0)))
13278 (clobber (reg:CC FLAGS_REG))]
13279 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13280 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13281 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13282 && ix86_pre_reload_split ()"
13283 "#"
13284 "&& 1"
13285 [(parallel
13286 [(set (match_dup 6)
13287 (ior:DWIH (ashift:DWIH (match_dup 6)
13288 (and:QI (match_dup 2) (match_dup 8)))
13289 (subreg:DWIH
13290 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13291 (minus:QI (match_dup 9)
13292 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13293 (clobber (reg:CC FLAGS_REG))])
13294 (parallel
13295 [(set (match_dup 4)
13296 (ashift:DWIH (match_dup 5) (match_dup 2)))
13297 (clobber (reg:CC FLAGS_REG))])]
13298 {
13299 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13300 {
13301 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13302 operands[2] = gen_lowpart (QImode, operands[2]);
13303 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13304 operands[2]));
13305 DONE;
13306 }
13307
13308 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13309
13310 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13311 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13312
13313 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13314 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13315 {
13316 rtx xops[3];
13317 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13318 xops[1] = operands[2];
13319 xops[2] = GEN_INT (INTVAL (operands[3])
13320 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13321 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13322 operands[2] = xops[0];
13323 }
13324
13325 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13326 operands[2] = gen_lowpart (QImode, operands[2]);
13327
13328 if (!rtx_equal_p (operands[6], operands[7]))
13329 emit_move_insn (operands[6], operands[7]);
13330 })
13331
13332 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13333 [(set (match_operand:<DWI> 0 "register_operand")
13334 (ashift:<DWI>
13335 (match_operand:<DWI> 1 "register_operand")
13336 (and:QI
13337 (match_operand:QI 2 "register_operand" "c")
13338 (match_operand:QI 3 "const_int_operand"))))
13339 (clobber (reg:CC FLAGS_REG))]
13340 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13341 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13342 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13343 && ix86_pre_reload_split ()"
13344 "#"
13345 "&& 1"
13346 [(parallel
13347 [(set (match_dup 6)
13348 (ior:DWIH (ashift:DWIH (match_dup 6)
13349 (and:QI (match_dup 2) (match_dup 8)))
13350 (subreg:DWIH
13351 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13352 (minus:QI (match_dup 9)
13353 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13354 (clobber (reg:CC FLAGS_REG))])
13355 (parallel
13356 [(set (match_dup 4)
13357 (ashift:DWIH (match_dup 5) (match_dup 2)))
13358 (clobber (reg:CC FLAGS_REG))])]
13359 {
13360 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13361 {
13362 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13363 operands[2]));
13364 DONE;
13365 }
13366
13367 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13368
13369 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13370 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13371
13372 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13373 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13374 {
13375 rtx tem = gen_reg_rtx (QImode);
13376 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13377 operands[2] = tem;
13378 }
13379
13380 if (!rtx_equal_p (operands[6], operands[7]))
13381 emit_move_insn (operands[6], operands[7]);
13382 })
13383
13384 (define_insn "ashl<mode>3_doubleword"
13385 [(set (match_operand:DWI 0 "register_operand" "=&r")
13386 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13387 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13388 (clobber (reg:CC FLAGS_REG))]
13389 ""
13390 "#"
13391 [(set_attr "type" "multi")])
13392
13393 (define_split
13394 [(set (match_operand:DWI 0 "register_operand")
13395 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13396 (match_operand:QI 2 "nonmemory_operand")))
13397 (clobber (reg:CC FLAGS_REG))]
13398 "epilogue_completed"
13399 [(const_int 0)]
13400 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13401
13402 ;; By default we don't ask for a scratch register, because when DWImode
13403 ;; values are manipulated, registers are already at a premium. But if
13404 ;; we have one handy, we won't turn it away.
13405
13406 (define_peephole2
13407 [(match_scratch:DWIH 3 "r")
13408 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13409 (ashift:<DWI>
13410 (match_operand:<DWI> 1 "nonmemory_operand")
13411 (match_operand:QI 2 "nonmemory_operand")))
13412 (clobber (reg:CC FLAGS_REG))])
13413 (match_dup 3)]
13414 "TARGET_CMOVE"
13415 [(const_int 0)]
13416 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13417
13418 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13419 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13420 (ashift:<DWI>
13421 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13422 (match_operand:QI 2 "const_int_operand")))
13423 (clobber (reg:CC FLAGS_REG))]
13424 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13425 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13426 "#"
13427 "&& reload_completed"
13428 [(const_int 0)]
13429 {
13430 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13431 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13432 if (!rtx_equal_p (operands[3], operands[1]))
13433 emit_move_insn (operands[3], operands[1]);
13434 if (bits > 0)
13435 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13436 ix86_expand_clear (operands[0]);
13437 DONE;
13438 })
13439
13440 (define_insn "x86_64_shld"
13441 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13442 (ior:DI (ashift:DI (match_dup 0)
13443 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13444 (const_int 63)))
13445 (subreg:DI
13446 (lshiftrt:TI
13447 (zero_extend:TI
13448 (match_operand:DI 1 "register_operand" "r"))
13449 (minus:QI (const_int 64)
13450 (and:QI (match_dup 2) (const_int 63)))) 0)))
13451 (clobber (reg:CC FLAGS_REG))]
13452 "TARGET_64BIT"
13453 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13454 [(set_attr "type" "ishift")
13455 (set_attr "prefix_0f" "1")
13456 (set_attr "mode" "DI")
13457 (set_attr "athlon_decode" "vector")
13458 (set_attr "amdfam10_decode" "vector")
13459 (set_attr "bdver1_decode" "vector")])
13460
13461 (define_insn "x86_64_shld_1"
13462 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13463 (ior:DI (ashift:DI (match_dup 0)
13464 (match_operand:QI 2 "const_0_to_63_operand"))
13465 (subreg:DI
13466 (lshiftrt:TI
13467 (zero_extend:TI
13468 (match_operand:DI 1 "register_operand" "r"))
13469 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13470 (clobber (reg:CC FLAGS_REG))]
13471 "TARGET_64BIT
13472 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13473 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13474 [(set_attr "type" "ishift")
13475 (set_attr "prefix_0f" "1")
13476 (set_attr "mode" "DI")
13477 (set_attr "length_immediate" "1")
13478 (set_attr "athlon_decode" "vector")
13479 (set_attr "amdfam10_decode" "vector")
13480 (set_attr "bdver1_decode" "vector")])
13481
13482 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13483 [(set (match_operand:DI 0 "nonimmediate_operand")
13484 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13485 (match_operand:QI 2 "const_0_to_63_operand"))
13486 (lshiftrt:DI
13487 (match_operand:DI 1 "nonimmediate_operand")
13488 (match_operand:QI 3 "const_0_to_63_operand"))))
13489 (clobber (reg:CC FLAGS_REG))]
13490 "TARGET_64BIT
13491 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13492 && ix86_pre_reload_split ()"
13493 "#"
13494 "&& 1"
13495 [(const_int 0)]
13496 {
13497 if (rtx_equal_p (operands[4], operands[0]))
13498 {
13499 operands[1] = force_reg (DImode, operands[1]);
13500 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13501 }
13502 else if (rtx_equal_p (operands[1], operands[0]))
13503 {
13504 operands[4] = force_reg (DImode, operands[4]);
13505 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13506 }
13507 else
13508 {
13509 operands[1] = force_reg (DImode, operands[1]);
13510 rtx tmp = gen_reg_rtx (DImode);
13511 emit_move_insn (tmp, operands[4]);
13512 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13513 emit_move_insn (operands[0], tmp);
13514 }
13515 DONE;
13516 })
13517
13518 (define_insn_and_split "*x86_64_shld_2"
13519 [(set (match_operand:DI 0 "nonimmediate_operand")
13520 (ior:DI (ashift:DI (match_dup 0)
13521 (match_operand:QI 2 "nonmemory_operand"))
13522 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13523 (minus:QI (const_int 64) (match_dup 2)))))
13524 (clobber (reg:CC FLAGS_REG))]
13525 "TARGET_64BIT && ix86_pre_reload_split ()"
13526 "#"
13527 "&& 1"
13528 [(parallel [(set (match_dup 0)
13529 (ior:DI (ashift:DI (match_dup 0)
13530 (and:QI (match_dup 2) (const_int 63)))
13531 (subreg:DI
13532 (lshiftrt:TI
13533 (zero_extend:TI (match_dup 1))
13534 (minus:QI (const_int 64)
13535 (and:QI (match_dup 2)
13536 (const_int 63)))) 0)))
13537 (clobber (reg:CC FLAGS_REG))])])
13538
13539 (define_insn "x86_shld"
13540 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13541 (ior:SI (ashift:SI (match_dup 0)
13542 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13543 (const_int 31)))
13544 (subreg:SI
13545 (lshiftrt:DI
13546 (zero_extend:DI
13547 (match_operand:SI 1 "register_operand" "r"))
13548 (minus:QI (const_int 32)
13549 (and:QI (match_dup 2) (const_int 31)))) 0)))
13550 (clobber (reg:CC FLAGS_REG))]
13551 ""
13552 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13553 [(set_attr "type" "ishift")
13554 (set_attr "prefix_0f" "1")
13555 (set_attr "mode" "SI")
13556 (set_attr "pent_pair" "np")
13557 (set_attr "athlon_decode" "vector")
13558 (set_attr "amdfam10_decode" "vector")
13559 (set_attr "bdver1_decode" "vector")])
13560
13561 (define_insn "x86_shld_1"
13562 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13563 (ior:SI (ashift:SI (match_dup 0)
13564 (match_operand:QI 2 "const_0_to_31_operand"))
13565 (subreg:SI
13566 (lshiftrt:DI
13567 (zero_extend:DI
13568 (match_operand:SI 1 "register_operand" "r"))
13569 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13570 (clobber (reg:CC FLAGS_REG))]
13571 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13572 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13573 [(set_attr "type" "ishift")
13574 (set_attr "prefix_0f" "1")
13575 (set_attr "length_immediate" "1")
13576 (set_attr "mode" "SI")
13577 (set_attr "pent_pair" "np")
13578 (set_attr "athlon_decode" "vector")
13579 (set_attr "amdfam10_decode" "vector")
13580 (set_attr "bdver1_decode" "vector")])
13581
13582 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13583 [(set (match_operand:SI 0 "nonimmediate_operand")
13584 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13585 (match_operand:QI 2 "const_0_to_31_operand"))
13586 (lshiftrt:SI
13587 (match_operand:SI 1 "nonimmediate_operand")
13588 (match_operand:QI 3 "const_0_to_31_operand"))))
13589 (clobber (reg:CC FLAGS_REG))]
13590 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
13591 && ix86_pre_reload_split ()"
13592 "#"
13593 "&& 1"
13594 [(const_int 0)]
13595 {
13596 if (rtx_equal_p (operands[4], operands[0]))
13597 {
13598 operands[1] = force_reg (SImode, operands[1]);
13599 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13600 }
13601 else if (rtx_equal_p (operands[1], operands[0]))
13602 {
13603 operands[4] = force_reg (SImode, operands[4]);
13604 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13605 }
13606 else
13607 {
13608 operands[1] = force_reg (SImode, operands[1]);
13609 rtx tmp = gen_reg_rtx (SImode);
13610 emit_move_insn (tmp, operands[4]);
13611 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
13612 emit_move_insn (operands[0], tmp);
13613 }
13614 DONE;
13615 })
13616
13617 (define_insn_and_split "*x86_shld_2"
13618 [(set (match_operand:SI 0 "nonimmediate_operand")
13619 (ior:SI (ashift:SI (match_dup 0)
13620 (match_operand:QI 2 "nonmemory_operand"))
13621 (lshiftrt:SI (match_operand:SI 1 "register_operand")
13622 (minus:QI (const_int 32) (match_dup 2)))))
13623 (clobber (reg:CC FLAGS_REG))]
13624 "TARGET_64BIT && ix86_pre_reload_split ()"
13625 "#"
13626 "&& 1"
13627 [(parallel [(set (match_dup 0)
13628 (ior:SI (ashift:SI (match_dup 0)
13629 (and:QI (match_dup 2) (const_int 31)))
13630 (subreg:SI
13631 (lshiftrt:DI
13632 (zero_extend:DI (match_dup 1))
13633 (minus:QI (const_int 32)
13634 (and:QI (match_dup 2)
13635 (const_int 31)))) 0)))
13636 (clobber (reg:CC FLAGS_REG))])])
13637
13638 (define_expand "@x86_shift<mode>_adj_1"
13639 [(set (reg:CCZ FLAGS_REG)
13640 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
13641 (match_dup 4))
13642 (const_int 0)))
13643 (set (match_operand:SWI48 0 "register_operand")
13644 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13645 (match_operand:SWI48 1 "register_operand")
13646 (match_dup 0)))
13647 (set (match_dup 1)
13648 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13649 (match_operand:SWI48 3 "register_operand")
13650 (match_dup 1)))]
13651 "TARGET_CMOVE"
13652 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
13653
13654 (define_expand "@x86_shift<mode>_adj_2"
13655 [(use (match_operand:SWI48 0 "register_operand"))
13656 (use (match_operand:SWI48 1 "register_operand"))
13657 (use (match_operand:QI 2 "register_operand"))]
13658 ""
13659 {
13660 rtx_code_label *label = gen_label_rtx ();
13661 rtx tmp;
13662
13663 emit_insn (gen_testqi_ccz_1 (operands[2],
13664 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
13665
13666 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13667 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13668 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13669 gen_rtx_LABEL_REF (VOIDmode, label),
13670 pc_rtx);
13671 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
13672 JUMP_LABEL (tmp) = label;
13673
13674 emit_move_insn (operands[0], operands[1]);
13675 ix86_expand_clear (operands[1]);
13676
13677 emit_label (label);
13678 LABEL_NUSES (label) = 1;
13679
13680 DONE;
13681 })
13682
13683 ;; Avoid useless masking of count operand.
13684 (define_insn_and_split "*ashl<mode>3_mask"
13685 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13686 (ashift:SWI48
13687 (match_operand:SWI48 1 "nonimmediate_operand")
13688 (subreg:QI
13689 (and
13690 (match_operand 2 "int248_register_operand" "c,r")
13691 (match_operand 3 "const_int_operand")) 0)))
13692 (clobber (reg:CC FLAGS_REG))]
13693 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13694 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13695 == GET_MODE_BITSIZE (<MODE>mode)-1
13696 && ix86_pre_reload_split ()"
13697 "#"
13698 "&& 1"
13699 [(parallel
13700 [(set (match_dup 0)
13701 (ashift:SWI48 (match_dup 1)
13702 (match_dup 2)))
13703 (clobber (reg:CC FLAGS_REG))])]
13704 {
13705 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13706 operands[2] = gen_lowpart (QImode, operands[2]);
13707 }
13708 [(set_attr "isa" "*,bmi2")])
13709
13710 (define_insn_and_split "*ashl<mode>3_mask_1"
13711 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13712 (ashift:SWI48
13713 (match_operand:SWI48 1 "nonimmediate_operand")
13714 (and:QI
13715 (match_operand:QI 2 "register_operand" "c,r")
13716 (match_operand:QI 3 "const_int_operand"))))
13717 (clobber (reg:CC FLAGS_REG))]
13718 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13719 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13720 == GET_MODE_BITSIZE (<MODE>mode)-1
13721 && ix86_pre_reload_split ()"
13722 "#"
13723 "&& 1"
13724 [(parallel
13725 [(set (match_dup 0)
13726 (ashift:SWI48 (match_dup 1)
13727 (match_dup 2)))
13728 (clobber (reg:CC FLAGS_REG))])]
13729 ""
13730 [(set_attr "isa" "*,bmi2")])
13731
13732 (define_insn "*bmi2_ashl<mode>3_1"
13733 [(set (match_operand:SWI48 0 "register_operand" "=r")
13734 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13735 (match_operand:SWI48 2 "register_operand" "r")))]
13736 "TARGET_BMI2"
13737 "shlx\t{%2, %1, %0|%0, %1, %2}"
13738 [(set_attr "type" "ishiftx")
13739 (set_attr "mode" "<MODE>")])
13740
13741 (define_insn "*ashl<mode>3_1"
13742 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
13743 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
13744 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
13745 (clobber (reg:CC FLAGS_REG))]
13746 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
13747 {
13748 switch (get_attr_type (insn))
13749 {
13750 case TYPE_LEA:
13751 case TYPE_ISHIFTX:
13752 case TYPE_MSKLOG:
13753 return "#";
13754
13755 case TYPE_ALU:
13756 gcc_assert (operands[2] == const1_rtx);
13757 gcc_assert (rtx_equal_p (operands[0], operands[1]));
13758 return "add{<imodesuffix>}\t%0, %0";
13759
13760 default:
13761 if (operands[2] == const1_rtx
13762 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13763 return "sal{<imodesuffix>}\t%0";
13764 else
13765 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
13766 }
13767 }
13768 [(set_attr "isa" "*,*,bmi2,avx512bw")
13769 (set (attr "type")
13770 (cond [(eq_attr "alternative" "1")
13771 (const_string "lea")
13772 (eq_attr "alternative" "2")
13773 (const_string "ishiftx")
13774 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
13775 (match_operand 0 "register_operand"))
13776 (match_operand 2 "const1_operand"))
13777 (const_string "alu")
13778 (eq_attr "alternative" "3")
13779 (const_string "msklog")
13780 ]
13781 (const_string "ishift")))
13782 (set (attr "length_immediate")
13783 (if_then_else
13784 (ior (eq_attr "type" "alu")
13785 (and (eq_attr "type" "ishift")
13786 (and (match_operand 2 "const1_operand")
13787 (ior (match_test "TARGET_SHIFT1")
13788 (match_test "optimize_function_for_size_p (cfun)")))))
13789 (const_string "0")
13790 (const_string "*")))
13791 (set_attr "mode" "<MODE>")])
13792
13793 ;; Convert shift to the shiftx pattern to avoid flags dependency.
13794 (define_split
13795 [(set (match_operand:SWI48 0 "register_operand")
13796 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
13797 (match_operand:QI 2 "register_operand")))
13798 (clobber (reg:CC FLAGS_REG))]
13799 "TARGET_BMI2 && reload_completed"
13800 [(set (match_dup 0)
13801 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
13802 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
13803
13804 (define_insn "*bmi2_ashlsi3_1_zext"
13805 [(set (match_operand:DI 0 "register_operand" "=r")
13806 (zero_extend:DI
13807 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
13808 (match_operand:SI 2 "register_operand" "r"))))]
13809 "TARGET_64BIT && TARGET_BMI2"
13810 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
13811 [(set_attr "type" "ishiftx")
13812 (set_attr "mode" "SI")])
13813
13814 (define_insn "*ashlsi3_1_zext"
13815 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
13816 (zero_extend:DI
13817 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
13818 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
13819 (clobber (reg:CC FLAGS_REG))]
13820 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
13821 {
13822 switch (get_attr_type (insn))
13823 {
13824 case TYPE_LEA:
13825 case TYPE_ISHIFTX:
13826 return "#";
13827
13828 case TYPE_ALU:
13829 gcc_assert (operands[2] == const1_rtx);
13830 return "add{l}\t%k0, %k0";
13831
13832 default:
13833 if (operands[2] == const1_rtx
13834 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13835 return "sal{l}\t%k0";
13836 else
13837 return "sal{l}\t{%2, %k0|%k0, %2}";
13838 }
13839 }
13840 [(set_attr "isa" "*,*,bmi2")
13841 (set (attr "type")
13842 (cond [(eq_attr "alternative" "1")
13843 (const_string "lea")
13844 (eq_attr "alternative" "2")
13845 (const_string "ishiftx")
13846 (and (match_test "TARGET_DOUBLE_WITH_ADD")
13847 (match_operand 2 "const1_operand"))
13848 (const_string "alu")
13849 ]
13850 (const_string "ishift")))
13851 (set (attr "length_immediate")
13852 (if_then_else
13853 (ior (eq_attr "type" "alu")
13854 (and (eq_attr "type" "ishift")
13855 (and (match_operand 2 "const1_operand")
13856 (ior (match_test "TARGET_SHIFT1")
13857 (match_test "optimize_function_for_size_p (cfun)")))))
13858 (const_string "0")
13859 (const_string "*")))
13860 (set_attr "mode" "SI")])
13861
13862 ;; Convert shift to the shiftx pattern to avoid flags dependency.
13863 (define_split
13864 [(set (match_operand:DI 0 "register_operand")
13865 (zero_extend:DI
13866 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
13867 (match_operand:QI 2 "register_operand"))))
13868 (clobber (reg:CC FLAGS_REG))]
13869 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
13870 [(set (match_dup 0)
13871 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
13872 "operands[2] = gen_lowpart (SImode, operands[2]);")
13873
13874 (define_insn "*ashlhi3_1"
13875 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
13876 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
13877 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
13878 (clobber (reg:CC FLAGS_REG))]
13879 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
13880 {
13881 switch (get_attr_type (insn))
13882 {
13883 case TYPE_LEA:
13884 case TYPE_MSKLOG:
13885 return "#";
13886
13887 case TYPE_ALU:
13888 gcc_assert (operands[2] == const1_rtx);
13889 return "add{w}\t%0, %0";
13890
13891 default:
13892 if (operands[2] == const1_rtx
13893 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13894 return "sal{w}\t%0";
13895 else
13896 return "sal{w}\t{%2, %0|%0, %2}";
13897 }
13898 }
13899 [(set_attr "isa" "*,*,avx512f")
13900 (set (attr "type")
13901 (cond [(eq_attr "alternative" "1")
13902 (const_string "lea")
13903 (eq_attr "alternative" "2")
13904 (const_string "msklog")
13905 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
13906 (match_operand 0 "register_operand"))
13907 (match_operand 2 "const1_operand"))
13908 (const_string "alu")
13909 ]
13910 (const_string "ishift")))
13911 (set (attr "length_immediate")
13912 (if_then_else
13913 (ior (eq_attr "type" "alu")
13914 (and (eq_attr "type" "ishift")
13915 (and (match_operand 2 "const1_operand")
13916 (ior (match_test "TARGET_SHIFT1")
13917 (match_test "optimize_function_for_size_p (cfun)")))))
13918 (const_string "0")
13919 (const_string "*")))
13920 (set_attr "mode" "HI,SI,HI")])
13921
13922 (define_insn "*ashlqi3_1"
13923 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
13924 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
13925 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
13926 (clobber (reg:CC FLAGS_REG))]
13927 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
13928 {
13929 switch (get_attr_type (insn))
13930 {
13931 case TYPE_LEA:
13932 case TYPE_MSKLOG:
13933 return "#";
13934
13935 case TYPE_ALU:
13936 gcc_assert (operands[2] == const1_rtx);
13937 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
13938 return "add{l}\t%k0, %k0";
13939 else
13940 return "add{b}\t%0, %0";
13941
13942 default:
13943 if (operands[2] == const1_rtx
13944 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13945 {
13946 if (get_attr_mode (insn) == MODE_SI)
13947 return "sal{l}\t%k0";
13948 else
13949 return "sal{b}\t%0";
13950 }
13951 else
13952 {
13953 if (get_attr_mode (insn) == MODE_SI)
13954 return "sal{l}\t{%2, %k0|%k0, %2}";
13955 else
13956 return "sal{b}\t{%2, %0|%0, %2}";
13957 }
13958 }
13959 }
13960 [(set_attr "isa" "*,*,*,avx512dq")
13961 (set (attr "type")
13962 (cond [(eq_attr "alternative" "2")
13963 (const_string "lea")
13964 (eq_attr "alternative" "3")
13965 (const_string "msklog")
13966 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
13967 (match_operand 0 "register_operand"))
13968 (match_operand 2 "const1_operand"))
13969 (const_string "alu")
13970 ]
13971 (const_string "ishift")))
13972 (set (attr "length_immediate")
13973 (if_then_else
13974 (ior (eq_attr "type" "alu")
13975 (and (eq_attr "type" "ishift")
13976 (and (match_operand 2 "const1_operand")
13977 (ior (match_test "TARGET_SHIFT1")
13978 (match_test "optimize_function_for_size_p (cfun)")))))
13979 (const_string "0")
13980 (const_string "*")))
13981 (set_attr "mode" "QI,SI,SI,QI")
13982 ;; Potential partial reg stall on alternative 1.
13983 (set (attr "preferred_for_speed")
13984 (cond [(eq_attr "alternative" "1")
13985 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13986 (symbol_ref "true")))])
13987
13988 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13989 (define_insn_and_split "*ashl<mode>3_1_slp"
13990 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13991 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
13992 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
13993 (clobber (reg:CC FLAGS_REG))]
13994 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13995 {
13996 if (which_alternative)
13997 return "#";
13998
13999 switch (get_attr_type (insn))
14000 {
14001 case TYPE_ALU:
14002 gcc_assert (operands[2] == const1_rtx);
14003 return "add{<imodesuffix>}\t%0, %0";
14004
14005 default:
14006 if (operands[2] == const1_rtx
14007 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14008 return "sal{<imodesuffix>}\t%0";
14009 else
14010 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14011 }
14012 }
14013 "&& reload_completed"
14014 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14015 (parallel
14016 [(set (strict_low_part (match_dup 0))
14017 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14018 (clobber (reg:CC FLAGS_REG))])]
14019 ""
14020 [(set (attr "type")
14021 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14022 (match_operand 2 "const1_operand"))
14023 (const_string "alu")
14024 ]
14025 (const_string "ishift")))
14026 (set (attr "length_immediate")
14027 (if_then_else
14028 (ior (eq_attr "type" "alu")
14029 (and (eq_attr "type" "ishift")
14030 (and (match_operand 2 "const1_operand")
14031 (ior (match_test "TARGET_SHIFT1")
14032 (match_test "optimize_function_for_size_p (cfun)")))))
14033 (const_string "0")
14034 (const_string "*")))
14035 (set_attr "mode" "<MODE>")])
14036
14037 ;; Convert ashift to the lea pattern to avoid flags dependency.
14038 (define_split
14039 [(set (match_operand:SWI 0 "general_reg_operand")
14040 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14041 (match_operand 2 "const_0_to_3_operand")))
14042 (clobber (reg:CC FLAGS_REG))]
14043 "reload_completed
14044 && REGNO (operands[0]) != REGNO (operands[1])"
14045 [(set (match_dup 0)
14046 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14047 {
14048 if (<MODE>mode != <LEAMODE>mode)
14049 {
14050 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14051 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14052 }
14053 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14054 })
14055
14056 ;; Convert ashift to the lea pattern to avoid flags dependency.
14057 (define_split
14058 [(set (match_operand:DI 0 "general_reg_operand")
14059 (zero_extend:DI
14060 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14061 (match_operand 2 "const_0_to_3_operand"))))
14062 (clobber (reg:CC FLAGS_REG))]
14063 "TARGET_64BIT && reload_completed
14064 && REGNO (operands[0]) != REGNO (operands[1])"
14065 [(set (match_dup 0)
14066 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14067 {
14068 operands[1] = gen_lowpart (SImode, operands[1]);
14069 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14070 })
14071
14072 ;; This pattern can't accept a variable shift count, since shifts by
14073 ;; zero don't affect the flags. We assume that shifts by constant
14074 ;; zero are optimized away.
14075 (define_insn "*ashl<mode>3_cmp"
14076 [(set (reg FLAGS_REG)
14077 (compare
14078 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14079 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14080 (const_int 0)))
14081 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14082 (ashift:SWI (match_dup 1) (match_dup 2)))]
14083 "(optimize_function_for_size_p (cfun)
14084 || !TARGET_PARTIAL_FLAG_REG_STALL
14085 || (operands[2] == const1_rtx
14086 && (TARGET_SHIFT1
14087 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14088 && ix86_match_ccmode (insn, CCGOCmode)
14089 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14090 {
14091 switch (get_attr_type (insn))
14092 {
14093 case TYPE_ALU:
14094 gcc_assert (operands[2] == const1_rtx);
14095 return "add{<imodesuffix>}\t%0, %0";
14096
14097 default:
14098 if (operands[2] == const1_rtx
14099 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14100 return "sal{<imodesuffix>}\t%0";
14101 else
14102 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14103 }
14104 }
14105 [(set (attr "type")
14106 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14107 (match_operand 0 "register_operand"))
14108 (match_operand 2 "const1_operand"))
14109 (const_string "alu")
14110 ]
14111 (const_string "ishift")))
14112 (set (attr "length_immediate")
14113 (if_then_else
14114 (ior (eq_attr "type" "alu")
14115 (and (eq_attr "type" "ishift")
14116 (and (match_operand 2 "const1_operand")
14117 (ior (match_test "TARGET_SHIFT1")
14118 (match_test "optimize_function_for_size_p (cfun)")))))
14119 (const_string "0")
14120 (const_string "*")))
14121 (set_attr "mode" "<MODE>")])
14122
14123 (define_insn "*ashlsi3_cmp_zext"
14124 [(set (reg FLAGS_REG)
14125 (compare
14126 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14127 (match_operand:QI 2 "const_1_to_31_operand"))
14128 (const_int 0)))
14129 (set (match_operand:DI 0 "register_operand" "=r")
14130 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14131 "TARGET_64BIT
14132 && (optimize_function_for_size_p (cfun)
14133 || !TARGET_PARTIAL_FLAG_REG_STALL
14134 || (operands[2] == const1_rtx
14135 && (TARGET_SHIFT1
14136 || TARGET_DOUBLE_WITH_ADD)))
14137 && ix86_match_ccmode (insn, CCGOCmode)
14138 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14139 {
14140 switch (get_attr_type (insn))
14141 {
14142 case TYPE_ALU:
14143 gcc_assert (operands[2] == const1_rtx);
14144 return "add{l}\t%k0, %k0";
14145
14146 default:
14147 if (operands[2] == const1_rtx
14148 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14149 return "sal{l}\t%k0";
14150 else
14151 return "sal{l}\t{%2, %k0|%k0, %2}";
14152 }
14153 }
14154 [(set (attr "type")
14155 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14156 (match_operand 2 "const1_operand"))
14157 (const_string "alu")
14158 ]
14159 (const_string "ishift")))
14160 (set (attr "length_immediate")
14161 (if_then_else
14162 (ior (eq_attr "type" "alu")
14163 (and (eq_attr "type" "ishift")
14164 (and (match_operand 2 "const1_operand")
14165 (ior (match_test "TARGET_SHIFT1")
14166 (match_test "optimize_function_for_size_p (cfun)")))))
14167 (const_string "0")
14168 (const_string "*")))
14169 (set_attr "mode" "SI")])
14170
14171 (define_insn "*ashl<mode>3_cconly"
14172 [(set (reg FLAGS_REG)
14173 (compare
14174 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14175 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14176 (const_int 0)))
14177 (clobber (match_scratch:SWI 0 "=<r>"))]
14178 "(optimize_function_for_size_p (cfun)
14179 || !TARGET_PARTIAL_FLAG_REG_STALL
14180 || (operands[2] == const1_rtx
14181 && (TARGET_SHIFT1
14182 || TARGET_DOUBLE_WITH_ADD)))
14183 && ix86_match_ccmode (insn, CCGOCmode)"
14184 {
14185 switch (get_attr_type (insn))
14186 {
14187 case TYPE_ALU:
14188 gcc_assert (operands[2] == const1_rtx);
14189 return "add{<imodesuffix>}\t%0, %0";
14190
14191 default:
14192 if (operands[2] == const1_rtx
14193 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14194 return "sal{<imodesuffix>}\t%0";
14195 else
14196 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14197 }
14198 }
14199 [(set (attr "type")
14200 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14201 (match_operand 0 "register_operand"))
14202 (match_operand 2 "const1_operand"))
14203 (const_string "alu")
14204 ]
14205 (const_string "ishift")))
14206 (set (attr "length_immediate")
14207 (if_then_else
14208 (ior (eq_attr "type" "alu")
14209 (and (eq_attr "type" "ishift")
14210 (and (match_operand 2 "const1_operand")
14211 (ior (match_test "TARGET_SHIFT1")
14212 (match_test "optimize_function_for_size_p (cfun)")))))
14213 (const_string "0")
14214 (const_string "*")))
14215 (set_attr "mode" "<MODE>")])
14216
14217 (define_insn "*ashlqi_ext<mode>_2"
14218 [(set (zero_extract:SWI248
14219 (match_operand 0 "int248_register_operand" "+Q")
14220 (const_int 8)
14221 (const_int 8))
14222 (subreg:SWI248
14223 (ashift:QI
14224 (subreg:QI
14225 (match_operator:SWI248 3 "extract_operator"
14226 [(match_operand 1 "int248_register_operand" "0")
14227 (const_int 8)
14228 (const_int 8)]) 0)
14229 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
14230 (clobber (reg:CC FLAGS_REG))]
14231 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
14232 rtx_equal_p (operands[0], operands[1])"
14233 {
14234 switch (get_attr_type (insn))
14235 {
14236 case TYPE_ALU:
14237 gcc_assert (operands[2] == const1_rtx);
14238 return "add{b}\t%h0, %h0";
14239
14240 default:
14241 if (operands[2] == const1_rtx
14242 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14243 return "sal{b}\t%h0";
14244 else
14245 return "sal{b}\t{%2, %h0|%h0, %2}";
14246 }
14247 }
14248 [(set (attr "type")
14249 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14250 (match_operand 2 "const1_operand"))
14251 (const_string "alu")
14252 ]
14253 (const_string "ishift")))
14254 (set (attr "length_immediate")
14255 (if_then_else
14256 (ior (eq_attr "type" "alu")
14257 (and (eq_attr "type" "ishift")
14258 (and (match_operand 2 "const1_operand")
14259 (ior (match_test "TARGET_SHIFT1")
14260 (match_test "optimize_function_for_size_p (cfun)")))))
14261 (const_string "0")
14262 (const_string "*")))
14263 (set_attr "mode" "QI")])
14264
14265 ;; See comment above `ashl<mode>3' about how this works.
14266
14267 (define_expand "<insn><mode>3"
14268 [(set (match_operand:SDWIM 0 "<shift_operand>")
14269 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14270 (match_operand:QI 2 "nonmemory_operand")))]
14271 ""
14272 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14273
14274 ;; Avoid useless masking of count operand.
14275 (define_insn_and_split "*<insn><mode>3_mask"
14276 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14277 (any_shiftrt:SWI48
14278 (match_operand:SWI48 1 "nonimmediate_operand")
14279 (subreg:QI
14280 (and
14281 (match_operand 2 "int248_register_operand" "c,r")
14282 (match_operand 3 "const_int_operand")) 0)))
14283 (clobber (reg:CC FLAGS_REG))]
14284 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14285 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14286 == GET_MODE_BITSIZE (<MODE>mode)-1
14287 && ix86_pre_reload_split ()"
14288 "#"
14289 "&& 1"
14290 [(parallel
14291 [(set (match_dup 0)
14292 (any_shiftrt:SWI48 (match_dup 1)
14293 (match_dup 2)))
14294 (clobber (reg:CC FLAGS_REG))])]
14295 {
14296 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14297 operands[2] = gen_lowpart (QImode, operands[2]);
14298 }
14299 [(set_attr "isa" "*,bmi2")])
14300
14301 (define_insn_and_split "*<insn><mode>3_mask_1"
14302 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14303 (any_shiftrt:SWI48
14304 (match_operand:SWI48 1 "nonimmediate_operand")
14305 (and:QI
14306 (match_operand:QI 2 "register_operand" "c,r")
14307 (match_operand:QI 3 "const_int_operand"))))
14308 (clobber (reg:CC FLAGS_REG))]
14309 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14310 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14311 == GET_MODE_BITSIZE (<MODE>mode)-1
14312 && ix86_pre_reload_split ()"
14313 "#"
14314 "&& 1"
14315 [(parallel
14316 [(set (match_dup 0)
14317 (any_shiftrt:SWI48 (match_dup 1)
14318 (match_dup 2)))
14319 (clobber (reg:CC FLAGS_REG))])]
14320 ""
14321 [(set_attr "isa" "*,bmi2")])
14322
14323 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14324 [(set (match_operand:<DWI> 0 "register_operand")
14325 (any_shiftrt:<DWI>
14326 (match_operand:<DWI> 1 "register_operand")
14327 (subreg:QI
14328 (and
14329 (match_operand 2 "int248_register_operand" "c")
14330 (match_operand 3 "const_int_operand")) 0)))
14331 (clobber (reg:CC FLAGS_REG))]
14332 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14333 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14334 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14335 && ix86_pre_reload_split ()"
14336 "#"
14337 "&& 1"
14338 [(parallel
14339 [(set (match_dup 4)
14340 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14341 (and:QI (match_dup 2) (match_dup 8)))
14342 (subreg:DWIH
14343 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14344 (minus:QI (match_dup 9)
14345 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14346 (clobber (reg:CC FLAGS_REG))])
14347 (parallel
14348 [(set (match_dup 6)
14349 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14350 (clobber (reg:CC FLAGS_REG))])]
14351 {
14352 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14353 {
14354 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14355 operands[2] = gen_lowpart (QImode, operands[2]);
14356 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14357 operands[2]));
14358 DONE;
14359 }
14360
14361 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14362
14363 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14364 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14365
14366 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14367 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14368 {
14369 rtx xops[3];
14370 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14371 xops[1] = operands[2];
14372 xops[2] = GEN_INT (INTVAL (operands[3])
14373 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14374 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14375 operands[2] = xops[0];
14376 }
14377
14378 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14379 operands[2] = gen_lowpart (QImode, operands[2]);
14380
14381 if (!rtx_equal_p (operands[4], operands[5]))
14382 emit_move_insn (operands[4], operands[5]);
14383 })
14384
14385 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14386 [(set (match_operand:<DWI> 0 "register_operand")
14387 (any_shiftrt:<DWI>
14388 (match_operand:<DWI> 1 "register_operand")
14389 (and:QI
14390 (match_operand:QI 2 "register_operand" "c")
14391 (match_operand:QI 3 "const_int_operand"))))
14392 (clobber (reg:CC FLAGS_REG))]
14393 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14394 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14395 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14396 && ix86_pre_reload_split ()"
14397 "#"
14398 "&& 1"
14399 [(parallel
14400 [(set (match_dup 4)
14401 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14402 (and:QI (match_dup 2) (match_dup 8)))
14403 (subreg:DWIH
14404 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14405 (minus:QI (match_dup 9)
14406 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14407 (clobber (reg:CC FLAGS_REG))])
14408 (parallel
14409 [(set (match_dup 6)
14410 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14411 (clobber (reg:CC FLAGS_REG))])]
14412 {
14413 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14414 {
14415 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14416 operands[2]));
14417 DONE;
14418 }
14419
14420 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14421
14422 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14423 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14424
14425 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14426 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14427 {
14428 rtx tem = gen_reg_rtx (QImode);
14429 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14430 operands[2] = tem;
14431 }
14432
14433 if (!rtx_equal_p (operands[4], operands[5]))
14434 emit_move_insn (operands[4], operands[5]);
14435 })
14436
14437 (define_insn_and_split "<insn><mode>3_doubleword"
14438 [(set (match_operand:DWI 0 "register_operand" "=&r")
14439 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14440 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14441 (clobber (reg:CC FLAGS_REG))]
14442 ""
14443 "#"
14444 "epilogue_completed"
14445 [(const_int 0)]
14446 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14447 [(set_attr "type" "multi")])
14448
14449 ;; By default we don't ask for a scratch register, because when DWImode
14450 ;; values are manipulated, registers are already at a premium. But if
14451 ;; we have one handy, we won't turn it away.
14452
14453 (define_peephole2
14454 [(match_scratch:DWIH 3 "r")
14455 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14456 (any_shiftrt:<DWI>
14457 (match_operand:<DWI> 1 "register_operand")
14458 (match_operand:QI 2 "nonmemory_operand")))
14459 (clobber (reg:CC FLAGS_REG))])
14460 (match_dup 3)]
14461 "TARGET_CMOVE"
14462 [(const_int 0)]
14463 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14464
14465 (define_insn "x86_64_shrd"
14466 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14467 (ior:DI (lshiftrt:DI (match_dup 0)
14468 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14469 (const_int 63)))
14470 (subreg:DI
14471 (ashift:TI
14472 (zero_extend:TI
14473 (match_operand:DI 1 "register_operand" "r"))
14474 (minus:QI (const_int 64)
14475 (and:QI (match_dup 2) (const_int 63)))) 0)))
14476 (clobber (reg:CC FLAGS_REG))]
14477 "TARGET_64BIT"
14478 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14479 [(set_attr "type" "ishift")
14480 (set_attr "prefix_0f" "1")
14481 (set_attr "mode" "DI")
14482 (set_attr "athlon_decode" "vector")
14483 (set_attr "amdfam10_decode" "vector")
14484 (set_attr "bdver1_decode" "vector")])
14485
14486 (define_insn "x86_64_shrd_1"
14487 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14488 (ior:DI (lshiftrt:DI (match_dup 0)
14489 (match_operand:QI 2 "const_0_to_63_operand"))
14490 (subreg:DI
14491 (ashift:TI
14492 (zero_extend:TI
14493 (match_operand:DI 1 "register_operand" "r"))
14494 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14495 (clobber (reg:CC FLAGS_REG))]
14496 "TARGET_64BIT
14497 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14498 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14499 [(set_attr "type" "ishift")
14500 (set_attr "prefix_0f" "1")
14501 (set_attr "length_immediate" "1")
14502 (set_attr "mode" "DI")
14503 (set_attr "athlon_decode" "vector")
14504 (set_attr "amdfam10_decode" "vector")
14505 (set_attr "bdver1_decode" "vector")])
14506
14507 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14508 [(set (match_operand:DI 0 "nonimmediate_operand")
14509 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14510 (match_operand:QI 2 "const_0_to_63_operand"))
14511 (ashift:DI
14512 (match_operand:DI 1 "nonimmediate_operand")
14513 (match_operand:QI 3 "const_0_to_63_operand"))))
14514 (clobber (reg:CC FLAGS_REG))]
14515 "TARGET_64BIT
14516 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14517 && ix86_pre_reload_split ()"
14518 "#"
14519 "&& 1"
14520 [(const_int 0)]
14521 {
14522 if (rtx_equal_p (operands[4], operands[0]))
14523 {
14524 operands[1] = force_reg (DImode, operands[1]);
14525 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14526 }
14527 else if (rtx_equal_p (operands[1], operands[0]))
14528 {
14529 operands[4] = force_reg (DImode, operands[4]);
14530 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14531 }
14532 else
14533 {
14534 operands[1] = force_reg (DImode, operands[1]);
14535 rtx tmp = gen_reg_rtx (DImode);
14536 emit_move_insn (tmp, operands[4]);
14537 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14538 emit_move_insn (operands[0], tmp);
14539 }
14540 DONE;
14541 })
14542
14543 (define_insn_and_split "*x86_64_shrd_2"
14544 [(set (match_operand:DI 0 "nonimmediate_operand")
14545 (ior:DI (lshiftrt:DI (match_dup 0)
14546 (match_operand:QI 2 "nonmemory_operand"))
14547 (ashift:DI (match_operand:DI 1 "register_operand")
14548 (minus:QI (const_int 64) (match_dup 2)))))
14549 (clobber (reg:CC FLAGS_REG))]
14550 "TARGET_64BIT && ix86_pre_reload_split ()"
14551 "#"
14552 "&& 1"
14553 [(parallel [(set (match_dup 0)
14554 (ior:DI (lshiftrt:DI (match_dup 0)
14555 (and:QI (match_dup 2) (const_int 63)))
14556 (subreg:DI
14557 (ashift:TI
14558 (zero_extend:TI (match_dup 1))
14559 (minus:QI (const_int 64)
14560 (and:QI (match_dup 2)
14561 (const_int 63)))) 0)))
14562 (clobber (reg:CC FLAGS_REG))])])
14563
14564 (define_insn "x86_shrd"
14565 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14566 (ior:SI (lshiftrt:SI (match_dup 0)
14567 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14568 (const_int 31)))
14569 (subreg:SI
14570 (ashift:DI
14571 (zero_extend:DI
14572 (match_operand:SI 1 "register_operand" "r"))
14573 (minus:QI (const_int 32)
14574 (and:QI (match_dup 2) (const_int 31)))) 0)))
14575 (clobber (reg:CC FLAGS_REG))]
14576 ""
14577 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
14578 [(set_attr "type" "ishift")
14579 (set_attr "prefix_0f" "1")
14580 (set_attr "mode" "SI")
14581 (set_attr "pent_pair" "np")
14582 (set_attr "athlon_decode" "vector")
14583 (set_attr "amdfam10_decode" "vector")
14584 (set_attr "bdver1_decode" "vector")])
14585
14586 (define_insn "x86_shrd_1"
14587 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14588 (ior:SI (lshiftrt:SI (match_dup 0)
14589 (match_operand:QI 2 "const_0_to_31_operand"))
14590 (subreg:SI
14591 (ashift:DI
14592 (zero_extend:DI
14593 (match_operand:SI 1 "register_operand" "r"))
14594 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14595 (clobber (reg:CC FLAGS_REG))]
14596 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14597 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
14598 [(set_attr "type" "ishift")
14599 (set_attr "prefix_0f" "1")
14600 (set_attr "length_immediate" "1")
14601 (set_attr "mode" "SI")
14602 (set_attr "pent_pair" "np")
14603 (set_attr "athlon_decode" "vector")
14604 (set_attr "amdfam10_decode" "vector")
14605 (set_attr "bdver1_decode" "vector")])
14606
14607 (define_insn_and_split "*x86_shrd_shld_1_nozext"
14608 [(set (match_operand:SI 0 "nonimmediate_operand")
14609 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
14610 (match_operand:QI 2 "const_0_to_31_operand"))
14611 (ashift:SI
14612 (match_operand:SI 1 "nonimmediate_operand")
14613 (match_operand:QI 3 "const_0_to_31_operand"))))
14614 (clobber (reg:CC FLAGS_REG))]
14615 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14616 && ix86_pre_reload_split ()"
14617 "#"
14618 "&& 1"
14619 [(const_int 0)]
14620 {
14621 if (rtx_equal_p (operands[4], operands[0]))
14622 {
14623 operands[1] = force_reg (SImode, operands[1]);
14624 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14625 }
14626 else if (rtx_equal_p (operands[1], operands[0]))
14627 {
14628 operands[4] = force_reg (SImode, operands[4]);
14629 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14630 }
14631 else
14632 {
14633 operands[1] = force_reg (SImode, operands[1]);
14634 rtx tmp = gen_reg_rtx (SImode);
14635 emit_move_insn (tmp, operands[4]);
14636 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14637 emit_move_insn (operands[0], tmp);
14638 }
14639 DONE;
14640 })
14641
14642 (define_insn_and_split "*x86_shrd_2"
14643 [(set (match_operand:SI 0 "nonimmediate_operand")
14644 (ior:SI (lshiftrt:SI (match_dup 0)
14645 (match_operand:QI 2 "nonmemory_operand"))
14646 (ashift:SI (match_operand:SI 1 "register_operand")
14647 (minus:QI (const_int 32) (match_dup 2)))))
14648 (clobber (reg:CC FLAGS_REG))]
14649 "TARGET_64BIT && ix86_pre_reload_split ()"
14650 "#"
14651 "&& 1"
14652 [(parallel [(set (match_dup 0)
14653 (ior:SI (lshiftrt:SI (match_dup 0)
14654 (and:QI (match_dup 2) (const_int 31)))
14655 (subreg:SI
14656 (ashift:DI
14657 (zero_extend:DI (match_dup 1))
14658 (minus:QI (const_int 32)
14659 (and:QI (match_dup 2)
14660 (const_int 31)))) 0)))
14661 (clobber (reg:CC FLAGS_REG))])])
14662
14663 ;; Base name for insn mnemonic.
14664 (define_mode_attr cvt_mnemonic
14665 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
14666
14667 (define_insn "ashr<mode>3_cvt"
14668 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
14669 (ashiftrt:SWI48
14670 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
14671 (match_operand:QI 2 "const_int_operand")))
14672 (clobber (reg:CC FLAGS_REG))]
14673 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
14674 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14675 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14676 "@
14677 <cvt_mnemonic>
14678 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
14679 [(set_attr "type" "imovx,ishift")
14680 (set_attr "prefix_0f" "0,*")
14681 (set_attr "length_immediate" "0,*")
14682 (set_attr "modrm" "0,1")
14683 (set_attr "mode" "<MODE>")])
14684
14685 (define_insn "*ashrsi3_cvt_zext"
14686 [(set (match_operand:DI 0 "register_operand" "=*d,r")
14687 (zero_extend:DI
14688 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
14689 (match_operand:QI 2 "const_int_operand"))))
14690 (clobber (reg:CC FLAGS_REG))]
14691 "TARGET_64BIT && INTVAL (operands[2]) == 31
14692 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14693 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
14694 "@
14695 {cltd|cdq}
14696 sar{l}\t{%2, %k0|%k0, %2}"
14697 [(set_attr "type" "imovx,ishift")
14698 (set_attr "prefix_0f" "0,*")
14699 (set_attr "length_immediate" "0,*")
14700 (set_attr "modrm" "0,1")
14701 (set_attr "mode" "SI")])
14702
14703 (define_expand "@x86_shift<mode>_adj_3"
14704 [(use (match_operand:SWI48 0 "register_operand"))
14705 (use (match_operand:SWI48 1 "register_operand"))
14706 (use (match_operand:QI 2 "register_operand"))]
14707 ""
14708 {
14709 rtx_code_label *label = gen_label_rtx ();
14710 rtx tmp;
14711
14712 emit_insn (gen_testqi_ccz_1 (operands[2],
14713 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14714
14715 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14716 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14717 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14718 gen_rtx_LABEL_REF (VOIDmode, label),
14719 pc_rtx);
14720 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14721 JUMP_LABEL (tmp) = label;
14722
14723 emit_move_insn (operands[0], operands[1]);
14724 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
14725 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
14726 emit_label (label);
14727 LABEL_NUSES (label) = 1;
14728
14729 DONE;
14730 })
14731
14732 (define_insn "*bmi2_<insn><mode>3_1"
14733 [(set (match_operand:SWI48 0 "register_operand" "=r")
14734 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14735 (match_operand:SWI48 2 "register_operand" "r")))]
14736 "TARGET_BMI2"
14737 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
14738 [(set_attr "type" "ishiftx")
14739 (set_attr "mode" "<MODE>")])
14740
14741 (define_insn "*ashr<mode>3_1"
14742 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
14743 (ashiftrt:SWI48
14744 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
14745 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
14746 (clobber (reg:CC FLAGS_REG))]
14747 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14748 {
14749 switch (get_attr_type (insn))
14750 {
14751 case TYPE_ISHIFTX:
14752 return "#";
14753
14754 default:
14755 if (operands[2] == const1_rtx
14756 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14757 return "sar{<imodesuffix>}\t%0";
14758 else
14759 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
14760 }
14761 }
14762 [(set_attr "isa" "*,bmi2")
14763 (set_attr "type" "ishift,ishiftx")
14764 (set (attr "length_immediate")
14765 (if_then_else
14766 (and (match_operand 2 "const1_operand")
14767 (ior (match_test "TARGET_SHIFT1")
14768 (match_test "optimize_function_for_size_p (cfun)")))
14769 (const_string "0")
14770 (const_string "*")))
14771 (set_attr "mode" "<MODE>")])
14772
14773 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
14774 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
14775 (define_insn_and_split "*highpartdisi2"
14776 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
14777 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
14778 (const_int 32)))
14779 (clobber (reg:CC FLAGS_REG))]
14780 "TARGET_64BIT"
14781 "#"
14782 "&& reload_completed"
14783 [(parallel
14784 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
14785 (clobber (reg:CC FLAGS_REG))])]
14786 {
14787 if (SSE_REG_P (operands[0]))
14788 {
14789 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
14790 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
14791 const1_rtx, const1_rtx,
14792 GEN_INT (5), GEN_INT (5)));
14793 DONE;
14794 }
14795 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
14796 })
14797
14798 (define_insn "*lshr<mode>3_1"
14799 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
14800 (lshiftrt:SWI48
14801 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
14802 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
14803 (clobber (reg:CC FLAGS_REG))]
14804 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
14805 {
14806 switch (get_attr_type (insn))
14807 {
14808 case TYPE_ISHIFTX:
14809 case TYPE_MSKLOG:
14810 return "#";
14811
14812 default:
14813 if (operands[2] == const1_rtx
14814 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14815 return "shr{<imodesuffix>}\t%0";
14816 else
14817 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
14818 }
14819 }
14820 [(set_attr "isa" "*,bmi2,avx512bw")
14821 (set_attr "type" "ishift,ishiftx,msklog")
14822 (set (attr "length_immediate")
14823 (if_then_else
14824 (and (and (match_operand 2 "const1_operand")
14825 (eq_attr "alternative" "0"))
14826 (ior (match_test "TARGET_SHIFT1")
14827 (match_test "optimize_function_for_size_p (cfun)")))
14828 (const_string "0")
14829 (const_string "*")))
14830 (set_attr "mode" "<MODE>")])
14831
14832 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14833 (define_split
14834 [(set (match_operand:SWI48 0 "register_operand")
14835 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14836 (match_operand:QI 2 "register_operand")))
14837 (clobber (reg:CC FLAGS_REG))]
14838 "TARGET_BMI2 && reload_completed"
14839 [(set (match_dup 0)
14840 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
14841 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14842
14843 (define_insn "*bmi2_<insn>si3_1_zext"
14844 [(set (match_operand:DI 0 "register_operand" "=r")
14845 (zero_extend:DI
14846 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14847 (match_operand:SI 2 "register_operand" "r"))))]
14848 "TARGET_64BIT && TARGET_BMI2"
14849 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
14850 [(set_attr "type" "ishiftx")
14851 (set_attr "mode" "SI")])
14852
14853 (define_insn "*<insn>si3_1_zext"
14854 [(set (match_operand:DI 0 "register_operand" "=r,r")
14855 (zero_extend:DI
14856 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
14857 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
14858 (clobber (reg:CC FLAGS_REG))]
14859 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
14860 {
14861 switch (get_attr_type (insn))
14862 {
14863 case TYPE_ISHIFTX:
14864 return "#";
14865
14866 default:
14867 if (operands[2] == const1_rtx
14868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14869 return "<shift>{l}\t%k0";
14870 else
14871 return "<shift>{l}\t{%2, %k0|%k0, %2}";
14872 }
14873 }
14874 [(set_attr "isa" "*,bmi2")
14875 (set_attr "type" "ishift,ishiftx")
14876 (set (attr "length_immediate")
14877 (if_then_else
14878 (and (match_operand 2 "const1_operand")
14879 (ior (match_test "TARGET_SHIFT1")
14880 (match_test "optimize_function_for_size_p (cfun)")))
14881 (const_string "0")
14882 (const_string "*")))
14883 (set_attr "mode" "SI")])
14884
14885 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14886 (define_split
14887 [(set (match_operand:DI 0 "register_operand")
14888 (zero_extend:DI
14889 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
14890 (match_operand:QI 2 "register_operand"))))
14891 (clobber (reg:CC FLAGS_REG))]
14892 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14893 [(set (match_dup 0)
14894 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
14895 "operands[2] = gen_lowpart (SImode, operands[2]);")
14896
14897 (define_insn "*ashr<mode>3_1"
14898 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
14899 (ashiftrt:SWI12
14900 (match_operand:SWI12 1 "nonimmediate_operand" "0")
14901 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
14902 (clobber (reg:CC FLAGS_REG))]
14903 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14904 {
14905 if (operands[2] == const1_rtx
14906 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14907 return "sar{<imodesuffix>}\t%0";
14908 else
14909 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
14910 }
14911 [(set_attr "type" "ishift")
14912 (set (attr "length_immediate")
14913 (if_then_else
14914 (and (match_operand 2 "const1_operand")
14915 (ior (match_test "TARGET_SHIFT1")
14916 (match_test "optimize_function_for_size_p (cfun)")))
14917 (const_string "0")
14918 (const_string "*")))
14919 (set_attr "mode" "<MODE>")])
14920
14921 (define_insn "*lshrqi3_1"
14922 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
14923 (lshiftrt:QI
14924 (match_operand:QI 1 "nonimmediate_operand" "0, k")
14925 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
14926 (clobber (reg:CC FLAGS_REG))]
14927 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
14928 {
14929 switch (get_attr_type (insn))
14930 {
14931 case TYPE_ISHIFT:
14932 if (operands[2] == const1_rtx
14933 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14934 return "shr{b}\t%0";
14935 else
14936 return "shr{b}\t{%2, %0|%0, %2}";
14937 case TYPE_MSKLOG:
14938 return "#";
14939 default:
14940 gcc_unreachable ();
14941 }
14942 }
14943 [(set_attr "isa" "*,avx512dq")
14944 (set_attr "type" "ishift,msklog")
14945 (set (attr "length_immediate")
14946 (if_then_else
14947 (and (and (match_operand 2 "const1_operand")
14948 (eq_attr "alternative" "0"))
14949 (ior (match_test "TARGET_SHIFT1")
14950 (match_test "optimize_function_for_size_p (cfun)")))
14951 (const_string "0")
14952 (const_string "*")))
14953 (set_attr "mode" "QI")])
14954
14955 (define_insn "*lshrhi3_1"
14956 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
14957 (lshiftrt:HI
14958 (match_operand:HI 1 "nonimmediate_operand" "0, k")
14959 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
14960 (clobber (reg:CC FLAGS_REG))]
14961 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
14962 {
14963 switch (get_attr_type (insn))
14964 {
14965 case TYPE_ISHIFT:
14966 if (operands[2] == const1_rtx
14967 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14968 return "shr{w}\t%0";
14969 else
14970 return "shr{w}\t{%2, %0|%0, %2}";
14971 case TYPE_MSKLOG:
14972 return "#";
14973 default:
14974 gcc_unreachable ();
14975 }
14976 }
14977 [(set_attr "isa" "*, avx512f")
14978 (set_attr "type" "ishift,msklog")
14979 (set (attr "length_immediate")
14980 (if_then_else
14981 (and (and (match_operand 2 "const1_operand")
14982 (eq_attr "alternative" "0"))
14983 (ior (match_test "TARGET_SHIFT1")
14984 (match_test "optimize_function_for_size_p (cfun)")))
14985 (const_string "0")
14986 (const_string "*")))
14987 (set_attr "mode" "HI")])
14988
14989 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14990 (define_insn_and_split "*<insn><mode>3_1_slp"
14991 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14992 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14993 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14994 (clobber (reg:CC FLAGS_REG))]
14995 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14996 {
14997 if (which_alternative)
14998 return "#";
14999
15000 if (operands[2] == const1_rtx
15001 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15002 return "<shift>{<imodesuffix>}\t%0";
15003 else
15004 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15005 }
15006 "&& reload_completed"
15007 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15008 (parallel
15009 [(set (strict_low_part (match_dup 0))
15010 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15011 (clobber (reg:CC FLAGS_REG))])]
15012 ""
15013 [(set_attr "type" "ishift")
15014 (set (attr "length_immediate")
15015 (if_then_else
15016 (and (match_operand 2 "const1_operand")
15017 (ior (match_test "TARGET_SHIFT1")
15018 (match_test "optimize_function_for_size_p (cfun)")))
15019 (const_string "0")
15020 (const_string "*")))
15021 (set_attr "mode" "<MODE>")])
15022
15023 ;; This pattern can't accept a variable shift count, since shifts by
15024 ;; zero don't affect the flags. We assume that shifts by constant
15025 ;; zero are optimized away.
15026 (define_insn "*<insn><mode>3_cmp"
15027 [(set (reg FLAGS_REG)
15028 (compare
15029 (any_shiftrt:SWI
15030 (match_operand:SWI 1 "nonimmediate_operand" "0")
15031 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15032 (const_int 0)))
15033 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15034 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15035 "(optimize_function_for_size_p (cfun)
15036 || !TARGET_PARTIAL_FLAG_REG_STALL
15037 || (operands[2] == const1_rtx
15038 && TARGET_SHIFT1))
15039 && ix86_match_ccmode (insn, CCGOCmode)
15040 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15041 {
15042 if (operands[2] == const1_rtx
15043 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15044 return "<shift>{<imodesuffix>}\t%0";
15045 else
15046 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15047 }
15048 [(set_attr "type" "ishift")
15049 (set (attr "length_immediate")
15050 (if_then_else
15051 (and (match_operand 2 "const1_operand")
15052 (ior (match_test "TARGET_SHIFT1")
15053 (match_test "optimize_function_for_size_p (cfun)")))
15054 (const_string "0")
15055 (const_string "*")))
15056 (set_attr "mode" "<MODE>")])
15057
15058 (define_insn "*<insn>si3_cmp_zext"
15059 [(set (reg FLAGS_REG)
15060 (compare
15061 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15062 (match_operand:QI 2 "const_1_to_31_operand"))
15063 (const_int 0)))
15064 (set (match_operand:DI 0 "register_operand" "=r")
15065 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15066 "TARGET_64BIT
15067 && (optimize_function_for_size_p (cfun)
15068 || !TARGET_PARTIAL_FLAG_REG_STALL
15069 || (operands[2] == const1_rtx
15070 && TARGET_SHIFT1))
15071 && ix86_match_ccmode (insn, CCGOCmode)
15072 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15073 {
15074 if (operands[2] == const1_rtx
15075 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15076 return "<shift>{l}\t%k0";
15077 else
15078 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15079 }
15080 [(set_attr "type" "ishift")
15081 (set (attr "length_immediate")
15082 (if_then_else
15083 (and (match_operand 2 "const1_operand")
15084 (ior (match_test "TARGET_SHIFT1")
15085 (match_test "optimize_function_for_size_p (cfun)")))
15086 (const_string "0")
15087 (const_string "*")))
15088 (set_attr "mode" "SI")])
15089
15090 (define_insn "*<insn><mode>3_cconly"
15091 [(set (reg FLAGS_REG)
15092 (compare
15093 (any_shiftrt:SWI
15094 (match_operand:SWI 1 "register_operand" "0")
15095 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15096 (const_int 0)))
15097 (clobber (match_scratch:SWI 0 "=<r>"))]
15098 "(optimize_function_for_size_p (cfun)
15099 || !TARGET_PARTIAL_FLAG_REG_STALL
15100 || (operands[2] == const1_rtx
15101 && TARGET_SHIFT1))
15102 && ix86_match_ccmode (insn, CCGOCmode)"
15103 {
15104 if (operands[2] == const1_rtx
15105 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15106 return "<shift>{<imodesuffix>}\t%0";
15107 else
15108 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15109 }
15110 [(set_attr "type" "ishift")
15111 (set (attr "length_immediate")
15112 (if_then_else
15113 (and (match_operand 2 "const1_operand")
15114 (ior (match_test "TARGET_SHIFT1")
15115 (match_test "optimize_function_for_size_p (cfun)")))
15116 (const_string "0")
15117 (const_string "*")))
15118 (set_attr "mode" "<MODE>")])
15119
15120 (define_insn "*<insn>qi_ext<mode>_2"
15121 [(set (zero_extract:SWI248
15122 (match_operand 0 "int248_register_operand" "+Q")
15123 (const_int 8)
15124 (const_int 8))
15125 (subreg:SWI248
15126 (any_shiftrt:QI
15127 (subreg:QI
15128 (match_operator:SWI248 3 "extract_operator"
15129 [(match_operand 1 "int248_register_operand" "0")
15130 (const_int 8)
15131 (const_int 8)]) 0)
15132 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
15133 (clobber (reg:CC FLAGS_REG))]
15134 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
15135 rtx_equal_p (operands[0], operands[1])"
15136 {
15137 if (operands[2] == const1_rtx
15138 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15139 return "<shift>{b}\t%h0";
15140 else
15141 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15142 }
15143 [(set_attr "type" "ishift")
15144 (set (attr "length_immediate")
15145 (if_then_else
15146 (and (match_operand 2 "const1_operand")
15147 (ior (match_test "TARGET_SHIFT1")
15148 (match_test "optimize_function_for_size_p (cfun)")))
15149 (const_string "0")
15150 (const_string "*")))
15151 (set_attr "mode" "QI")])
15152 \f
15153 ;; Rotate instructions
15154
15155 (define_expand "<insn>ti3"
15156 [(set (match_operand:TI 0 "register_operand")
15157 (any_rotate:TI (match_operand:TI 1 "register_operand")
15158 (match_operand:QI 2 "nonmemory_operand")))]
15159 "TARGET_64BIT"
15160 {
15161 if (const_1_to_63_operand (operands[2], VOIDmode))
15162 emit_insn (gen_ix86_<insn>ti3_doubleword
15163 (operands[0], operands[1], operands[2]));
15164 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15165 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15166 else
15167 {
15168 rtx amount = force_reg (QImode, operands[2]);
15169 rtx src_lo = gen_lowpart (DImode, operands[1]);
15170 rtx src_hi = gen_highpart (DImode, operands[1]);
15171 rtx tmp_lo = gen_reg_rtx (DImode);
15172 rtx tmp_hi = gen_reg_rtx (DImode);
15173 emit_move_insn (tmp_lo, src_lo);
15174 emit_move_insn (tmp_hi, src_hi);
15175 rtx (*shiftd) (rtx, rtx, rtx)
15176 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15177 emit_insn (shiftd (tmp_lo, src_hi, amount));
15178 emit_insn (shiftd (tmp_hi, src_lo, amount));
15179 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15180 rtx dst_hi = gen_highpart (DImode, operands[0]);
15181 emit_move_insn (dst_lo, tmp_lo);
15182 emit_move_insn (dst_hi, tmp_hi);
15183 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15184 }
15185 DONE;
15186 })
15187
15188 (define_expand "<insn>di3"
15189 [(set (match_operand:DI 0 "shiftdi_operand")
15190 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15191 (match_operand:QI 2 "nonmemory_operand")))]
15192 ""
15193 {
15194 if (TARGET_64BIT)
15195 ix86_expand_binary_operator (<CODE>, DImode, operands);
15196 else if (const_1_to_31_operand (operands[2], VOIDmode))
15197 emit_insn (gen_ix86_<insn>di3_doubleword
15198 (operands[0], operands[1], operands[2]));
15199 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15200 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15201 else
15202 FAIL;
15203
15204 DONE;
15205 })
15206
15207 (define_expand "<insn><mode>3"
15208 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15209 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15210 (match_operand:QI 2 "nonmemory_operand")))]
15211 ""
15212 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15213
15214 ;; Avoid useless masking of count operand.
15215 (define_insn_and_split "*<insn><mode>3_mask"
15216 [(set (match_operand:SWI 0 "nonimmediate_operand")
15217 (any_rotate:SWI
15218 (match_operand:SWI 1 "nonimmediate_operand")
15219 (subreg:QI
15220 (and
15221 (match_operand 2 "int248_register_operand" "c")
15222 (match_operand 3 "const_int_operand")) 0)))
15223 (clobber (reg:CC FLAGS_REG))]
15224 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15225 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15226 == GET_MODE_BITSIZE (<MODE>mode)-1
15227 && ix86_pre_reload_split ()"
15228 "#"
15229 "&& 1"
15230 [(parallel
15231 [(set (match_dup 0)
15232 (any_rotate:SWI (match_dup 1)
15233 (match_dup 2)))
15234 (clobber (reg:CC FLAGS_REG))])]
15235 {
15236 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15237 operands[2] = gen_lowpart (QImode, operands[2]);
15238 })
15239
15240 (define_split
15241 [(set (match_operand:SWI 0 "register_operand")
15242 (any_rotate:SWI
15243 (match_operand:SWI 1 "const_int_operand")
15244 (subreg:QI
15245 (and
15246 (match_operand 2 "int248_register_operand")
15247 (match_operand 3 "const_int_operand")) 0)))]
15248 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15249 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15250 [(set (match_dup 4) (match_dup 1))
15251 (set (match_dup 0)
15252 (any_rotate:SWI (match_dup 4)
15253 (subreg:QI (match_dup 2) 0)))]
15254 "operands[4] = gen_reg_rtx (<MODE>mode);")
15255
15256 (define_insn_and_split "*<insn><mode>3_mask_1"
15257 [(set (match_operand:SWI 0 "nonimmediate_operand")
15258 (any_rotate:SWI
15259 (match_operand:SWI 1 "nonimmediate_operand")
15260 (and:QI
15261 (match_operand:QI 2 "register_operand" "c")
15262 (match_operand:QI 3 "const_int_operand"))))
15263 (clobber (reg:CC FLAGS_REG))]
15264 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15265 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15266 == GET_MODE_BITSIZE (<MODE>mode)-1
15267 && ix86_pre_reload_split ()"
15268 "#"
15269 "&& 1"
15270 [(parallel
15271 [(set (match_dup 0)
15272 (any_rotate:SWI (match_dup 1)
15273 (match_dup 2)))
15274 (clobber (reg:CC FLAGS_REG))])])
15275
15276 (define_split
15277 [(set (match_operand:SWI 0 "register_operand")
15278 (any_rotate:SWI
15279 (match_operand:SWI 1 "const_int_operand")
15280 (and:QI
15281 (match_operand:QI 2 "register_operand")
15282 (match_operand:QI 3 "const_int_operand"))))]
15283 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15284 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15285 [(set (match_dup 4) (match_dup 1))
15286 (set (match_dup 0)
15287 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15288 "operands[4] = gen_reg_rtx (<MODE>mode);")
15289
15290 ;; Implement rotation using two double-precision
15291 ;; shift instructions and a scratch register.
15292
15293 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15294 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15295 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15296 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15297 (clobber (reg:CC FLAGS_REG))
15298 (clobber (match_scratch:DWIH 3 "=&r"))]
15299 ""
15300 "#"
15301 "reload_completed"
15302 [(set (match_dup 3) (match_dup 4))
15303 (parallel
15304 [(set (match_dup 4)
15305 (ior:DWIH (ashift:DWIH (match_dup 4)
15306 (and:QI (match_dup 2) (match_dup 6)))
15307 (subreg:DWIH
15308 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15309 (minus:QI (match_dup 7)
15310 (and:QI (match_dup 2)
15311 (match_dup 6)))) 0)))
15312 (clobber (reg:CC FLAGS_REG))])
15313 (parallel
15314 [(set (match_dup 5)
15315 (ior:DWIH (ashift:DWIH (match_dup 5)
15316 (and:QI (match_dup 2) (match_dup 6)))
15317 (subreg:DWIH
15318 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15319 (minus:QI (match_dup 7)
15320 (and:QI (match_dup 2)
15321 (match_dup 6)))) 0)))
15322 (clobber (reg:CC FLAGS_REG))])]
15323 {
15324 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15325 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15326
15327 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15328 })
15329
15330 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15331 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15332 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15333 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15334 (clobber (reg:CC FLAGS_REG))
15335 (clobber (match_scratch:DWIH 3 "=&r"))]
15336 ""
15337 "#"
15338 "reload_completed"
15339 [(set (match_dup 3) (match_dup 4))
15340 (parallel
15341 [(set (match_dup 4)
15342 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15343 (and:QI (match_dup 2) (match_dup 6)))
15344 (subreg:DWIH
15345 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15346 (minus:QI (match_dup 7)
15347 (and:QI (match_dup 2)
15348 (match_dup 6)))) 0)))
15349 (clobber (reg:CC FLAGS_REG))])
15350 (parallel
15351 [(set (match_dup 5)
15352 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15353 (and:QI (match_dup 2) (match_dup 6)))
15354 (subreg:DWIH
15355 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15356 (minus:QI (match_dup 7)
15357 (and:QI (match_dup 2)
15358 (match_dup 6)))) 0)))
15359 (clobber (reg:CC FLAGS_REG))])]
15360 {
15361 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15362 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15363
15364 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15365 })
15366
15367 (define_insn_and_split "<insn>32di2_doubleword"
15368 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
15369 (any_rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,r,o")
15370 (const_int 32)))]
15371 "!TARGET_64BIT"
15372 "#"
15373 "&& reload_completed"
15374 [(set (match_dup 0) (match_dup 3))
15375 (set (match_dup 2) (match_dup 1))]
15376 {
15377 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15378 if (rtx_equal_p (operands[0], operands[1]))
15379 {
15380 emit_insn (gen_swapsi (operands[0], operands[2]));
15381 DONE;
15382 }
15383 })
15384
15385 (define_insn_and_split "<insn>64ti2_doubleword"
15386 [(set (match_operand:TI 0 "register_operand" "=r,r,r")
15387 (any_rotate:TI (match_operand:TI 1 "nonimmediate_operand" "0,r,o")
15388 (const_int 64)))]
15389 "TARGET_64BIT"
15390 "#"
15391 "&& reload_completed"
15392 [(set (match_dup 0) (match_dup 3))
15393 (set (match_dup 2) (match_dup 1))]
15394 {
15395 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15396 if (rtx_equal_p (operands[0], operands[1]))
15397 {
15398 emit_insn (gen_swapdi (operands[0], operands[2]));
15399 DONE;
15400 }
15401 })
15402
15403 (define_mode_attr rorx_immediate_operand
15404 [(SI "const_0_to_31_operand")
15405 (DI "const_0_to_63_operand")])
15406
15407 (define_insn "*bmi2_rorx<mode>3_1"
15408 [(set (match_operand:SWI48 0 "register_operand" "=r")
15409 (rotatert:SWI48
15410 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15411 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15412 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15413 "rorx\t{%2, %1, %0|%0, %1, %2}"
15414 [(set_attr "type" "rotatex")
15415 (set_attr "mode" "<MODE>")])
15416
15417 (define_insn "*<insn><mode>3_1"
15418 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15419 (any_rotate:SWI48
15420 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15421 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15422 (clobber (reg:CC FLAGS_REG))]
15423 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15424 {
15425 switch (get_attr_type (insn))
15426 {
15427 case TYPE_ROTATEX:
15428 return "#";
15429
15430 default:
15431 if (operands[2] == const1_rtx
15432 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15433 return "<rotate>{<imodesuffix>}\t%0";
15434 else
15435 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15436 }
15437 }
15438 [(set_attr "isa" "*,bmi2")
15439 (set_attr "type" "rotate,rotatex")
15440 (set (attr "preferred_for_size")
15441 (cond [(eq_attr "alternative" "0")
15442 (symbol_ref "true")]
15443 (symbol_ref "false")))
15444 (set (attr "length_immediate")
15445 (if_then_else
15446 (and (eq_attr "type" "rotate")
15447 (and (match_operand 2 "const1_operand")
15448 (ior (match_test "TARGET_SHIFT1")
15449 (match_test "optimize_function_for_size_p (cfun)"))))
15450 (const_string "0")
15451 (const_string "*")))
15452 (set_attr "mode" "<MODE>")])
15453
15454 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15455 (define_split
15456 [(set (match_operand:SWI48 0 "register_operand")
15457 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15458 (match_operand:QI 2 "const_int_operand")))
15459 (clobber (reg:CC FLAGS_REG))]
15460 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15461 [(set (match_dup 0)
15462 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15463 {
15464 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15465
15466 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15467 })
15468
15469 (define_split
15470 [(set (match_operand:SWI48 0 "register_operand")
15471 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15472 (match_operand:QI 2 "const_int_operand")))
15473 (clobber (reg:CC FLAGS_REG))]
15474 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15475 [(set (match_dup 0)
15476 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15477
15478 (define_insn "*bmi2_rorxsi3_1_zext"
15479 [(set (match_operand:DI 0 "register_operand" "=r")
15480 (zero_extend:DI
15481 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15482 (match_operand:QI 2 "const_0_to_31_operand"))))]
15483 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15484 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
15485 [(set_attr "type" "rotatex")
15486 (set_attr "mode" "SI")])
15487
15488 (define_insn "*<insn>si3_1_zext"
15489 [(set (match_operand:DI 0 "register_operand" "=r,r")
15490 (zero_extend:DI
15491 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15492 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
15493 (clobber (reg:CC FLAGS_REG))]
15494 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15495 {
15496 switch (get_attr_type (insn))
15497 {
15498 case TYPE_ROTATEX:
15499 return "#";
15500
15501 default:
15502 if (operands[2] == const1_rtx
15503 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15504 return "<rotate>{l}\t%k0";
15505 else
15506 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
15507 }
15508 }
15509 [(set_attr "isa" "*,bmi2")
15510 (set_attr "type" "rotate,rotatex")
15511 (set (attr "preferred_for_size")
15512 (cond [(eq_attr "alternative" "0")
15513 (symbol_ref "true")]
15514 (symbol_ref "false")))
15515 (set (attr "length_immediate")
15516 (if_then_else
15517 (and (eq_attr "type" "rotate")
15518 (and (match_operand 2 "const1_operand")
15519 (ior (match_test "TARGET_SHIFT1")
15520 (match_test "optimize_function_for_size_p (cfun)"))))
15521 (const_string "0")
15522 (const_string "*")))
15523 (set_attr "mode" "SI")])
15524
15525 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15526 (define_split
15527 [(set (match_operand:DI 0 "register_operand")
15528 (zero_extend:DI
15529 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
15530 (match_operand:QI 2 "const_int_operand"))))
15531 (clobber (reg:CC FLAGS_REG))]
15532 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15533 && !optimize_function_for_size_p (cfun)"
15534 [(set (match_dup 0)
15535 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
15536 {
15537 int bitsize = GET_MODE_BITSIZE (SImode);
15538
15539 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15540 })
15541
15542 (define_split
15543 [(set (match_operand:DI 0 "register_operand")
15544 (zero_extend:DI
15545 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
15546 (match_operand:QI 2 "const_int_operand"))))
15547 (clobber (reg:CC FLAGS_REG))]
15548 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15549 && !optimize_function_for_size_p (cfun)"
15550 [(set (match_dup 0)
15551 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
15552
15553 (define_insn "*<insn><mode>3_1"
15554 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15555 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15556 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15557 (clobber (reg:CC FLAGS_REG))]
15558 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15559 {
15560 if (operands[2] == const1_rtx
15561 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15562 return "<rotate>{<imodesuffix>}\t%0";
15563 else
15564 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15565 }
15566 [(set_attr "type" "rotate")
15567 (set (attr "length_immediate")
15568 (if_then_else
15569 (and (match_operand 2 "const1_operand")
15570 (ior (match_test "TARGET_SHIFT1")
15571 (match_test "optimize_function_for_size_p (cfun)")))
15572 (const_string "0")
15573 (const_string "*")))
15574 (set_attr "mode" "<MODE>")])
15575
15576 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15577 (define_insn_and_split "*<insn><mode>3_1_slp"
15578 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15579 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15580 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15581 (clobber (reg:CC FLAGS_REG))]
15582 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15583 {
15584 if (which_alternative)
15585 return "#";
15586
15587 if (operands[2] == const1_rtx
15588 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15589 return "<rotate>{<imodesuffix>}\t%0";
15590 else
15591 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15592 }
15593 "&& reload_completed"
15594 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15595 (parallel
15596 [(set (strict_low_part (match_dup 0))
15597 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
15598 (clobber (reg:CC FLAGS_REG))])]
15599 ""
15600 [(set_attr "type" "rotate")
15601 (set (attr "length_immediate")
15602 (if_then_else
15603 (and (match_operand 2 "const1_operand")
15604 (ior (match_test "TARGET_SHIFT1")
15605 (match_test "optimize_function_for_size_p (cfun)")))
15606 (const_string "0")
15607 (const_string "*")))
15608 (set_attr "mode" "<MODE>")])
15609
15610 (define_split
15611 [(set (match_operand:HI 0 "QIreg_operand")
15612 (any_rotate:HI (match_dup 0) (const_int 8)))
15613 (clobber (reg:CC FLAGS_REG))]
15614 "reload_completed
15615 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
15616 [(parallel [(set (strict_low_part (match_dup 0))
15617 (bswap:HI (match_dup 0)))
15618 (clobber (reg:CC FLAGS_REG))])])
15619 \f
15620 ;; Bit set / bit test instructions
15621
15622 ;; %%% bts, btr, btc
15623
15624 ;; These instructions are *slow* when applied to memory.
15625
15626 (define_code_attr btsc [(ior "bts") (xor "btc")])
15627
15628 (define_insn "*<btsc><mode>"
15629 [(set (match_operand:SWI48 0 "register_operand" "=r")
15630 (any_or:SWI48
15631 (ashift:SWI48 (const_int 1)
15632 (match_operand:QI 2 "register_operand" "r"))
15633 (match_operand:SWI48 1 "register_operand" "0")))
15634 (clobber (reg:CC FLAGS_REG))]
15635 "TARGET_USE_BT"
15636 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15637 [(set_attr "type" "alu1")
15638 (set_attr "prefix_0f" "1")
15639 (set_attr "znver1_decode" "double")
15640 (set_attr "mode" "<MODE>")])
15641
15642 ;; Avoid useless masking of count operand.
15643 (define_insn_and_split "*<btsc><mode>_mask"
15644 [(set (match_operand:SWI48 0 "register_operand")
15645 (any_or:SWI48
15646 (ashift:SWI48
15647 (const_int 1)
15648 (subreg:QI
15649 (and
15650 (match_operand 1 "int248_register_operand")
15651 (match_operand 2 "const_int_operand")) 0))
15652 (match_operand:SWI48 3 "register_operand")))
15653 (clobber (reg:CC FLAGS_REG))]
15654 "TARGET_USE_BT
15655 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15656 == GET_MODE_BITSIZE (<MODE>mode)-1
15657 && ix86_pre_reload_split ()"
15658 "#"
15659 "&& 1"
15660 [(parallel
15661 [(set (match_dup 0)
15662 (any_or:SWI48
15663 (ashift:SWI48 (const_int 1)
15664 (match_dup 1))
15665 (match_dup 3)))
15666 (clobber (reg:CC FLAGS_REG))])]
15667 {
15668 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
15669 operands[1] = gen_lowpart (QImode, operands[1]);
15670 })
15671
15672 (define_insn_and_split "*<btsc><mode>_mask_1"
15673 [(set (match_operand:SWI48 0 "register_operand")
15674 (any_or:SWI48
15675 (ashift:SWI48
15676 (const_int 1)
15677 (and:QI
15678 (match_operand:QI 1 "register_operand")
15679 (match_operand:QI 2 "const_int_operand")))
15680 (match_operand:SWI48 3 "register_operand")))
15681 (clobber (reg:CC FLAGS_REG))]
15682 "TARGET_USE_BT
15683 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15684 == GET_MODE_BITSIZE (<MODE>mode)-1
15685 && ix86_pre_reload_split ()"
15686 "#"
15687 "&& 1"
15688 [(parallel
15689 [(set (match_dup 0)
15690 (any_or:SWI48
15691 (ashift:SWI48 (const_int 1)
15692 (match_dup 1))
15693 (match_dup 3)))
15694 (clobber (reg:CC FLAGS_REG))])])
15695
15696 (define_insn "*btr<mode>"
15697 [(set (match_operand:SWI48 0 "register_operand" "=r")
15698 (and:SWI48
15699 (rotate:SWI48 (const_int -2)
15700 (match_operand:QI 2 "register_operand" "r"))
15701 (match_operand:SWI48 1 "register_operand" "0")))
15702 (clobber (reg:CC FLAGS_REG))]
15703 "TARGET_USE_BT"
15704 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15705 [(set_attr "type" "alu1")
15706 (set_attr "prefix_0f" "1")
15707 (set_attr "znver1_decode" "double")
15708 (set_attr "mode" "<MODE>")])
15709
15710 ;; Avoid useless masking of count operand.
15711 (define_insn_and_split "*btr<mode>_mask"
15712 [(set (match_operand:SWI48 0 "register_operand")
15713 (and:SWI48
15714 (rotate:SWI48
15715 (const_int -2)
15716 (subreg:QI
15717 (and
15718 (match_operand 1 "int248_register_operand")
15719 (match_operand 2 "const_int_operand")) 0))
15720 (match_operand:SWI48 3 "register_operand")))
15721 (clobber (reg:CC FLAGS_REG))]
15722 "TARGET_USE_BT
15723 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15724 == GET_MODE_BITSIZE (<MODE>mode)-1
15725 && ix86_pre_reload_split ()"
15726 "#"
15727 "&& 1"
15728 [(parallel
15729 [(set (match_dup 0)
15730 (and:SWI48
15731 (rotate:SWI48 (const_int -2)
15732 (match_dup 1))
15733 (match_dup 3)))
15734 (clobber (reg:CC FLAGS_REG))])]
15735 {
15736 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
15737 operands[1] = gen_lowpart (QImode, operands[1]);
15738 })
15739
15740 (define_insn_and_split "*btr<mode>_mask_1"
15741 [(set (match_operand:SWI48 0 "register_operand")
15742 (and:SWI48
15743 (rotate:SWI48
15744 (const_int -2)
15745 (and:QI
15746 (match_operand:QI 1 "register_operand")
15747 (match_operand:QI 2 "const_int_operand")))
15748 (match_operand:SWI48 3 "register_operand")))
15749 (clobber (reg:CC FLAGS_REG))]
15750 "TARGET_USE_BT
15751 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15752 == GET_MODE_BITSIZE (<MODE>mode)-1
15753 && ix86_pre_reload_split ()"
15754 "#"
15755 "&& 1"
15756 [(parallel
15757 [(set (match_dup 0)
15758 (and:SWI48
15759 (rotate:SWI48 (const_int -2)
15760 (match_dup 1))
15761 (match_dup 3)))
15762 (clobber (reg:CC FLAGS_REG))])])
15763
15764 (define_insn_and_split "*btr<mode>_1"
15765 [(set (match_operand:SWI12 0 "register_operand")
15766 (and:SWI12
15767 (subreg:SWI12
15768 (rotate:SI (const_int -2)
15769 (match_operand:QI 2 "register_operand")) 0)
15770 (match_operand:SWI12 1 "nonimmediate_operand")))
15771 (clobber (reg:CC FLAGS_REG))]
15772 "TARGET_USE_BT && ix86_pre_reload_split ()"
15773 "#"
15774 "&& 1"
15775 [(parallel
15776 [(set (match_dup 0)
15777 (and:SI (rotate:SI (const_int -2) (match_dup 2))
15778 (match_dup 1)))
15779 (clobber (reg:CC FLAGS_REG))])]
15780 {
15781 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15782 operands[1] = force_reg (<MODE>mode, operands[1]);
15783 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
15784 })
15785
15786 (define_insn_and_split "*btr<mode>_2"
15787 [(set (zero_extract:HI
15788 (match_operand:SWI12 0 "nonimmediate_operand")
15789 (const_int 1)
15790 (zero_extend:SI (match_operand:QI 1 "register_operand")))
15791 (const_int 0))
15792 (clobber (reg:CC FLAGS_REG))]
15793 "TARGET_USE_BT && ix86_pre_reload_split ()"
15794 "#"
15795 "&& MEM_P (operands[0])"
15796 [(set (match_dup 2) (match_dup 0))
15797 (parallel
15798 [(set (match_dup 3)
15799 (and:SI (rotate:SI (const_int -2) (match_dup 1))
15800 (match_dup 4)))
15801 (clobber (reg:CC FLAGS_REG))])
15802 (set (match_dup 0) (match_dup 5))]
15803 {
15804 operands[2] = gen_reg_rtx (<MODE>mode);
15805 operands[5] = gen_reg_rtx (<MODE>mode);
15806 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
15807 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
15808 })
15809
15810 (define_split
15811 [(set (zero_extract:HI
15812 (match_operand:SWI12 0 "register_operand")
15813 (const_int 1)
15814 (zero_extend:SI (match_operand:QI 1 "register_operand")))
15815 (const_int 0))
15816 (clobber (reg:CC FLAGS_REG))]
15817 "TARGET_USE_BT && ix86_pre_reload_split ()"
15818 [(parallel
15819 [(set (match_dup 0)
15820 (and:SI (rotate:SI (const_int -2) (match_dup 1))
15821 (match_dup 2)))
15822 (clobber (reg:CC FLAGS_REG))])]
15823 {
15824 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15825 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15826 })
15827
15828 ;; These instructions are never faster than the corresponding
15829 ;; and/ior/xor operations when using immediate operand, so with
15830 ;; 32-bit there's no point. But in 64-bit, we can't hold the
15831 ;; relevant immediates within the instruction itself, so operating
15832 ;; on bits in the high 32-bits of a register becomes easier.
15833 ;;
15834 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
15835 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
15836 ;; negdf respectively, so they can never be disabled entirely.
15837
15838 (define_insn "*btsq_imm"
15839 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
15840 (const_int 1)
15841 (match_operand 1 "const_0_to_63_operand"))
15842 (const_int 1))
15843 (clobber (reg:CC FLAGS_REG))]
15844 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
15845 "bts{q}\t{%1, %0|%0, %1}"
15846 [(set_attr "type" "alu1")
15847 (set_attr "prefix_0f" "1")
15848 (set_attr "znver1_decode" "double")
15849 (set_attr "mode" "DI")])
15850
15851 (define_insn "*btrq_imm"
15852 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
15853 (const_int 1)
15854 (match_operand 1 "const_0_to_63_operand"))
15855 (const_int 0))
15856 (clobber (reg:CC FLAGS_REG))]
15857 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
15858 "btr{q}\t{%1, %0|%0, %1}"
15859 [(set_attr "type" "alu1")
15860 (set_attr "prefix_0f" "1")
15861 (set_attr "znver1_decode" "double")
15862 (set_attr "mode" "DI")])
15863
15864 (define_insn "*btcq_imm"
15865 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
15866 (const_int 1)
15867 (match_operand 1 "const_0_to_63_operand"))
15868 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
15869 (clobber (reg:CC FLAGS_REG))]
15870 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
15871 "btc{q}\t{%1, %0|%0, %1}"
15872 [(set_attr "type" "alu1")
15873 (set_attr "prefix_0f" "1")
15874 (set_attr "znver1_decode" "double")
15875 (set_attr "mode" "DI")])
15876
15877 ;; Allow Nocona to avoid these instructions if a register is available.
15878
15879 (define_peephole2
15880 [(match_scratch:DI 2 "r")
15881 (parallel [(set (zero_extract:DI
15882 (match_operand:DI 0 "nonimmediate_operand")
15883 (const_int 1)
15884 (match_operand 1 "const_0_to_63_operand"))
15885 (const_int 1))
15886 (clobber (reg:CC FLAGS_REG))])]
15887 "TARGET_64BIT && !TARGET_USE_BT"
15888 [(parallel [(set (match_dup 0)
15889 (ior:DI (match_dup 0) (match_dup 3)))
15890 (clobber (reg:CC FLAGS_REG))])]
15891 {
15892 int i = INTVAL (operands[1]);
15893
15894 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
15895
15896 if (!x86_64_immediate_operand (operands[3], DImode))
15897 {
15898 emit_move_insn (operands[2], operands[3]);
15899 operands[3] = operands[2];
15900 }
15901 })
15902
15903 (define_peephole2
15904 [(match_scratch:DI 2 "r")
15905 (parallel [(set (zero_extract:DI
15906 (match_operand:DI 0 "nonimmediate_operand")
15907 (const_int 1)
15908 (match_operand 1 "const_0_to_63_operand"))
15909 (const_int 0))
15910 (clobber (reg:CC FLAGS_REG))])]
15911 "TARGET_64BIT && !TARGET_USE_BT"
15912 [(parallel [(set (match_dup 0)
15913 (and:DI (match_dup 0) (match_dup 3)))
15914 (clobber (reg:CC FLAGS_REG))])]
15915 {
15916 int i = INTVAL (operands[1]);
15917
15918 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
15919
15920 if (!x86_64_immediate_operand (operands[3], DImode))
15921 {
15922 emit_move_insn (operands[2], operands[3]);
15923 operands[3] = operands[2];
15924 }
15925 })
15926
15927 (define_peephole2
15928 [(match_scratch:DI 2 "r")
15929 (parallel [(set (zero_extract:DI
15930 (match_operand:DI 0 "nonimmediate_operand")
15931 (const_int 1)
15932 (match_operand 1 "const_0_to_63_operand"))
15933 (not:DI (zero_extract:DI
15934 (match_dup 0) (const_int 1) (match_dup 1))))
15935 (clobber (reg:CC FLAGS_REG))])]
15936 "TARGET_64BIT && !TARGET_USE_BT"
15937 [(parallel [(set (match_dup 0)
15938 (xor:DI (match_dup 0) (match_dup 3)))
15939 (clobber (reg:CC FLAGS_REG))])]
15940 {
15941 int i = INTVAL (operands[1]);
15942
15943 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
15944
15945 if (!x86_64_immediate_operand (operands[3], DImode))
15946 {
15947 emit_move_insn (operands[2], operands[3]);
15948 operands[3] = operands[2];
15949 }
15950 })
15951
15952 ;; %%% bt
15953
15954 (define_insn "*bt<mode>"
15955 [(set (reg:CCC FLAGS_REG)
15956 (compare:CCC
15957 (zero_extract:SWI48
15958 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
15959 (const_int 1)
15960 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
15961 (const_int 0)))]
15962 ""
15963 {
15964 switch (get_attr_mode (insn))
15965 {
15966 case MODE_SI:
15967 return "bt{l}\t{%1, %k0|%k0, %1}";
15968
15969 case MODE_DI:
15970 return "bt{q}\t{%q1, %0|%0, %q1}";
15971
15972 default:
15973 gcc_unreachable ();
15974 }
15975 }
15976 [(set_attr "type" "alu1")
15977 (set_attr "prefix_0f" "1")
15978 (set (attr "mode")
15979 (if_then_else
15980 (and (match_test "CONST_INT_P (operands[1])")
15981 (match_test "INTVAL (operands[1]) < 32"))
15982 (const_string "SI")
15983 (const_string "<MODE>")))])
15984
15985 (define_insn_and_split "*jcc_bt<mode>"
15986 [(set (pc)
15987 (if_then_else (match_operator 0 "bt_comparison_operator"
15988 [(zero_extract:SWI48
15989 (match_operand:SWI48 1 "nonimmediate_operand")
15990 (const_int 1)
15991 (match_operand:SI 2 "nonmemory_operand"))
15992 (const_int 0)])
15993 (label_ref (match_operand 3))
15994 (pc)))
15995 (clobber (reg:CC FLAGS_REG))]
15996 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
15997 && (CONST_INT_P (operands[2])
15998 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
15999 && INTVAL (operands[2])
16000 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16001 : !memory_operand (operands[1], <MODE>mode))
16002 && ix86_pre_reload_split ()"
16003 "#"
16004 "&& 1"
16005 [(set (reg:CCC FLAGS_REG)
16006 (compare:CCC
16007 (zero_extract:SWI48
16008 (match_dup 1)
16009 (const_int 1)
16010 (match_dup 2))
16011 (const_int 0)))
16012 (set (pc)
16013 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16014 (label_ref (match_dup 3))
16015 (pc)))]
16016 {
16017 operands[0] = shallow_copy_rtx (operands[0]);
16018 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16019 })
16020
16021 (define_insn_and_split "*jcc_bt<mode>_1"
16022 [(set (pc)
16023 (if_then_else (match_operator 0 "bt_comparison_operator"
16024 [(zero_extract:SWI48
16025 (match_operand:SWI48 1 "register_operand")
16026 (const_int 1)
16027 (zero_extend:SI
16028 (match_operand:QI 2 "register_operand")))
16029 (const_int 0)])
16030 (label_ref (match_operand 3))
16031 (pc)))
16032 (clobber (reg:CC FLAGS_REG))]
16033 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16034 && ix86_pre_reload_split ()"
16035 "#"
16036 "&& 1"
16037 [(set (reg:CCC FLAGS_REG)
16038 (compare:CCC
16039 (zero_extract:SWI48
16040 (match_dup 1)
16041 (const_int 1)
16042 (match_dup 2))
16043 (const_int 0)))
16044 (set (pc)
16045 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16046 (label_ref (match_dup 3))
16047 (pc)))]
16048 {
16049 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16050 operands[0] = shallow_copy_rtx (operands[0]);
16051 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16052 })
16053
16054 ;; Avoid useless masking of bit offset operand.
16055 (define_insn_and_split "*jcc_bt<mode>_mask"
16056 [(set (pc)
16057 (if_then_else (match_operator 0 "bt_comparison_operator"
16058 [(zero_extract:SWI48
16059 (match_operand:SWI48 1 "register_operand")
16060 (const_int 1)
16061 (and:SI
16062 (match_operand:SI 2 "register_operand")
16063 (match_operand 3 "const_int_operand")))])
16064 (label_ref (match_operand 4))
16065 (pc)))
16066 (clobber (reg:CC FLAGS_REG))]
16067 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16068 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16069 == GET_MODE_BITSIZE (<MODE>mode)-1
16070 && ix86_pre_reload_split ()"
16071 "#"
16072 "&& 1"
16073 [(set (reg:CCC FLAGS_REG)
16074 (compare:CCC
16075 (zero_extract:SWI48
16076 (match_dup 1)
16077 (const_int 1)
16078 (match_dup 2))
16079 (const_int 0)))
16080 (set (pc)
16081 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16082 (label_ref (match_dup 4))
16083 (pc)))]
16084 {
16085 operands[0] = shallow_copy_rtx (operands[0]);
16086 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16087 })
16088
16089 (define_insn_and_split "*jcc_bt<mode>_mask_1"
16090 [(set (pc)
16091 (if_then_else (match_operator 0 "bt_comparison_operator"
16092 [(zero_extract:SWI48
16093 (match_operand:SWI48 1 "register_operand")
16094 (const_int 1)
16095 (zero_extend:SI
16096 (subreg:QI
16097 (and
16098 (match_operand 2 "int248_register_operand")
16099 (match_operand 3 "const_int_operand")) 0)))])
16100 (label_ref (match_operand 4))
16101 (pc)))
16102 (clobber (reg:CC FLAGS_REG))]
16103 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16104 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16105 == GET_MODE_BITSIZE (<MODE>mode)-1
16106 && ix86_pre_reload_split ()"
16107 "#"
16108 "&& 1"
16109 [(set (reg:CCC FLAGS_REG)
16110 (compare:CCC
16111 (zero_extract:SWI48
16112 (match_dup 1)
16113 (const_int 1)
16114 (match_dup 2))
16115 (const_int 0)))
16116 (set (pc)
16117 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16118 (label_ref (match_dup 4))
16119 (pc)))]
16120 {
16121 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16122 operands[2] = gen_lowpart (SImode, operands[2]);
16123 operands[0] = shallow_copy_rtx (operands[0]);
16124 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16125 })
16126
16127 ;; Help combine recognize bt followed by cmov
16128 (define_split
16129 [(set (match_operand:SWI248 0 "register_operand")
16130 (if_then_else:SWI248
16131 (match_operator 5 "bt_comparison_operator"
16132 [(zero_extract:SWI48
16133 (match_operand:SWI48 1 "register_operand")
16134 (const_int 1)
16135 (zero_extend:SI (match_operand:QI 2 "register_operand")))
16136 (const_int 0)])
16137 (match_operand:SWI248 3 "nonimmediate_operand")
16138 (match_operand:SWI248 4 "nonimmediate_operand")))]
16139 "TARGET_USE_BT && TARGET_CMOVE
16140 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16141 && ix86_pre_reload_split ()"
16142 [(set (reg:CCC FLAGS_REG)
16143 (compare:CCC
16144 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16145 (const_int 0)))
16146 (set (match_dup 0)
16147 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16148 (match_dup 3)
16149 (match_dup 4)))]
16150 {
16151 if (GET_CODE (operands[5]) == EQ)
16152 std::swap (operands[3], operands[4]);
16153 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16154 })
16155
16156 ;; Help combine recognize bt followed by setc
16157 (define_insn_and_split "*bt<mode>_setcqi"
16158 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16159 (zero_extract:SWI48
16160 (match_operand:SWI48 1 "register_operand")
16161 (const_int 1)
16162 (zero_extend:SI (match_operand:QI 2 "register_operand"))))
16163 (clobber (reg:CC FLAGS_REG))]
16164 "TARGET_USE_BT && ix86_pre_reload_split ()"
16165 "#"
16166 "&& 1"
16167 [(set (reg:CCC FLAGS_REG)
16168 (compare:CCC
16169 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16170 (const_int 0)))
16171 (set (match_dup 0)
16172 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16173 {
16174 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16175 })
16176
16177 ;; Help combine recognize bt followed by setnc
16178 (define_insn_and_split "*bt<mode>_setncqi"
16179 [(set (match_operand:QI 0 "register_operand")
16180 (and:QI
16181 (not:QI
16182 (subreg:QI
16183 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16184 (match_operand:QI 2 "register_operand")) 0))
16185 (const_int 1)))
16186 (clobber (reg:CC FLAGS_REG))]
16187 "TARGET_USE_BT && ix86_pre_reload_split ()"
16188 "#"
16189 "&& 1"
16190 [(set (reg:CCC FLAGS_REG)
16191 (compare:CCC
16192 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16193 (const_int 0)))
16194 (set (match_dup 0)
16195 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16196 {
16197 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16198 })
16199
16200 (define_insn_and_split "*bt<mode>_setnc<mode>"
16201 [(set (match_operand:SWI48 0 "register_operand")
16202 (and:SWI48
16203 (not:SWI48
16204 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16205 (match_operand:QI 2 "register_operand")))
16206 (const_int 1)))
16207 (clobber (reg:CC FLAGS_REG))]
16208 "TARGET_USE_BT && ix86_pre_reload_split ()"
16209 "#"
16210 "&& 1"
16211 [(set (reg:CCC FLAGS_REG)
16212 (compare:CCC
16213 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16214 (const_int 0)))
16215 (set (match_dup 3)
16216 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16217 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16218 {
16219 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16220 operands[3] = gen_reg_rtx (QImode);
16221 })
16222 \f
16223 ;; Store-flag instructions.
16224
16225 (define_split
16226 [(set (match_operand:QI 0 "nonimmediate_operand")
16227 (match_operator:QI 1 "add_comparison_operator"
16228 [(not:SWI (match_operand:SWI 2 "register_operand"))
16229 (match_operand:SWI 3 "nonimmediate_operand")]))]
16230 ""
16231 [(set (reg:CCC FLAGS_REG)
16232 (compare:CCC
16233 (plus:SWI (match_dup 2) (match_dup 3))
16234 (match_dup 2)))
16235 (set (match_dup 0)
16236 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16237
16238 (define_split
16239 [(set (match_operand:QI 0 "nonimmediate_operand")
16240 (match_operator:QI 1 "shr_comparison_operator"
16241 [(match_operand:DI 2 "register_operand")
16242 (match_operand 3 "const_int_operand")]))]
16243 "TARGET_64BIT
16244 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16245 [(set (reg:CCZ FLAGS_REG)
16246 (compare:CCZ
16247 (lshiftrt:DI (match_dup 2) (match_dup 4))
16248 (const_int 0)))
16249 (set (match_dup 0)
16250 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16251 {
16252 enum rtx_code new_code;
16253
16254 operands[1] = shallow_copy_rtx (operands[1]);
16255 switch (GET_CODE (operands[1]))
16256 {
16257 case GTU: new_code = NE; break;
16258 case LEU: new_code = EQ; break;
16259 default: gcc_unreachable ();
16260 }
16261 PUT_CODE (operands[1], new_code);
16262
16263 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16264 })
16265
16266 ;; For all sCOND expanders, also expand the compare or test insn that
16267 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16268
16269 (define_insn_and_split "*setcc_di_1"
16270 [(set (match_operand:DI 0 "register_operand" "=q")
16271 (match_operator:DI 1 "ix86_comparison_operator"
16272 [(reg FLAGS_REG) (const_int 0)]))]
16273 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16274 "#"
16275 "&& reload_completed"
16276 [(set (match_dup 2) (match_dup 1))
16277 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16278 {
16279 operands[1] = shallow_copy_rtx (operands[1]);
16280 PUT_MODE (operands[1], QImode);
16281 operands[2] = gen_lowpart (QImode, operands[0]);
16282 })
16283
16284 (define_insn_and_split "*setcc_<mode>_1_and"
16285 [(set (match_operand:SWI24 0 "register_operand" "=q")
16286 (match_operator:SWI24 1 "ix86_comparison_operator"
16287 [(reg FLAGS_REG) (const_int 0)]))
16288 (clobber (reg:CC FLAGS_REG))]
16289 "!TARGET_PARTIAL_REG_STALL
16290 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16291 "#"
16292 "&& reload_completed"
16293 [(set (match_dup 2) (match_dup 1))
16294 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16295 (clobber (reg:CC FLAGS_REG))])]
16296 {
16297 operands[1] = shallow_copy_rtx (operands[1]);
16298 PUT_MODE (operands[1], QImode);
16299 operands[2] = gen_lowpart (QImode, operands[0]);
16300 })
16301
16302 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16303 [(set (match_operand:SWI24 0 "register_operand" "=q")
16304 (match_operator:SWI24 1 "ix86_comparison_operator"
16305 [(reg FLAGS_REG) (const_int 0)]))]
16306 "!TARGET_PARTIAL_REG_STALL
16307 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16308 "#"
16309 "&& reload_completed"
16310 [(set (match_dup 2) (match_dup 1))
16311 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16312 {
16313 operands[1] = shallow_copy_rtx (operands[1]);
16314 PUT_MODE (operands[1], QImode);
16315 operands[2] = gen_lowpart (QImode, operands[0]);
16316 })
16317
16318 (define_insn "*setcc_qi"
16319 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16320 (match_operator:QI 1 "ix86_comparison_operator"
16321 [(reg FLAGS_REG) (const_int 0)]))]
16322 ""
16323 "set%C1\t%0"
16324 [(set_attr "type" "setcc")
16325 (set_attr "mode" "QI")])
16326
16327 (define_insn "*setcc_qi_slp"
16328 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16329 (match_operator:QI 1 "ix86_comparison_operator"
16330 [(reg FLAGS_REG) (const_int 0)]))]
16331 ""
16332 "set%C1\t%0"
16333 [(set_attr "type" "setcc")
16334 (set_attr "mode" "QI")])
16335
16336 ;; In general it is not safe to assume too much about CCmode registers,
16337 ;; so simplify-rtx stops when it sees a second one. Under certain
16338 ;; conditions this is safe on x86, so help combine not create
16339 ;;
16340 ;; seta %al
16341 ;; testb %al, %al
16342 ;; sete %al
16343
16344 (define_split
16345 [(set (match_operand:QI 0 "nonimmediate_operand")
16346 (ne:QI (match_operator 1 "ix86_comparison_operator"
16347 [(reg FLAGS_REG) (const_int 0)])
16348 (const_int 0)))]
16349 ""
16350 [(set (match_dup 0) (match_dup 1))]
16351 {
16352 operands[1] = shallow_copy_rtx (operands[1]);
16353 PUT_MODE (operands[1], QImode);
16354 })
16355
16356 (define_split
16357 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16358 (ne:QI (match_operator 1 "ix86_comparison_operator"
16359 [(reg FLAGS_REG) (const_int 0)])
16360 (const_int 0)))]
16361 ""
16362 [(set (match_dup 0) (match_dup 1))]
16363 {
16364 operands[1] = shallow_copy_rtx (operands[1]);
16365 PUT_MODE (operands[1], QImode);
16366 })
16367
16368 (define_split
16369 [(set (match_operand:QI 0 "nonimmediate_operand")
16370 (eq:QI (match_operator 1 "ix86_comparison_operator"
16371 [(reg FLAGS_REG) (const_int 0)])
16372 (const_int 0)))]
16373 ""
16374 [(set (match_dup 0) (match_dup 1))]
16375 {
16376 operands[1] = shallow_copy_rtx (operands[1]);
16377 PUT_MODE (operands[1], QImode);
16378 PUT_CODE (operands[1],
16379 ix86_reverse_condition (GET_CODE (operands[1]),
16380 GET_MODE (XEXP (operands[1], 0))));
16381
16382 /* Make sure that (a) the CCmode we have for the flags is strong
16383 enough for the reversed compare or (b) we have a valid FP compare. */
16384 if (! ix86_comparison_operator (operands[1], VOIDmode))
16385 FAIL;
16386 })
16387
16388 (define_split
16389 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16390 (eq:QI (match_operator 1 "ix86_comparison_operator"
16391 [(reg FLAGS_REG) (const_int 0)])
16392 (const_int 0)))]
16393 ""
16394 [(set (match_dup 0) (match_dup 1))]
16395 {
16396 operands[1] = shallow_copy_rtx (operands[1]);
16397 PUT_MODE (operands[1], QImode);
16398 PUT_CODE (operands[1],
16399 ix86_reverse_condition (GET_CODE (operands[1]),
16400 GET_MODE (XEXP (operands[1], 0))));
16401
16402 /* Make sure that (a) the CCmode we have for the flags is strong
16403 enough for the reversed compare or (b) we have a valid FP compare. */
16404 if (! ix86_comparison_operator (operands[1], VOIDmode))
16405 FAIL;
16406 })
16407
16408 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
16409 ;; subsequent logical operations are used to imitate conditional moves.
16410 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
16411 ;; it directly.
16412
16413 (define_insn "setcc_<mode>_sse"
16414 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16415 (match_operator:MODEF 3 "sse_comparison_operator"
16416 [(match_operand:MODEF 1 "register_operand" "0,x")
16417 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
16418 "SSE_FLOAT_MODE_P (<MODE>mode)"
16419 "@
16420 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
16421 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16422 [(set_attr "isa" "noavx,avx")
16423 (set_attr "type" "ssecmp")
16424 (set_attr "length_immediate" "1")
16425 (set_attr "prefix" "orig,vex")
16426 (set_attr "mode" "<MODE>")])
16427
16428 (define_insn "setcc_hf_mask"
16429 [(set (match_operand:QI 0 "register_operand" "=k")
16430 (unspec:QI
16431 [(match_operand:HF 1 "register_operand" "v")
16432 (match_operand:HF 2 "nonimmediate_operand" "vm")
16433 (match_operand:SI 3 "const_0_to_31_operand")]
16434 UNSPEC_PCMP))]
16435 "TARGET_AVX512FP16"
16436 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16437 [(set_attr "type" "ssecmp")
16438 (set_attr "prefix" "evex")
16439 (set_attr "mode" "HF")])
16440
16441 \f
16442 ;; Basic conditional jump instructions.
16443
16444 (define_split
16445 [(set (pc)
16446 (if_then_else
16447 (match_operator 1 "add_comparison_operator"
16448 [(not:SWI (match_operand:SWI 2 "register_operand"))
16449 (match_operand:SWI 3 "nonimmediate_operand")])
16450 (label_ref (match_operand 0))
16451 (pc)))]
16452 ""
16453 [(set (reg:CCC FLAGS_REG)
16454 (compare:CCC
16455 (plus:SWI (match_dup 2) (match_dup 3))
16456 (match_dup 2)))
16457 (set (pc)
16458 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
16459 (label_ref (match_operand 0))
16460 (pc)))])
16461
16462 (define_split
16463 [(set (pc)
16464 (if_then_else
16465 (match_operator 1 "shr_comparison_operator"
16466 [(match_operand:DI 2 "register_operand")
16467 (match_operand 3 "const_int_operand")])
16468 (label_ref (match_operand 0))
16469 (pc)))]
16470 "TARGET_64BIT
16471 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16472 [(set (reg:CCZ FLAGS_REG)
16473 (compare:CCZ
16474 (lshiftrt:DI (match_dup 2) (match_dup 4))
16475 (const_int 0)))
16476 (set (pc)
16477 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
16478 (label_ref (match_operand 0))
16479 (pc)))]
16480 {
16481 enum rtx_code new_code;
16482
16483 operands[1] = shallow_copy_rtx (operands[1]);
16484 switch (GET_CODE (operands[1]))
16485 {
16486 case GTU: new_code = NE; break;
16487 case LEU: new_code = EQ; break;
16488 default: gcc_unreachable ();
16489 }
16490 PUT_CODE (operands[1], new_code);
16491
16492 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16493 })
16494
16495 ;; We ignore the overflow flag for signed branch instructions.
16496
16497 (define_insn "*jcc"
16498 [(set (pc)
16499 (if_then_else (match_operator 1 "ix86_comparison_operator"
16500 [(reg FLAGS_REG) (const_int 0)])
16501 (label_ref (match_operand 0))
16502 (pc)))]
16503 ""
16504 "%!%+j%C1\t%l0"
16505 [(set_attr "type" "ibr")
16506 (set_attr "modrm" "0")
16507 (set (attr "length")
16508 (if_then_else
16509 (and (ge (minus (match_dup 0) (pc))
16510 (const_int -126))
16511 (lt (minus (match_dup 0) (pc))
16512 (const_int 128)))
16513 (const_int 2)
16514 (const_int 6)))])
16515
16516 ;; In general it is not safe to assume too much about CCmode registers,
16517 ;; so simplify-rtx stops when it sees a second one. Under certain
16518 ;; conditions this is safe on x86, so help combine not create
16519 ;;
16520 ;; seta %al
16521 ;; testb %al, %al
16522 ;; je Lfoo
16523
16524 (define_split
16525 [(set (pc)
16526 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
16527 [(reg FLAGS_REG) (const_int 0)])
16528 (const_int 0))
16529 (label_ref (match_operand 1))
16530 (pc)))]
16531 ""
16532 [(set (pc)
16533 (if_then_else (match_dup 0)
16534 (label_ref (match_dup 1))
16535 (pc)))]
16536 {
16537 operands[0] = shallow_copy_rtx (operands[0]);
16538 PUT_MODE (operands[0], VOIDmode);
16539 })
16540
16541 (define_split
16542 [(set (pc)
16543 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
16544 [(reg FLAGS_REG) (const_int 0)])
16545 (const_int 0))
16546 (label_ref (match_operand 1))
16547 (pc)))]
16548 ""
16549 [(set (pc)
16550 (if_then_else (match_dup 0)
16551 (label_ref (match_dup 1))
16552 (pc)))]
16553 {
16554 operands[0] = shallow_copy_rtx (operands[0]);
16555 PUT_MODE (operands[0], VOIDmode);
16556 PUT_CODE (operands[0],
16557 ix86_reverse_condition (GET_CODE (operands[0]),
16558 GET_MODE (XEXP (operands[0], 0))));
16559
16560 /* Make sure that (a) the CCmode we have for the flags is strong
16561 enough for the reversed compare or (b) we have a valid FP compare. */
16562 if (! ix86_comparison_operator (operands[0], VOIDmode))
16563 FAIL;
16564 })
16565 \f
16566 ;; Unconditional and other jump instructions
16567
16568 (define_insn "jump"
16569 [(set (pc)
16570 (label_ref (match_operand 0)))]
16571 ""
16572 "%!jmp\t%l0"
16573 [(set_attr "type" "ibr")
16574 (set_attr "modrm" "0")
16575 (set (attr "length")
16576 (if_then_else
16577 (and (ge (minus (match_dup 0) (pc))
16578 (const_int -126))
16579 (lt (minus (match_dup 0) (pc))
16580 (const_int 128)))
16581 (const_int 2)
16582 (const_int 5)))])
16583
16584 (define_expand "indirect_jump"
16585 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
16586 ""
16587 {
16588 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16589 operands[0] = convert_memory_address (word_mode, operands[0]);
16590 cfun->machine->has_local_indirect_jump = true;
16591 })
16592
16593 (define_insn "*indirect_jump"
16594 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
16595 ""
16596 "* return ix86_output_indirect_jmp (operands[0]);"
16597 [(set (attr "type")
16598 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16599 != indirect_branch_keep)")
16600 (const_string "multi")
16601 (const_string "ibr")))
16602 (set_attr "length_immediate" "0")])
16603
16604 (define_expand "tablejump"
16605 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
16606 (use (label_ref (match_operand 1)))])]
16607 ""
16608 {
16609 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
16610 relative. Convert the relative address to an absolute address. */
16611 if (flag_pic)
16612 {
16613 rtx op0, op1;
16614 enum rtx_code code;
16615
16616 /* We can't use @GOTOFF for text labels on VxWorks;
16617 see gotoff_operand. */
16618 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
16619 {
16620 code = PLUS;
16621 op0 = operands[0];
16622 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
16623 }
16624 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
16625 {
16626 code = PLUS;
16627 op0 = operands[0];
16628 op1 = pic_offset_table_rtx;
16629 }
16630 else
16631 {
16632 code = MINUS;
16633 op0 = pic_offset_table_rtx;
16634 op1 = operands[0];
16635 }
16636
16637 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
16638 OPTAB_DIRECT);
16639 }
16640
16641 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16642 operands[0] = convert_memory_address (word_mode, operands[0]);
16643 cfun->machine->has_local_indirect_jump = true;
16644 })
16645
16646 (define_insn "*tablejump_1"
16647 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
16648 (use (label_ref (match_operand 1)))]
16649 ""
16650 "* return ix86_output_indirect_jmp (operands[0]);"
16651 [(set (attr "type")
16652 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16653 != indirect_branch_keep)")
16654 (const_string "multi")
16655 (const_string "ibr")))
16656 (set_attr "length_immediate" "0")])
16657 \f
16658 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
16659
16660 (define_peephole2
16661 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
16662 (set (match_operand:QI 1 "register_operand")
16663 (match_operator:QI 2 "ix86_comparison_operator"
16664 [(reg FLAGS_REG) (const_int 0)]))
16665 (set (match_operand 3 "any_QIreg_operand")
16666 (zero_extend (match_dup 1)))]
16667 "(peep2_reg_dead_p (3, operands[1])
16668 || operands_match_p (operands[1], operands[3]))
16669 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16670 && peep2_regno_dead_p (0, FLAGS_REG)"
16671 [(set (match_dup 4) (match_dup 0))
16672 (set (strict_low_part (match_dup 5))
16673 (match_dup 2))]
16674 {
16675 operands[5] = gen_lowpart (QImode, operands[3]);
16676 ix86_expand_clear (operands[3]);
16677 })
16678
16679 (define_peephole2
16680 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
16681 (match_operand 4)])
16682 (set (match_operand:QI 1 "register_operand")
16683 (match_operator:QI 2 "ix86_comparison_operator"
16684 [(reg FLAGS_REG) (const_int 0)]))
16685 (set (match_operand 3 "any_QIreg_operand")
16686 (zero_extend (match_dup 1)))]
16687 "(peep2_reg_dead_p (3, operands[1])
16688 || operands_match_p (operands[1], operands[3]))
16689 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16690 && ! reg_overlap_mentioned_p (operands[3], operands[4])
16691 && ! reg_set_p (operands[3], operands[4])
16692 && peep2_regno_dead_p (0, FLAGS_REG)"
16693 [(parallel [(set (match_dup 5) (match_dup 0))
16694 (match_dup 4)])
16695 (set (strict_low_part (match_dup 6))
16696 (match_dup 2))]
16697 {
16698 operands[6] = gen_lowpart (QImode, operands[3]);
16699 ix86_expand_clear (operands[3]);
16700 })
16701
16702 (define_peephole2
16703 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
16704 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
16705 (match_operand 5)])
16706 (set (match_operand:QI 2 "register_operand")
16707 (match_operator:QI 3 "ix86_comparison_operator"
16708 [(reg FLAGS_REG) (const_int 0)]))
16709 (set (match_operand 4 "any_QIreg_operand")
16710 (zero_extend (match_dup 2)))]
16711 "(peep2_reg_dead_p (4, operands[2])
16712 || operands_match_p (operands[2], operands[4]))
16713 && ! reg_overlap_mentioned_p (operands[4], operands[0])
16714 && ! reg_overlap_mentioned_p (operands[4], operands[1])
16715 && ! reg_overlap_mentioned_p (operands[4], operands[5])
16716 && ! reg_set_p (operands[4], operands[5])
16717 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
16718 && peep2_regno_dead_p (0, FLAGS_REG)"
16719 [(set (match_dup 6) (match_dup 0))
16720 (parallel [(set (match_dup 7) (match_dup 1))
16721 (match_dup 5)])
16722 (set (strict_low_part (match_dup 8))
16723 (match_dup 3))]
16724 {
16725 operands[8] = gen_lowpart (QImode, operands[4]);
16726 ix86_expand_clear (operands[4]);
16727 })
16728
16729 ;; Similar, but match zero extend with andsi3.
16730
16731 (define_peephole2
16732 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
16733 (set (match_operand:QI 1 "register_operand")
16734 (match_operator:QI 2 "ix86_comparison_operator"
16735 [(reg FLAGS_REG) (const_int 0)]))
16736 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
16737 (and:SI (match_dup 3) (const_int 255)))
16738 (clobber (reg:CC FLAGS_REG))])]
16739 "REGNO (operands[1]) == REGNO (operands[3])
16740 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16741 && peep2_regno_dead_p (0, FLAGS_REG)"
16742 [(set (match_dup 4) (match_dup 0))
16743 (set (strict_low_part (match_dup 5))
16744 (match_dup 2))]
16745 {
16746 operands[5] = gen_lowpart (QImode, operands[3]);
16747 ix86_expand_clear (operands[3]);
16748 })
16749
16750 (define_peephole2
16751 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
16752 (match_operand 4)])
16753 (set (match_operand:QI 1 "register_operand")
16754 (match_operator:QI 2 "ix86_comparison_operator"
16755 [(reg FLAGS_REG) (const_int 0)]))
16756 (parallel [(set (match_operand 3 "any_QIreg_operand")
16757 (zero_extend (match_dup 1)))
16758 (clobber (reg:CC FLAGS_REG))])]
16759 "(peep2_reg_dead_p (3, operands[1])
16760 || operands_match_p (operands[1], operands[3]))
16761 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16762 && ! reg_overlap_mentioned_p (operands[3], operands[4])
16763 && ! reg_set_p (operands[3], operands[4])
16764 && peep2_regno_dead_p (0, FLAGS_REG)"
16765 [(parallel [(set (match_dup 5) (match_dup 0))
16766 (match_dup 4)])
16767 (set (strict_low_part (match_dup 6))
16768 (match_dup 2))]
16769 {
16770 operands[6] = gen_lowpart (QImode, operands[3]);
16771 ix86_expand_clear (operands[3]);
16772 })
16773
16774 (define_peephole2
16775 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
16776 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
16777 (match_operand 5)])
16778 (set (match_operand:QI 2 "register_operand")
16779 (match_operator:QI 3 "ix86_comparison_operator"
16780 [(reg FLAGS_REG) (const_int 0)]))
16781 (parallel [(set (match_operand 4 "any_QIreg_operand")
16782 (zero_extend (match_dup 2)))
16783 (clobber (reg:CC FLAGS_REG))])]
16784 "(peep2_reg_dead_p (4, operands[2])
16785 || operands_match_p (operands[2], operands[4]))
16786 && ! reg_overlap_mentioned_p (operands[4], operands[0])
16787 && ! reg_overlap_mentioned_p (operands[4], operands[1])
16788 && ! reg_overlap_mentioned_p (operands[4], operands[5])
16789 && ! reg_set_p (operands[4], operands[5])
16790 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
16791 && peep2_regno_dead_p (0, FLAGS_REG)"
16792 [(set (match_dup 6) (match_dup 0))
16793 (parallel [(set (match_dup 7) (match_dup 1))
16794 (match_dup 5)])
16795 (set (strict_low_part (match_dup 8))
16796 (match_dup 3))]
16797 {
16798 operands[8] = gen_lowpart (QImode, operands[4]);
16799 ix86_expand_clear (operands[4]);
16800 })
16801 \f
16802 ;; Call instructions.
16803
16804 ;; The predicates normally associated with named expanders are not properly
16805 ;; checked for calls. This is a bug in the generic code, but it isn't that
16806 ;; easy to fix. Ignore it for now and be prepared to fix things up.
16807
16808 ;; P6 processors will jump to the address after the decrement when %esp
16809 ;; is used as a call operand, so they will execute return address as a code.
16810 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
16811
16812 ;; Register constraint for call instruction.
16813 (define_mode_attr c [(SI "l") (DI "r")])
16814
16815 ;; Call subroutine returning no value.
16816
16817 (define_expand "call"
16818 [(call (match_operand:QI 0)
16819 (match_operand 1))
16820 (use (match_operand 2))]
16821 ""
16822 {
16823 ix86_expand_call (NULL, operands[0], operands[1],
16824 operands[2], NULL, false);
16825 DONE;
16826 })
16827
16828 (define_expand "sibcall"
16829 [(call (match_operand:QI 0)
16830 (match_operand 1))
16831 (use (match_operand 2))]
16832 ""
16833 {
16834 ix86_expand_call (NULL, operands[0], operands[1],
16835 operands[2], NULL, true);
16836 DONE;
16837 })
16838
16839 (define_insn "*call"
16840 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
16841 (match_operand 1))]
16842 "!SIBLING_CALL_P (insn)"
16843 "* return ix86_output_call_insn (insn, operands[0]);"
16844 [(set_attr "type" "call")])
16845
16846 ;; This covers both call and sibcall since only GOT slot is allowed.
16847 (define_insn "*call_got_x32"
16848 [(call (mem:QI (zero_extend:DI
16849 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
16850 (match_operand 1))]
16851 "TARGET_X32"
16852 {
16853 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
16854 return ix86_output_call_insn (insn, fnaddr);
16855 }
16856 [(set_attr "type" "call")])
16857
16858 ;; Since sibcall never returns, we can only use call-clobbered register
16859 ;; as GOT base.
16860 (define_insn "*sibcall_GOT_32"
16861 [(call (mem:QI
16862 (mem:SI (plus:SI
16863 (match_operand:SI 0 "register_no_elim_operand" "U")
16864 (match_operand:SI 1 "GOT32_symbol_operand"))))
16865 (match_operand 2))]
16866 "!TARGET_MACHO
16867 && !TARGET_64BIT
16868 && !TARGET_INDIRECT_BRANCH_REGISTER
16869 && SIBLING_CALL_P (insn)"
16870 {
16871 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
16872 fnaddr = gen_const_mem (SImode, fnaddr);
16873 return ix86_output_call_insn (insn, fnaddr);
16874 }
16875 [(set_attr "type" "call")])
16876
16877 (define_insn "*sibcall"
16878 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
16879 (match_operand 1))]
16880 "SIBLING_CALL_P (insn)"
16881 "* return ix86_output_call_insn (insn, operands[0]);"
16882 [(set_attr "type" "call")])
16883
16884 (define_insn "*sibcall_memory"
16885 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
16886 (match_operand 1))
16887 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
16888 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
16889 "* return ix86_output_call_insn (insn, operands[0]);"
16890 [(set_attr "type" "call")])
16891
16892 (define_peephole2
16893 [(set (match_operand:W 0 "register_operand")
16894 (match_operand:W 1 "memory_operand"))
16895 (call (mem:QI (match_dup 0))
16896 (match_operand 3))]
16897 "!TARGET_X32
16898 && !TARGET_INDIRECT_BRANCH_REGISTER
16899 && SIBLING_CALL_P (peep2_next_insn (1))
16900 && !reg_mentioned_p (operands[0],
16901 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
16902 [(parallel [(call (mem:QI (match_dup 1))
16903 (match_dup 3))
16904 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
16905
16906 (define_peephole2
16907 [(set (match_operand:W 0 "register_operand")
16908 (match_operand:W 1 "memory_operand"))
16909 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
16910 (call (mem:QI (match_dup 0))
16911 (match_operand 3))]
16912 "!TARGET_X32
16913 && !TARGET_INDIRECT_BRANCH_REGISTER
16914 && SIBLING_CALL_P (peep2_next_insn (2))
16915 && !reg_mentioned_p (operands[0],
16916 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
16917 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
16918 (parallel [(call (mem:QI (match_dup 1))
16919 (match_dup 3))
16920 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
16921
16922 (define_expand "call_pop"
16923 [(parallel [(call (match_operand:QI 0)
16924 (match_operand:SI 1))
16925 (set (reg:SI SP_REG)
16926 (plus:SI (reg:SI SP_REG)
16927 (match_operand:SI 3)))])]
16928 "!TARGET_64BIT"
16929 {
16930 ix86_expand_call (NULL, operands[0], operands[1],
16931 operands[2], operands[3], false);
16932 DONE;
16933 })
16934
16935 (define_insn "*call_pop"
16936 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
16937 (match_operand 1))
16938 (set (reg:SI SP_REG)
16939 (plus:SI (reg:SI SP_REG)
16940 (match_operand:SI 2 "immediate_operand" "i")))]
16941 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
16942 "* return ix86_output_call_insn (insn, operands[0]);"
16943 [(set_attr "type" "call")])
16944
16945 (define_insn "*sibcall_pop"
16946 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
16947 (match_operand 1))
16948 (set (reg:SI SP_REG)
16949 (plus:SI (reg:SI SP_REG)
16950 (match_operand:SI 2 "immediate_operand" "i")))]
16951 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
16952 "* return ix86_output_call_insn (insn, operands[0]);"
16953 [(set_attr "type" "call")])
16954
16955 (define_insn "*sibcall_pop_memory"
16956 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
16957 (match_operand 1))
16958 (set (reg:SI SP_REG)
16959 (plus:SI (reg:SI SP_REG)
16960 (match_operand:SI 2 "immediate_operand" "i")))
16961 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
16962 "!TARGET_64BIT"
16963 "* return ix86_output_call_insn (insn, operands[0]);"
16964 [(set_attr "type" "call")])
16965
16966 (define_peephole2
16967 [(set (match_operand:SI 0 "register_operand")
16968 (match_operand:SI 1 "memory_operand"))
16969 (parallel [(call (mem:QI (match_dup 0))
16970 (match_operand 3))
16971 (set (reg:SI SP_REG)
16972 (plus:SI (reg:SI SP_REG)
16973 (match_operand:SI 4 "immediate_operand")))])]
16974 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
16975 && !reg_mentioned_p (operands[0],
16976 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
16977 [(parallel [(call (mem:QI (match_dup 1))
16978 (match_dup 3))
16979 (set (reg:SI SP_REG)
16980 (plus:SI (reg:SI SP_REG)
16981 (match_dup 4)))
16982 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
16983
16984 (define_peephole2
16985 [(set (match_operand:SI 0 "register_operand")
16986 (match_operand:SI 1 "memory_operand"))
16987 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
16988 (parallel [(call (mem:QI (match_dup 0))
16989 (match_operand 3))
16990 (set (reg:SI SP_REG)
16991 (plus:SI (reg:SI SP_REG)
16992 (match_operand:SI 4 "immediate_operand")))])]
16993 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
16994 && !reg_mentioned_p (operands[0],
16995 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
16996 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
16997 (parallel [(call (mem:QI (match_dup 1))
16998 (match_dup 3))
16999 (set (reg:SI SP_REG)
17000 (plus:SI (reg:SI SP_REG)
17001 (match_dup 4)))
17002 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17003
17004 ;; Combining simple memory jump instruction
17005
17006 (define_peephole2
17007 [(set (match_operand:W 0 "register_operand")
17008 (match_operand:W 1 "memory_operand"))
17009 (set (pc) (match_dup 0))]
17010 "!TARGET_X32
17011 && !TARGET_INDIRECT_BRANCH_REGISTER
17012 && peep2_reg_dead_p (2, operands[0])"
17013 [(set (pc) (match_dup 1))])
17014
17015 ;; Call subroutine, returning value in operand 0
17016
17017 (define_expand "call_value"
17018 [(set (match_operand 0)
17019 (call (match_operand:QI 1)
17020 (match_operand 2)))
17021 (use (match_operand 3))]
17022 ""
17023 {
17024 ix86_expand_call (operands[0], operands[1], operands[2],
17025 operands[3], NULL, false);
17026 DONE;
17027 })
17028
17029 (define_expand "sibcall_value"
17030 [(set (match_operand 0)
17031 (call (match_operand:QI 1)
17032 (match_operand 2)))
17033 (use (match_operand 3))]
17034 ""
17035 {
17036 ix86_expand_call (operands[0], operands[1], operands[2],
17037 operands[3], NULL, true);
17038 DONE;
17039 })
17040
17041 (define_insn "*call_value"
17042 [(set (match_operand 0)
17043 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17044 (match_operand 2)))]
17045 "!SIBLING_CALL_P (insn)"
17046 "* return ix86_output_call_insn (insn, operands[1]);"
17047 [(set_attr "type" "callv")])
17048
17049 ;; This covers both call and sibcall since only GOT slot is allowed.
17050 (define_insn "*call_value_got_x32"
17051 [(set (match_operand 0)
17052 (call (mem:QI
17053 (zero_extend:DI
17054 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17055 (match_operand 2)))]
17056 "TARGET_X32"
17057 {
17058 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17059 return ix86_output_call_insn (insn, fnaddr);
17060 }
17061 [(set_attr "type" "callv")])
17062
17063 ;; Since sibcall never returns, we can only use call-clobbered register
17064 ;; as GOT base.
17065 (define_insn "*sibcall_value_GOT_32"
17066 [(set (match_operand 0)
17067 (call (mem:QI
17068 (mem:SI (plus:SI
17069 (match_operand:SI 1 "register_no_elim_operand" "U")
17070 (match_operand:SI 2 "GOT32_symbol_operand"))))
17071 (match_operand 3)))]
17072 "!TARGET_MACHO
17073 && !TARGET_64BIT
17074 && !TARGET_INDIRECT_BRANCH_REGISTER
17075 && SIBLING_CALL_P (insn)"
17076 {
17077 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17078 fnaddr = gen_const_mem (SImode, fnaddr);
17079 return ix86_output_call_insn (insn, fnaddr);
17080 }
17081 [(set_attr "type" "callv")])
17082
17083 (define_insn "*sibcall_value"
17084 [(set (match_operand 0)
17085 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17086 (match_operand 2)))]
17087 "SIBLING_CALL_P (insn)"
17088 "* return ix86_output_call_insn (insn, operands[1]);"
17089 [(set_attr "type" "callv")])
17090
17091 (define_insn "*sibcall_value_memory"
17092 [(set (match_operand 0)
17093 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17094 (match_operand 2)))
17095 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17096 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17097 "* return ix86_output_call_insn (insn, operands[1]);"
17098 [(set_attr "type" "callv")])
17099
17100 (define_peephole2
17101 [(set (match_operand:W 0 "register_operand")
17102 (match_operand:W 1 "memory_operand"))
17103 (set (match_operand 2)
17104 (call (mem:QI (match_dup 0))
17105 (match_operand 3)))]
17106 "!TARGET_X32
17107 && !TARGET_INDIRECT_BRANCH_REGISTER
17108 && SIBLING_CALL_P (peep2_next_insn (1))
17109 && !reg_mentioned_p (operands[0],
17110 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17111 [(parallel [(set (match_dup 2)
17112 (call (mem:QI (match_dup 1))
17113 (match_dup 3)))
17114 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17115
17116 (define_peephole2
17117 [(set (match_operand:W 0 "register_operand")
17118 (match_operand:W 1 "memory_operand"))
17119 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17120 (set (match_operand 2)
17121 (call (mem:QI (match_dup 0))
17122 (match_operand 3)))]
17123 "!TARGET_X32
17124 && !TARGET_INDIRECT_BRANCH_REGISTER
17125 && SIBLING_CALL_P (peep2_next_insn (2))
17126 && !reg_mentioned_p (operands[0],
17127 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17128 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17129 (parallel [(set (match_dup 2)
17130 (call (mem:QI (match_dup 1))
17131 (match_dup 3)))
17132 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17133
17134 (define_expand "call_value_pop"
17135 [(parallel [(set (match_operand 0)
17136 (call (match_operand:QI 1)
17137 (match_operand:SI 2)))
17138 (set (reg:SI SP_REG)
17139 (plus:SI (reg:SI SP_REG)
17140 (match_operand:SI 4)))])]
17141 "!TARGET_64BIT"
17142 {
17143 ix86_expand_call (operands[0], operands[1], operands[2],
17144 operands[3], operands[4], false);
17145 DONE;
17146 })
17147
17148 (define_insn "*call_value_pop"
17149 [(set (match_operand 0)
17150 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17151 (match_operand 2)))
17152 (set (reg:SI SP_REG)
17153 (plus:SI (reg:SI SP_REG)
17154 (match_operand:SI 3 "immediate_operand" "i")))]
17155 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17156 "* return ix86_output_call_insn (insn, operands[1]);"
17157 [(set_attr "type" "callv")])
17158
17159 (define_insn "*sibcall_value_pop"
17160 [(set (match_operand 0)
17161 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17162 (match_operand 2)))
17163 (set (reg:SI SP_REG)
17164 (plus:SI (reg:SI SP_REG)
17165 (match_operand:SI 3 "immediate_operand" "i")))]
17166 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17167 "* return ix86_output_call_insn (insn, operands[1]);"
17168 [(set_attr "type" "callv")])
17169
17170 (define_insn "*sibcall_value_pop_memory"
17171 [(set (match_operand 0)
17172 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17173 (match_operand 2)))
17174 (set (reg:SI SP_REG)
17175 (plus:SI (reg:SI SP_REG)
17176 (match_operand:SI 3 "immediate_operand" "i")))
17177 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17178 "!TARGET_64BIT"
17179 "* return ix86_output_call_insn (insn, operands[1]);"
17180 [(set_attr "type" "callv")])
17181
17182 (define_peephole2
17183 [(set (match_operand:SI 0 "register_operand")
17184 (match_operand:SI 1 "memory_operand"))
17185 (parallel [(set (match_operand 2)
17186 (call (mem:QI (match_dup 0))
17187 (match_operand 3)))
17188 (set (reg:SI SP_REG)
17189 (plus:SI (reg:SI SP_REG)
17190 (match_operand:SI 4 "immediate_operand")))])]
17191 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17192 && !reg_mentioned_p (operands[0],
17193 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17194 [(parallel [(set (match_dup 2)
17195 (call (mem:QI (match_dup 1))
17196 (match_dup 3)))
17197 (set (reg:SI SP_REG)
17198 (plus:SI (reg:SI SP_REG)
17199 (match_dup 4)))
17200 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17201
17202 (define_peephole2
17203 [(set (match_operand:SI 0 "register_operand")
17204 (match_operand:SI 1 "memory_operand"))
17205 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17206 (parallel [(set (match_operand 2)
17207 (call (mem:QI (match_dup 0))
17208 (match_operand 3)))
17209 (set (reg:SI SP_REG)
17210 (plus:SI (reg:SI SP_REG)
17211 (match_operand:SI 4 "immediate_operand")))])]
17212 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17213 && !reg_mentioned_p (operands[0],
17214 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17215 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17216 (parallel [(set (match_dup 2)
17217 (call (mem:QI (match_dup 1))
17218 (match_dup 3)))
17219 (set (reg:SI SP_REG)
17220 (plus:SI (reg:SI SP_REG)
17221 (match_dup 4)))
17222 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17223
17224 ;; Call subroutine returning any type.
17225
17226 (define_expand "untyped_call"
17227 [(parallel [(call (match_operand 0)
17228 (const_int 0))
17229 (match_operand 1)
17230 (match_operand 2)])]
17231 ""
17232 {
17233 int i;
17234
17235 /* In order to give reg-stack an easier job in validating two
17236 coprocessor registers as containing a possible return value,
17237 simply pretend the untyped call returns a complex long double
17238 value.
17239
17240 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17241 and should have the default ABI. */
17242
17243 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17244 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17245 operands[0], const0_rtx,
17246 GEN_INT ((TARGET_64BIT
17247 ? (ix86_abi == SYSV_ABI
17248 ? X86_64_SSE_REGPARM_MAX
17249 : X86_64_MS_SSE_REGPARM_MAX)
17250 : X86_32_SSE_REGPARM_MAX)
17251 - 1),
17252 NULL, false);
17253
17254 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17255 {
17256 rtx set = XVECEXP (operands[2], 0, i);
17257 emit_move_insn (SET_DEST (set), SET_SRC (set));
17258 }
17259
17260 /* The optimizer does not know that the call sets the function value
17261 registers we stored in the result block. We avoid problems by
17262 claiming that all hard registers are used and clobbered at this
17263 point. */
17264 emit_insn (gen_blockage ());
17265
17266 DONE;
17267 })
17268 \f
17269 ;; Prologue and epilogue instructions
17270
17271 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17272 ;; all of memory. This blocks insns from being moved across this point.
17273
17274 (define_insn "blockage"
17275 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17276 ""
17277 ""
17278 [(set_attr "length" "0")])
17279
17280 ;; Do not schedule instructions accessing memory across this point.
17281
17282 (define_expand "memory_blockage"
17283 [(set (match_dup 0)
17284 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17285 ""
17286 {
17287 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17288 MEM_VOLATILE_P (operands[0]) = 1;
17289 })
17290
17291 (define_insn "*memory_blockage"
17292 [(set (match_operand:BLK 0)
17293 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17294 ""
17295 ""
17296 [(set_attr "length" "0")])
17297
17298 ;; As USE insns aren't meaningful after reload, this is used instead
17299 ;; to prevent deleting instructions setting registers for PIC code
17300 (define_insn "prologue_use"
17301 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17302 ""
17303 ""
17304 [(set_attr "length" "0")])
17305
17306 ;; Insn emitted into the body of a function to return from a function.
17307 ;; This is only done if the function's epilogue is known to be simple.
17308 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17309
17310 (define_expand "return"
17311 [(simple_return)]
17312 "ix86_can_use_return_insn_p ()"
17313 {
17314 if (crtl->args.pops_args)
17315 {
17316 rtx popc = GEN_INT (crtl->args.pops_args);
17317 emit_jump_insn (gen_simple_return_pop_internal (popc));
17318 DONE;
17319 }
17320 })
17321
17322 ;; We need to disable this for TARGET_SEH, as otherwise
17323 ;; shrink-wrapped prologue gets enabled too. This might exceed
17324 ;; the maximum size of prologue in unwind information.
17325 ;; Also disallow shrink-wrapping if using stack slot to pass the
17326 ;; static chain pointer - the first instruction has to be pushl %esi
17327 ;; and it can't be moved around, as we use alternate entry points
17328 ;; in that case.
17329 ;; Also disallow for ms_hook_prologue functions which have frame
17330 ;; pointer set up in function label which is correctly handled in
17331 ;; ix86_expand_{prologue|epligoue}() only.
17332
17333 (define_expand "simple_return"
17334 [(simple_return)]
17335 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17336 {
17337 if (crtl->args.pops_args)
17338 {
17339 rtx popc = GEN_INT (crtl->args.pops_args);
17340 emit_jump_insn (gen_simple_return_pop_internal (popc));
17341 DONE;
17342 }
17343 })
17344
17345 (define_insn "simple_return_internal"
17346 [(simple_return)]
17347 "reload_completed"
17348 "* return ix86_output_function_return (false);"
17349 [(set_attr "length" "1")
17350 (set_attr "atom_unit" "jeu")
17351 (set_attr "length_immediate" "0")
17352 (set_attr "modrm" "0")])
17353
17354 (define_insn "interrupt_return"
17355 [(simple_return)
17356 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17357 "reload_completed"
17358 {
17359 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17360 })
17361
17362 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17363 ;; instruction Athlon and K8 have.
17364
17365 (define_insn "simple_return_internal_long"
17366 [(simple_return)
17367 (unspec [(const_int 0)] UNSPEC_REP)]
17368 "reload_completed"
17369 "* return ix86_output_function_return (true);"
17370 [(set_attr "length" "2")
17371 (set_attr "atom_unit" "jeu")
17372 (set_attr "length_immediate" "0")
17373 (set_attr "prefix_rep" "1")
17374 (set_attr "modrm" "0")])
17375
17376 (define_insn_and_split "simple_return_pop_internal"
17377 [(simple_return)
17378 (use (match_operand:SI 0 "const_int_operand"))]
17379 "reload_completed"
17380 "ret\t%0"
17381 "&& cfun->machine->function_return_type != indirect_branch_keep"
17382 [(const_int 0)]
17383 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17384 [(set_attr "length" "3")
17385 (set_attr "atom_unit" "jeu")
17386 (set_attr "length_immediate" "2")
17387 (set_attr "modrm" "0")])
17388
17389 (define_expand "simple_return_indirect_internal"
17390 [(parallel
17391 [(simple_return)
17392 (use (match_operand 0 "register_operand"))])])
17393
17394 (define_insn "*simple_return_indirect_internal<mode>"
17395 [(simple_return)
17396 (use (match_operand:W 0 "register_operand" "r"))]
17397 "reload_completed"
17398 "* return ix86_output_indirect_function_return (operands[0]);"
17399 [(set (attr "type")
17400 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17401 != indirect_branch_keep)")
17402 (const_string "multi")
17403 (const_string "ibr")))
17404 (set_attr "length_immediate" "0")])
17405
17406 (define_insn "nop"
17407 [(const_int 0)]
17408 ""
17409 "nop"
17410 [(set_attr "length" "1")
17411 (set_attr "length_immediate" "0")
17412 (set_attr "modrm" "0")])
17413
17414 ;; Generate nops. Operand 0 is the number of nops, up to 8.
17415 (define_insn "nops"
17416 [(unspec_volatile [(match_operand 0 "const_int_operand")]
17417 UNSPECV_NOPS)]
17418 "reload_completed"
17419 {
17420 int num = INTVAL (operands[0]);
17421
17422 gcc_assert (IN_RANGE (num, 1, 8));
17423
17424 while (num--)
17425 fputs ("\tnop\n", asm_out_file);
17426
17427 return "";
17428 }
17429 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
17430 (set_attr "length_immediate" "0")
17431 (set_attr "modrm" "0")])
17432
17433 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
17434 ;; branch prediction penalty for the third jump in a 16-byte
17435 ;; block on K8.
17436
17437 (define_insn "pad"
17438 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
17439 ""
17440 {
17441 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
17442 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
17443 #else
17444 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
17445 The align insn is used to avoid 3 jump instructions in the row to improve
17446 branch prediction and the benefits hardly outweigh the cost of extra 8
17447 nops on the average inserted by full alignment pseudo operation. */
17448 #endif
17449 return "";
17450 }
17451 [(set_attr "length" "16")])
17452
17453 (define_expand "prologue"
17454 [(const_int 0)]
17455 ""
17456 "ix86_expand_prologue (); DONE;")
17457
17458 (define_expand "set_got"
17459 [(parallel
17460 [(set (match_operand:SI 0 "register_operand")
17461 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17462 (clobber (reg:CC FLAGS_REG))])]
17463 "!TARGET_64BIT"
17464 {
17465 if (flag_pic && !TARGET_VXWORKS_RTP)
17466 ix86_pc_thunk_call_expanded = true;
17467 })
17468
17469 (define_insn "*set_got"
17470 [(set (match_operand:SI 0 "register_operand" "=r")
17471 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17472 (clobber (reg:CC FLAGS_REG))]
17473 "!TARGET_64BIT"
17474 "* return output_set_got (operands[0], NULL_RTX);"
17475 [(set_attr "type" "multi")
17476 (set_attr "length" "12")])
17477
17478 (define_expand "set_got_labelled"
17479 [(parallel
17480 [(set (match_operand:SI 0 "register_operand")
17481 (unspec:SI [(label_ref (match_operand 1))]
17482 UNSPEC_SET_GOT))
17483 (clobber (reg:CC FLAGS_REG))])]
17484 "!TARGET_64BIT"
17485 {
17486 if (flag_pic && !TARGET_VXWORKS_RTP)
17487 ix86_pc_thunk_call_expanded = true;
17488 })
17489
17490 (define_insn "*set_got_labelled"
17491 [(set (match_operand:SI 0 "register_operand" "=r")
17492 (unspec:SI [(label_ref (match_operand 1))]
17493 UNSPEC_SET_GOT))
17494 (clobber (reg:CC FLAGS_REG))]
17495 "!TARGET_64BIT"
17496 "* return output_set_got (operands[0], operands[1]);"
17497 [(set_attr "type" "multi")
17498 (set_attr "length" "12")])
17499
17500 (define_insn "set_got_rex64"
17501 [(set (match_operand:DI 0 "register_operand" "=r")
17502 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
17503 "TARGET_64BIT"
17504 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
17505 [(set_attr "type" "lea")
17506 (set_attr "length_address" "4")
17507 (set_attr "mode" "DI")])
17508
17509 (define_insn "set_rip_rex64"
17510 [(set (match_operand:DI 0 "register_operand" "=r")
17511 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
17512 "TARGET_64BIT"
17513 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
17514 [(set_attr "type" "lea")
17515 (set_attr "length_address" "4")
17516 (set_attr "mode" "DI")])
17517
17518 (define_insn "set_got_offset_rex64"
17519 [(set (match_operand:DI 0 "register_operand" "=r")
17520 (unspec:DI
17521 [(label_ref (match_operand 1))]
17522 UNSPEC_SET_GOT_OFFSET))]
17523 "TARGET_LP64"
17524 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
17525 [(set_attr "type" "imov")
17526 (set_attr "length_immediate" "0")
17527 (set_attr "length_address" "8")
17528 (set_attr "mode" "DI")])
17529
17530 (define_expand "epilogue"
17531 [(const_int 0)]
17532 ""
17533 "ix86_expand_epilogue (1); DONE;")
17534
17535 (define_expand "sibcall_epilogue"
17536 [(const_int 0)]
17537 ""
17538 "ix86_expand_epilogue (0); DONE;")
17539
17540 (define_expand "eh_return"
17541 [(use (match_operand 0 "register_operand"))]
17542 ""
17543 {
17544 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
17545
17546 /* Tricky bit: we write the address of the handler to which we will
17547 be returning into someone else's stack frame, one word below the
17548 stack address we wish to restore. */
17549 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
17550 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
17551 /* Return address is always in word_mode. */
17552 tmp = gen_rtx_MEM (word_mode, tmp);
17553 if (GET_MODE (ra) != word_mode)
17554 ra = convert_to_mode (word_mode, ra, 1);
17555 emit_move_insn (tmp, ra);
17556
17557 emit_jump_insn (gen_eh_return_internal ());
17558 emit_barrier ();
17559 DONE;
17560 })
17561
17562 (define_insn_and_split "eh_return_internal"
17563 [(eh_return)]
17564 ""
17565 "#"
17566 "epilogue_completed"
17567 [(const_int 0)]
17568 "ix86_expand_epilogue (2); DONE;")
17569
17570 (define_expand "@leave_<mode>"
17571 [(parallel
17572 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
17573 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
17574 (clobber (mem:BLK (scratch)))])]
17575 ""
17576 "operands[0] = GEN_INT (<MODE_SIZE>);")
17577
17578 (define_insn "*leave"
17579 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
17580 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
17581 (clobber (mem:BLK (scratch)))]
17582 "!TARGET_64BIT"
17583 "leave"
17584 [(set_attr "type" "leave")])
17585
17586 (define_insn "*leave_rex64"
17587 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
17588 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
17589 (clobber (mem:BLK (scratch)))]
17590 "TARGET_64BIT"
17591 "leave"
17592 [(set_attr "type" "leave")])
17593 \f
17594 ;; Handle -fsplit-stack.
17595
17596 (define_expand "split_stack_prologue"
17597 [(const_int 0)]
17598 ""
17599 {
17600 ix86_expand_split_stack_prologue ();
17601 DONE;
17602 })
17603
17604 ;; In order to support the call/return predictor, we use a return
17605 ;; instruction which the middle-end doesn't see.
17606 (define_insn "split_stack_return"
17607 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
17608 UNSPECV_SPLIT_STACK_RETURN)]
17609 ""
17610 {
17611 if (operands[0] == const0_rtx)
17612 return "ret";
17613 else
17614 return "ret\t%0";
17615 }
17616 [(set_attr "atom_unit" "jeu")
17617 (set_attr "modrm" "0")
17618 (set (attr "length")
17619 (if_then_else (match_operand:SI 0 "const0_operand")
17620 (const_int 1)
17621 (const_int 3)))
17622 (set (attr "length_immediate")
17623 (if_then_else (match_operand:SI 0 "const0_operand")
17624 (const_int 0)
17625 (const_int 2)))])
17626
17627 ;; If there are operand 0 bytes available on the stack, jump to
17628 ;; operand 1.
17629
17630 (define_expand "split_stack_space_check"
17631 [(set (pc) (if_then_else
17632 (ltu (minus (reg SP_REG)
17633 (match_operand 0 "register_operand"))
17634 (match_dup 2))
17635 (label_ref (match_operand 1))
17636 (pc)))]
17637 ""
17638 {
17639 rtx reg = gen_reg_rtx (Pmode);
17640
17641 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
17642
17643 operands[2] = ix86_split_stack_guard ();
17644 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
17645
17646 DONE;
17647 })
17648 \f
17649 ;; Bit manipulation instructions.
17650
17651 (define_expand "ffs<mode>2"
17652 [(set (match_dup 2) (const_int -1))
17653 (parallel [(set (match_dup 3) (match_dup 4))
17654 (set (match_operand:SWI48 0 "register_operand")
17655 (ctz:SWI48
17656 (match_operand:SWI48 1 "nonimmediate_operand")))])
17657 (set (match_dup 0) (if_then_else:SWI48
17658 (eq (match_dup 3) (const_int 0))
17659 (match_dup 2)
17660 (match_dup 0)))
17661 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
17662 (clobber (reg:CC FLAGS_REG))])]
17663 ""
17664 {
17665 machine_mode flags_mode;
17666
17667 if (<MODE>mode == SImode && !TARGET_CMOVE)
17668 {
17669 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
17670 DONE;
17671 }
17672
17673 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
17674
17675 operands[2] = gen_reg_rtx (<MODE>mode);
17676 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
17677 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
17678 })
17679
17680 (define_insn_and_split "ffssi2_no_cmove"
17681 [(set (match_operand:SI 0 "register_operand" "=r")
17682 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
17683 (clobber (match_scratch:SI 2 "=&q"))
17684 (clobber (reg:CC FLAGS_REG))]
17685 "!TARGET_CMOVE"
17686 "#"
17687 "&& reload_completed"
17688 [(parallel [(set (match_dup 4) (match_dup 5))
17689 (set (match_dup 0) (ctz:SI (match_dup 1)))])
17690 (set (strict_low_part (match_dup 3))
17691 (eq:QI (match_dup 4) (const_int 0)))
17692 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
17693 (clobber (reg:CC FLAGS_REG))])
17694 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
17695 (clobber (reg:CC FLAGS_REG))])
17696 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
17697 (clobber (reg:CC FLAGS_REG))])]
17698 {
17699 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
17700
17701 operands[3] = gen_lowpart (QImode, operands[2]);
17702 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
17703 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
17704
17705 ix86_expand_clear (operands[2]);
17706 })
17707
17708 (define_insn_and_split "*tzcnt<mode>_1"
17709 [(set (reg:CCC FLAGS_REG)
17710 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17711 (const_int 0)))
17712 (set (match_operand:SWI48 0 "register_operand" "=r")
17713 (ctz:SWI48 (match_dup 1)))]
17714 "TARGET_BMI"
17715 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17716 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17717 && optimize_function_for_speed_p (cfun)
17718 && !reg_mentioned_p (operands[0], operands[1])"
17719 [(parallel
17720 [(set (reg:CCC FLAGS_REG)
17721 (compare:CCC (match_dup 1) (const_int 0)))
17722 (set (match_dup 0)
17723 (ctz:SWI48 (match_dup 1)))
17724 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
17725 "ix86_expand_clear (operands[0]);"
17726 [(set_attr "type" "alu1")
17727 (set_attr "prefix_0f" "1")
17728 (set_attr "prefix_rep" "1")
17729 (set_attr "btver2_decode" "double")
17730 (set_attr "mode" "<MODE>")])
17731
17732 ; False dependency happens when destination is only updated by tzcnt,
17733 ; lzcnt or popcnt. There is no false dependency when destination is
17734 ; also used in source.
17735 (define_insn "*tzcnt<mode>_1_falsedep"
17736 [(set (reg:CCC FLAGS_REG)
17737 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17738 (const_int 0)))
17739 (set (match_operand:SWI48 0 "register_operand" "=r")
17740 (ctz:SWI48 (match_dup 1)))
17741 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
17742 UNSPEC_INSN_FALSE_DEP)]
17743 "TARGET_BMI"
17744 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17745 [(set_attr "type" "alu1")
17746 (set_attr "prefix_0f" "1")
17747 (set_attr "prefix_rep" "1")
17748 (set_attr "btver2_decode" "double")
17749 (set_attr "mode" "<MODE>")])
17750
17751 (define_insn "*bsf<mode>_1"
17752 [(set (reg:CCZ FLAGS_REG)
17753 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17754 (const_int 0)))
17755 (set (match_operand:SWI48 0 "register_operand" "=r")
17756 (ctz:SWI48 (match_dup 1)))]
17757 ""
17758 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
17759 [(set_attr "type" "alu1")
17760 (set_attr "prefix_0f" "1")
17761 (set_attr "btver2_decode" "double")
17762 (set_attr "znver1_decode" "vector")
17763 (set_attr "mode" "<MODE>")])
17764
17765 (define_insn_and_split "ctz<mode>2"
17766 [(set (match_operand:SWI48 0 "register_operand" "=r")
17767 (ctz:SWI48
17768 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
17769 (clobber (reg:CC FLAGS_REG))]
17770 ""
17771 {
17772 if (TARGET_BMI)
17773 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17774 else if (optimize_function_for_size_p (cfun))
17775 ;
17776 else if (TARGET_CPU_P (GENERIC))
17777 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17778 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17779
17780 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17781 }
17782 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
17783 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17784 && optimize_function_for_speed_p (cfun)
17785 && !reg_mentioned_p (operands[0], operands[1])"
17786 [(parallel
17787 [(set (match_dup 0)
17788 (ctz:SWI48 (match_dup 1)))
17789 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17790 (clobber (reg:CC FLAGS_REG))])]
17791 "ix86_expand_clear (operands[0]);"
17792 [(set_attr "type" "alu1")
17793 (set_attr "prefix_0f" "1")
17794 (set (attr "prefix_rep")
17795 (if_then_else
17796 (ior (match_test "TARGET_BMI")
17797 (and (not (match_test "optimize_function_for_size_p (cfun)"))
17798 (match_test "TARGET_CPU_P (GENERIC)")))
17799 (const_string "1")
17800 (const_string "0")))
17801 (set_attr "mode" "<MODE>")])
17802
17803 ; False dependency happens when destination is only updated by tzcnt,
17804 ; lzcnt or popcnt. There is no false dependency when destination is
17805 ; also used in source.
17806 (define_insn "*ctz<mode>2_falsedep"
17807 [(set (match_operand:SWI48 0 "register_operand" "=r")
17808 (ctz:SWI48
17809 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
17810 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
17811 UNSPEC_INSN_FALSE_DEP)
17812 (clobber (reg:CC FLAGS_REG))]
17813 ""
17814 {
17815 if (TARGET_BMI)
17816 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17817 else if (TARGET_CPU_P (GENERIC))
17818 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17819 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17820 else
17821 gcc_unreachable ();
17822 }
17823 [(set_attr "type" "alu1")
17824 (set_attr "prefix_0f" "1")
17825 (set_attr "prefix_rep" "1")
17826 (set_attr "mode" "<MODE>")])
17827
17828 (define_insn_and_split "*ctzsi2_zext"
17829 [(set (match_operand:DI 0 "register_operand" "=r")
17830 (and:DI
17831 (subreg:DI
17832 (ctz:SI
17833 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
17834 (const_int 63)))
17835 (clobber (reg:CC FLAGS_REG))]
17836 "TARGET_BMI && TARGET_64BIT"
17837 "tzcnt{l}\t{%1, %k0|%k0, %1}"
17838 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17839 && optimize_function_for_speed_p (cfun)
17840 && !reg_mentioned_p (operands[0], operands[1])"
17841 [(parallel
17842 [(set (match_dup 0)
17843 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
17844 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17845 (clobber (reg:CC FLAGS_REG))])]
17846 "ix86_expand_clear (operands[0]);"
17847 [(set_attr "type" "alu1")
17848 (set_attr "prefix_0f" "1")
17849 (set_attr "prefix_rep" "1")
17850 (set_attr "mode" "SI")])
17851
17852 ; False dependency happens when destination is only updated by tzcnt,
17853 ; lzcnt or popcnt. There is no false dependency when destination is
17854 ; also used in source.
17855 (define_insn "*ctzsi2_zext_falsedep"
17856 [(set (match_operand:DI 0 "register_operand" "=r")
17857 (and:DI
17858 (subreg:DI
17859 (ctz:SI
17860 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
17861 (const_int 63)))
17862 (unspec [(match_operand:DI 2 "register_operand" "0")]
17863 UNSPEC_INSN_FALSE_DEP)
17864 (clobber (reg:CC FLAGS_REG))]
17865 "TARGET_BMI && TARGET_64BIT"
17866 "tzcnt{l}\t{%1, %k0|%k0, %1}"
17867 [(set_attr "type" "alu1")
17868 (set_attr "prefix_0f" "1")
17869 (set_attr "prefix_rep" "1")
17870 (set_attr "mode" "SI")])
17871
17872 (define_insn_and_split "*ctzsidi2_<s>ext"
17873 [(set (match_operand:DI 0 "register_operand" "=r")
17874 (any_extend:DI
17875 (ctz:SI
17876 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
17877 (clobber (reg:CC FLAGS_REG))]
17878 "TARGET_64BIT"
17879 {
17880 if (TARGET_BMI)
17881 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
17882 else if (TARGET_CPU_P (GENERIC)
17883 && !optimize_function_for_size_p (cfun))
17884 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17885 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
17886 return "bsf{l}\t{%1, %k0|%k0, %1}";
17887 }
17888 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
17889 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17890 && optimize_function_for_speed_p (cfun)
17891 && !reg_mentioned_p (operands[0], operands[1])"
17892 [(parallel
17893 [(set (match_dup 0)
17894 (any_extend:DI (ctz:SI (match_dup 1))))
17895 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17896 (clobber (reg:CC FLAGS_REG))])]
17897 "ix86_expand_clear (operands[0]);"
17898 [(set_attr "type" "alu1")
17899 (set_attr "prefix_0f" "1")
17900 (set (attr "prefix_rep")
17901 (if_then_else
17902 (ior (match_test "TARGET_BMI")
17903 (and (not (match_test "optimize_function_for_size_p (cfun)"))
17904 (match_test "TARGET_CPU_P (GENERIC)")))
17905 (const_string "1")
17906 (const_string "0")))
17907 (set_attr "mode" "SI")])
17908
17909 (define_insn "*ctzsidi2_<s>ext_falsedep"
17910 [(set (match_operand:DI 0 "register_operand" "=r")
17911 (any_extend:DI
17912 (ctz:SI
17913 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
17914 (unspec [(match_operand:DI 2 "register_operand" "0")]
17915 UNSPEC_INSN_FALSE_DEP)
17916 (clobber (reg:CC FLAGS_REG))]
17917 "TARGET_64BIT"
17918 {
17919 if (TARGET_BMI)
17920 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
17921 else if (TARGET_CPU_P (GENERIC))
17922 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17923 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
17924 else
17925 gcc_unreachable ();
17926 }
17927 [(set_attr "type" "alu1")
17928 (set_attr "prefix_0f" "1")
17929 (set_attr "prefix_rep" "1")
17930 (set_attr "mode" "SI")])
17931
17932 (define_insn "bsr_rex64"
17933 [(set (reg:CCZ FLAGS_REG)
17934 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
17935 (const_int 0)))
17936 (set (match_operand:DI 0 "register_operand" "=r")
17937 (minus:DI (const_int 63)
17938 (clz:DI (match_dup 1))))]
17939 "TARGET_64BIT"
17940 "bsr{q}\t{%1, %0|%0, %1}"
17941 [(set_attr "type" "alu1")
17942 (set_attr "prefix_0f" "1")
17943 (set_attr "znver1_decode" "vector")
17944 (set_attr "mode" "DI")])
17945
17946 (define_insn "bsr_rex64_1"
17947 [(set (match_operand:DI 0 "register_operand" "=r")
17948 (minus:DI (const_int 63)
17949 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
17950 (clobber (reg:CC FLAGS_REG))]
17951 "!TARGET_LZCNT && TARGET_64BIT"
17952 "bsr{q}\t{%1, %0|%0, %1}"
17953 [(set_attr "type" "alu1")
17954 (set_attr "prefix_0f" "1")
17955 (set_attr "znver1_decode" "vector")
17956 (set_attr "mode" "DI")])
17957
17958 (define_insn "bsr_rex64_1_zext"
17959 [(set (match_operand:DI 0 "register_operand" "=r")
17960 (zero_extend:DI
17961 (minus:SI (const_int 63)
17962 (subreg:SI
17963 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
17964 0))))
17965 (clobber (reg:CC FLAGS_REG))]
17966 "!TARGET_LZCNT && TARGET_64BIT"
17967 "bsr{q}\t{%1, %0|%0, %1}"
17968 [(set_attr "type" "alu1")
17969 (set_attr "prefix_0f" "1")
17970 (set_attr "znver1_decode" "vector")
17971 (set_attr "mode" "DI")])
17972
17973 (define_insn "bsr"
17974 [(set (reg:CCZ FLAGS_REG)
17975 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
17976 (const_int 0)))
17977 (set (match_operand:SI 0 "register_operand" "=r")
17978 (minus:SI (const_int 31)
17979 (clz:SI (match_dup 1))))]
17980 ""
17981 "bsr{l}\t{%1, %0|%0, %1}"
17982 [(set_attr "type" "alu1")
17983 (set_attr "prefix_0f" "1")
17984 (set_attr "znver1_decode" "vector")
17985 (set_attr "mode" "SI")])
17986
17987 (define_insn "bsr_1"
17988 [(set (match_operand:SI 0 "register_operand" "=r")
17989 (minus:SI (const_int 31)
17990 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
17991 (clobber (reg:CC FLAGS_REG))]
17992 "!TARGET_LZCNT"
17993 "bsr{l}\t{%1, %0|%0, %1}"
17994 [(set_attr "type" "alu1")
17995 (set_attr "prefix_0f" "1")
17996 (set_attr "znver1_decode" "vector")
17997 (set_attr "mode" "SI")])
17998
17999 (define_insn "bsr_zext_1"
18000 [(set (match_operand:DI 0 "register_operand" "=r")
18001 (zero_extend:DI
18002 (minus:SI
18003 (const_int 31)
18004 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18005 (clobber (reg:CC FLAGS_REG))]
18006 "!TARGET_LZCNT && TARGET_64BIT"
18007 "bsr{l}\t{%1, %k0|%k0, %1}"
18008 [(set_attr "type" "alu1")
18009 (set_attr "prefix_0f" "1")
18010 (set_attr "znver1_decode" "vector")
18011 (set_attr "mode" "SI")])
18012
18013 ; As bsr is undefined behavior on zero and for other input
18014 ; values it is in range 0 to 63, we can optimize away sign-extends.
18015 (define_insn_and_split "*bsr_rex64_2"
18016 [(set (match_operand:DI 0 "register_operand")
18017 (xor:DI
18018 (sign_extend:DI
18019 (minus:SI
18020 (const_int 63)
18021 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18022 0)))
18023 (const_int 63)))
18024 (clobber (reg:CC FLAGS_REG))]
18025 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18026 "#"
18027 "&& 1"
18028 [(parallel [(set (reg:CCZ FLAGS_REG)
18029 (compare:CCZ (match_dup 1) (const_int 0)))
18030 (set (match_dup 2)
18031 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18032 (parallel [(set (match_dup 0)
18033 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18034 (clobber (reg:CC FLAGS_REG))])]
18035 {
18036 operands[2] = gen_reg_rtx (DImode);
18037 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18038 })
18039
18040 (define_insn_and_split "*bsr_2"
18041 [(set (match_operand:DI 0 "register_operand")
18042 (sign_extend:DI
18043 (xor:SI
18044 (minus:SI
18045 (const_int 31)
18046 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18047 (const_int 31))))
18048 (clobber (reg:CC FLAGS_REG))]
18049 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18050 "#"
18051 "&& 1"
18052 [(parallel [(set (reg:CCZ FLAGS_REG)
18053 (compare:CCZ (match_dup 1) (const_int 0)))
18054 (set (match_dup 2)
18055 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18056 (parallel [(set (match_dup 0)
18057 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18058 (clobber (reg:CC FLAGS_REG))])]
18059 "operands[2] = gen_reg_rtx (SImode);")
18060
18061 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18062 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18063 ; in [0, 63] or [0, 31] range.
18064 (define_split
18065 [(set (match_operand:SI 0 "register_operand")
18066 (minus:SI
18067 (match_operand:SI 2 "const_int_operand")
18068 (xor:SI
18069 (minus:SI (const_int 63)
18070 (subreg:SI
18071 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18072 0))
18073 (const_int 63))))]
18074 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18075 [(set (match_dup 3)
18076 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18077 (set (match_dup 0)
18078 (plus:SI (match_dup 5) (match_dup 4)))]
18079 {
18080 operands[3] = gen_reg_rtx (DImode);
18081 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18082 if (INTVAL (operands[2]) == 63)
18083 {
18084 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18085 emit_move_insn (operands[0], operands[5]);
18086 DONE;
18087 }
18088 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18089 })
18090
18091 (define_split
18092 [(set (match_operand:SI 0 "register_operand")
18093 (minus:SI
18094 (match_operand:SI 2 "const_int_operand")
18095 (xor:SI
18096 (minus:SI (const_int 31)
18097 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18098 (const_int 31))))]
18099 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18100 [(set (match_dup 3)
18101 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18102 (set (match_dup 0)
18103 (plus:SI (match_dup 3) (match_dup 4)))]
18104 {
18105 if (INTVAL (operands[2]) == 31)
18106 {
18107 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18108 DONE;
18109 }
18110 operands[3] = gen_reg_rtx (SImode);
18111 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18112 })
18113
18114 (define_split
18115 [(set (match_operand:DI 0 "register_operand")
18116 (minus:DI
18117 (match_operand:DI 2 "const_int_operand")
18118 (xor:DI
18119 (sign_extend:DI
18120 (minus:SI (const_int 63)
18121 (subreg:SI
18122 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18123 0)))
18124 (const_int 63))))]
18125 "!TARGET_LZCNT
18126 && TARGET_64BIT
18127 && ix86_pre_reload_split ()
18128 && ((unsigned HOST_WIDE_INT)
18129 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18130 == UINTVAL (operands[2]) - 63)"
18131 [(set (match_dup 3)
18132 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18133 (set (match_dup 0)
18134 (plus:DI (match_dup 3) (match_dup 4)))]
18135 {
18136 if (INTVAL (operands[2]) == 63)
18137 {
18138 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18139 DONE;
18140 }
18141 operands[3] = gen_reg_rtx (DImode);
18142 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18143 })
18144
18145 (define_split
18146 [(set (match_operand:DI 0 "register_operand")
18147 (minus:DI
18148 (match_operand:DI 2 "const_int_operand")
18149 (sign_extend:DI
18150 (xor:SI
18151 (minus:SI (const_int 31)
18152 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18153 (const_int 31)))))]
18154 "!TARGET_LZCNT
18155 && TARGET_64BIT
18156 && ix86_pre_reload_split ()
18157 && ((unsigned HOST_WIDE_INT)
18158 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18159 == UINTVAL (operands[2]) - 31)"
18160 [(set (match_dup 3)
18161 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18162 (set (match_dup 0)
18163 (plus:DI (match_dup 3) (match_dup 4)))]
18164 {
18165 if (INTVAL (operands[2]) == 31)
18166 {
18167 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18168 DONE;
18169 }
18170 operands[3] = gen_reg_rtx (DImode);
18171 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18172 })
18173
18174 (define_expand "clz<mode>2"
18175 [(parallel
18176 [(set (reg:CCZ FLAGS_REG)
18177 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18178 (const_int 0)))
18179 (set (match_dup 3) (minus:SWI48
18180 (match_dup 2)
18181 (clz:SWI48 (match_dup 1))))])
18182 (parallel
18183 [(set (match_operand:SWI48 0 "register_operand")
18184 (xor:SWI48 (match_dup 3) (match_dup 2)))
18185 (clobber (reg:CC FLAGS_REG))])]
18186 ""
18187 {
18188 if (TARGET_LZCNT)
18189 {
18190 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18191 DONE;
18192 }
18193 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18194 operands[3] = gen_reg_rtx (<MODE>mode);
18195 })
18196
18197 (define_insn_and_split "clz<mode>2_lzcnt"
18198 [(set (match_operand:SWI48 0 "register_operand" "=r")
18199 (clz:SWI48
18200 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18201 (clobber (reg:CC FLAGS_REG))]
18202 "TARGET_LZCNT"
18203 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18204 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18205 && optimize_function_for_speed_p (cfun)
18206 && !reg_mentioned_p (operands[0], operands[1])"
18207 [(parallel
18208 [(set (match_dup 0)
18209 (clz:SWI48 (match_dup 1)))
18210 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18211 (clobber (reg:CC FLAGS_REG))])]
18212 "ix86_expand_clear (operands[0]);"
18213 [(set_attr "prefix_rep" "1")
18214 (set_attr "type" "bitmanip")
18215 (set_attr "mode" "<MODE>")])
18216
18217 ; False dependency happens when destination is only updated by tzcnt,
18218 ; lzcnt or popcnt. There is no false dependency when destination is
18219 ; also used in source.
18220 (define_insn "*clz<mode>2_lzcnt_falsedep"
18221 [(set (match_operand:SWI48 0 "register_operand" "=r")
18222 (clz:SWI48
18223 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18224 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18225 UNSPEC_INSN_FALSE_DEP)
18226 (clobber (reg:CC FLAGS_REG))]
18227 "TARGET_LZCNT"
18228 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18229 [(set_attr "prefix_rep" "1")
18230 (set_attr "type" "bitmanip")
18231 (set_attr "mode" "<MODE>")])
18232
18233 (define_insn_and_split "*clzsi2_lzcnt_zext"
18234 [(set (match_operand:DI 0 "register_operand" "=r")
18235 (and:DI
18236 (subreg:DI
18237 (clz:SI
18238 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18239 (const_int 63)))
18240 (clobber (reg:CC FLAGS_REG))]
18241 "TARGET_LZCNT && TARGET_64BIT"
18242 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18243 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18244 && optimize_function_for_speed_p (cfun)
18245 && !reg_mentioned_p (operands[0], operands[1])"
18246 [(parallel
18247 [(set (match_dup 0)
18248 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18249 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18250 (clobber (reg:CC FLAGS_REG))])]
18251 "ix86_expand_clear (operands[0]);"
18252 [(set_attr "prefix_rep" "1")
18253 (set_attr "type" "bitmanip")
18254 (set_attr "mode" "SI")])
18255
18256 ; False dependency happens when destination is only updated by tzcnt,
18257 ; lzcnt or popcnt. There is no false dependency when destination is
18258 ; also used in source.
18259 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18260 [(set (match_operand:DI 0 "register_operand" "=r")
18261 (and:DI
18262 (subreg:DI
18263 (clz:SI
18264 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18265 (const_int 63)))
18266 (unspec [(match_operand:DI 2 "register_operand" "0")]
18267 UNSPEC_INSN_FALSE_DEP)
18268 (clobber (reg:CC FLAGS_REG))]
18269 "TARGET_LZCNT"
18270 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18271 [(set_attr "prefix_rep" "1")
18272 (set_attr "type" "bitmanip")
18273 (set_attr "mode" "SI")])
18274
18275 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18276 [(set (match_operand:DI 0 "register_operand" "=r")
18277 (zero_extend:DI
18278 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18279 (clobber (reg:CC FLAGS_REG))]
18280 "TARGET_LZCNT && TARGET_64BIT"
18281 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18282 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18283 && optimize_function_for_speed_p (cfun)
18284 && !reg_mentioned_p (operands[0], operands[1])"
18285 [(parallel
18286 [(set (match_dup 0)
18287 (zero_extend:DI (clz:SI (match_dup 1))))
18288 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18289 (clobber (reg:CC FLAGS_REG))])]
18290 "ix86_expand_clear (operands[0]);"
18291 [(set_attr "prefix_rep" "1")
18292 (set_attr "type" "bitmanip")
18293 (set_attr "mode" "SI")])
18294
18295 ; False dependency happens when destination is only updated by tzcnt,
18296 ; lzcnt or popcnt. There is no false dependency when destination is
18297 ; also used in source.
18298 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18299 [(set (match_operand:DI 0 "register_operand" "=r")
18300 (zero_extend:DI
18301 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18302 (unspec [(match_operand:DI 2 "register_operand" "0")]
18303 UNSPEC_INSN_FALSE_DEP)
18304 (clobber (reg:CC FLAGS_REG))]
18305 "TARGET_LZCNT"
18306 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18307 [(set_attr "prefix_rep" "1")
18308 (set_attr "type" "bitmanip")
18309 (set_attr "mode" "SI")])
18310
18311 (define_int_iterator LT_ZCNT
18312 [(UNSPEC_TZCNT "TARGET_BMI")
18313 (UNSPEC_LZCNT "TARGET_LZCNT")])
18314
18315 (define_int_attr lt_zcnt
18316 [(UNSPEC_TZCNT "tzcnt")
18317 (UNSPEC_LZCNT "lzcnt")])
18318
18319 (define_int_attr lt_zcnt_type
18320 [(UNSPEC_TZCNT "alu1")
18321 (UNSPEC_LZCNT "bitmanip")])
18322
18323 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
18324 ;; provides operand size as output when source operand is zero.
18325
18326 (define_insn_and_split "<lt_zcnt>_<mode>"
18327 [(set (match_operand:SWI48 0 "register_operand" "=r")
18328 (unspec:SWI48
18329 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18330 (clobber (reg:CC FLAGS_REG))]
18331 ""
18332 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18333 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18334 && optimize_function_for_speed_p (cfun)
18335 && !reg_mentioned_p (operands[0], operands[1])"
18336 [(parallel
18337 [(set (match_dup 0)
18338 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18339 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18340 (clobber (reg:CC FLAGS_REG))])]
18341 "ix86_expand_clear (operands[0]);"
18342 [(set_attr "type" "<lt_zcnt_type>")
18343 (set_attr "prefix_0f" "1")
18344 (set_attr "prefix_rep" "1")
18345 (set_attr "mode" "<MODE>")])
18346
18347 ; False dependency happens when destination is only updated by tzcnt,
18348 ; lzcnt or popcnt. There is no false dependency when destination is
18349 ; also used in source.
18350 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18351 [(set (match_operand:SWI48 0 "register_operand" "=r")
18352 (unspec:SWI48
18353 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18354 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18355 UNSPEC_INSN_FALSE_DEP)
18356 (clobber (reg:CC FLAGS_REG))]
18357 ""
18358 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18359 [(set_attr "type" "<lt_zcnt_type>")
18360 (set_attr "prefix_0f" "1")
18361 (set_attr "prefix_rep" "1")
18362 (set_attr "mode" "<MODE>")])
18363
18364 (define_insn "<lt_zcnt>_hi"
18365 [(set (match_operand:HI 0 "register_operand" "=r")
18366 (unspec:HI
18367 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18368 (clobber (reg:CC FLAGS_REG))]
18369 ""
18370 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18371 [(set_attr "type" "<lt_zcnt_type>")
18372 (set_attr "prefix_0f" "1")
18373 (set_attr "prefix_rep" "1")
18374 (set_attr "mode" "HI")])
18375
18376 ;; BMI instructions.
18377
18378 (define_insn "bmi_bextr_<mode>"
18379 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18380 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18381 (match_operand:SWI48 2 "register_operand" "r,r")]
18382 UNSPEC_BEXTR))
18383 (clobber (reg:CC FLAGS_REG))]
18384 "TARGET_BMI"
18385 "bextr\t{%2, %1, %0|%0, %1, %2}"
18386 [(set_attr "type" "bitmanip")
18387 (set_attr "btver2_decode" "direct, double")
18388 (set_attr "mode" "<MODE>")])
18389
18390 (define_insn "*bmi_bextr_<mode>_ccz"
18391 [(set (reg:CCZ FLAGS_REG)
18392 (compare:CCZ
18393 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18394 (match_operand:SWI48 2 "register_operand" "r,r")]
18395 UNSPEC_BEXTR)
18396 (const_int 0)))
18397 (clobber (match_scratch:SWI48 0 "=r,r"))]
18398 "TARGET_BMI"
18399 "bextr\t{%2, %1, %0|%0, %1, %2}"
18400 [(set_attr "type" "bitmanip")
18401 (set_attr "btver2_decode" "direct, double")
18402 (set_attr "mode" "<MODE>")])
18403
18404 (define_insn "*bmi_blsi_<mode>"
18405 [(set (match_operand:SWI48 0 "register_operand" "=r")
18406 (and:SWI48
18407 (neg:SWI48
18408 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18409 (match_dup 1)))
18410 (clobber (reg:CC FLAGS_REG))]
18411 "TARGET_BMI"
18412 "blsi\t{%1, %0|%0, %1}"
18413 [(set_attr "type" "bitmanip")
18414 (set_attr "btver2_decode" "double")
18415 (set_attr "mode" "<MODE>")])
18416
18417 (define_insn "*bmi_blsi_<mode>_cmp"
18418 [(set (reg FLAGS_REG)
18419 (compare
18420 (and:SWI48
18421 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18422 (match_dup 1))
18423 (const_int 0)))
18424 (set (match_operand:SWI48 0 "register_operand" "=r")
18425 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
18426 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18427 "blsi\t{%1, %0|%0, %1}"
18428 [(set_attr "type" "bitmanip")
18429 (set_attr "btver2_decode" "double")
18430 (set_attr "mode" "<MODE>")])
18431
18432 (define_insn "*bmi_blsi_<mode>_ccno"
18433 [(set (reg FLAGS_REG)
18434 (compare
18435 (and:SWI48
18436 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18437 (match_dup 1))
18438 (const_int 0)))
18439 (clobber (match_scratch:SWI48 0 "=r"))]
18440 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18441 "blsi\t{%1, %0|%0, %1}"
18442 [(set_attr "type" "bitmanip")
18443 (set_attr "btver2_decode" "double")
18444 (set_attr "mode" "<MODE>")])
18445
18446 (define_insn "*bmi_blsmsk_<mode>"
18447 [(set (match_operand:SWI48 0 "register_operand" "=r")
18448 (xor:SWI48
18449 (plus:SWI48
18450 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18451 (const_int -1))
18452 (match_dup 1)))
18453 (clobber (reg:CC FLAGS_REG))]
18454 "TARGET_BMI"
18455 "blsmsk\t{%1, %0|%0, %1}"
18456 [(set_attr "type" "bitmanip")
18457 (set_attr "btver2_decode" "double")
18458 (set_attr "mode" "<MODE>")])
18459
18460 (define_insn "*bmi_blsr_<mode>"
18461 [(set (match_operand:SWI48 0 "register_operand" "=r")
18462 (and:SWI48
18463 (plus:SWI48
18464 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18465 (const_int -1))
18466 (match_dup 1)))
18467 (clobber (reg:CC FLAGS_REG))]
18468 "TARGET_BMI"
18469 "blsr\t{%1, %0|%0, %1}"
18470 [(set_attr "type" "bitmanip")
18471 (set_attr "btver2_decode" "double")
18472 (set_attr "mode" "<MODE>")])
18473
18474 (define_insn "*bmi_blsr_<mode>_cmp"
18475 [(set (reg:CCZ FLAGS_REG)
18476 (compare:CCZ
18477 (and:SWI48
18478 (plus:SWI48
18479 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18480 (const_int -1))
18481 (match_dup 1))
18482 (const_int 0)))
18483 (set (match_operand:SWI48 0 "register_operand" "=r")
18484 (and:SWI48
18485 (plus:SWI48
18486 (match_dup 1)
18487 (const_int -1))
18488 (match_dup 1)))]
18489 "TARGET_BMI"
18490 "blsr\t{%1, %0|%0, %1}"
18491 [(set_attr "type" "bitmanip")
18492 (set_attr "btver2_decode" "double")
18493 (set_attr "mode" "<MODE>")])
18494
18495 (define_insn "*bmi_blsr_<mode>_ccz"
18496 [(set (reg:CCZ FLAGS_REG)
18497 (compare:CCZ
18498 (and:SWI48
18499 (plus:SWI48
18500 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18501 (const_int -1))
18502 (match_dup 1))
18503 (const_int 0)))
18504 (clobber (match_scratch:SWI48 0 "=r"))]
18505 "TARGET_BMI"
18506 "blsr\t{%1, %0|%0, %1}"
18507 [(set_attr "type" "bitmanip")
18508 (set_attr "btver2_decode" "double")
18509 (set_attr "mode" "<MODE>")])
18510
18511 ;; BMI2 instructions.
18512 (define_expand "bmi2_bzhi_<mode>3"
18513 [(parallel
18514 [(set (match_operand:SWI48 0 "register_operand")
18515 (if_then_else:SWI48
18516 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
18517 (const_int 255))
18518 (const_int 0))
18519 (zero_extract:SWI48
18520 (match_operand:SWI48 1 "nonimmediate_operand")
18521 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
18522 (match_dup 3))
18523 (const_int 0))
18524 (const_int 0)))
18525 (clobber (reg:CC FLAGS_REG))])]
18526 "TARGET_BMI2"
18527 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
18528
18529 (define_insn "*bmi2_bzhi_<mode>3"
18530 [(set (match_operand:SWI48 0 "register_operand" "=r")
18531 (if_then_else:SWI48
18532 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
18533 (const_int 255))
18534 (const_int 0))
18535 (zero_extract:SWI48
18536 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18537 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
18538 (match_operand:SWI48 3 "const_int_operand"))
18539 (const_int 0))
18540 (const_int 0)))
18541 (clobber (reg:CC FLAGS_REG))]
18542 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18543 "bzhi\t{%2, %1, %0|%0, %1, %2}"
18544 [(set_attr "type" "bitmanip")
18545 (set_attr "prefix" "vex")
18546 (set_attr "mode" "<MODE>")])
18547
18548 (define_insn "*bmi2_bzhi_<mode>3_1"
18549 [(set (match_operand:SWI48 0 "register_operand" "=r")
18550 (if_then_else:SWI48
18551 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18552 (zero_extract:SWI48
18553 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18554 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
18555 (match_operand:SWI48 3 "const_int_operand"))
18556 (const_int 0))
18557 (const_int 0)))
18558 (clobber (reg:CC FLAGS_REG))]
18559 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18560 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18561 [(set_attr "type" "bitmanip")
18562 (set_attr "prefix" "vex")
18563 (set_attr "mode" "<MODE>")])
18564
18565 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
18566 [(set (reg:CCZ FLAGS_REG)
18567 (compare:CCZ
18568 (if_then_else:SWI48
18569 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18570 (zero_extract:SWI48
18571 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18572 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
18573 (match_operand:SWI48 3 "const_int_operand"))
18574 (const_int 0))
18575 (const_int 0))
18576 (const_int 0)))
18577 (clobber (match_scratch:SWI48 0 "=r"))]
18578 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18579 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18580 [(set_attr "type" "bitmanip")
18581 (set_attr "prefix" "vex")
18582 (set_attr "mode" "<MODE>")])
18583
18584 (define_insn "*bmi2_bzhi_<mode>3_2"
18585 [(set (match_operand:SWI48 0 "register_operand" "=r")
18586 (and:SWI48
18587 (plus:SWI48
18588 (ashift:SWI48 (const_int 1)
18589 (match_operand:QI 2 "register_operand" "r"))
18590 (const_int -1))
18591 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18592 (clobber (reg:CC FLAGS_REG))]
18593 "TARGET_BMI2"
18594 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18595 [(set_attr "type" "bitmanip")
18596 (set_attr "prefix" "vex")
18597 (set_attr "mode" "<MODE>")])
18598
18599 (define_insn "*bmi2_bzhi_<mode>3_3"
18600 [(set (match_operand:SWI48 0 "register_operand" "=r")
18601 (and:SWI48
18602 (not:SWI48
18603 (ashift:SWI48 (const_int -1)
18604 (match_operand:QI 2 "register_operand" "r")))
18605 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18606 (clobber (reg:CC FLAGS_REG))]
18607 "TARGET_BMI2"
18608 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18609 [(set_attr "type" "bitmanip")
18610 (set_attr "prefix" "vex")
18611 (set_attr "mode" "<MODE>")])
18612
18613 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
18614 [(set (match_operand:DI 0 "register_operand" "=r")
18615 (zero_extend:DI
18616 (and:SI
18617 (plus:SI
18618 (ashift:SI (const_int 1)
18619 (match_operand:QI 2 "register_operand" "r"))
18620 (const_int -1))
18621 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18622 (clobber (reg:CC FLAGS_REG))]
18623 "TARGET_64BIT && TARGET_BMI2"
18624 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18625 [(set_attr "type" "bitmanip")
18626 (set_attr "prefix" "vex")
18627 (set_attr "mode" "DI")])
18628
18629 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
18630 [(set (match_operand:DI 0 "register_operand" "=r")
18631 (and:DI
18632 (zero_extend:DI
18633 (plus:SI
18634 (ashift:SI (const_int 1)
18635 (match_operand:QI 2 "register_operand" "r"))
18636 (const_int -1)))
18637 (match_operand:DI 1 "nonimmediate_operand" "rm")))
18638 (clobber (reg:CC FLAGS_REG))]
18639 "TARGET_64BIT && TARGET_BMI2"
18640 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18641 [(set_attr "type" "bitmanip")
18642 (set_attr "prefix" "vex")
18643 (set_attr "mode" "DI")])
18644
18645 (define_insn "bmi2_pdep_<mode>3"
18646 [(set (match_operand:SWI48 0 "register_operand" "=r")
18647 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18648 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18649 UNSPEC_PDEP))]
18650 "TARGET_BMI2"
18651 "pdep\t{%2, %1, %0|%0, %1, %2}"
18652 [(set_attr "type" "bitmanip")
18653 (set_attr "prefix" "vex")
18654 (set_attr "mode" "<MODE>")])
18655
18656 (define_insn "bmi2_pext_<mode>3"
18657 [(set (match_operand:SWI48 0 "register_operand" "=r")
18658 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18659 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18660 UNSPEC_PEXT))]
18661 "TARGET_BMI2"
18662 "pext\t{%2, %1, %0|%0, %1, %2}"
18663 [(set_attr "type" "bitmanip")
18664 (set_attr "prefix" "vex")
18665 (set_attr "mode" "<MODE>")])
18666
18667 ;; TBM instructions.
18668 (define_insn "@tbm_bextri_<mode>"
18669 [(set (match_operand:SWI48 0 "register_operand" "=r")
18670 (zero_extract:SWI48
18671 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18672 (match_operand 2 "const_0_to_255_operand")
18673 (match_operand 3 "const_0_to_255_operand")))
18674 (clobber (reg:CC FLAGS_REG))]
18675 "TARGET_TBM"
18676 {
18677 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
18678 return "bextr\t{%2, %1, %0|%0, %1, %2}";
18679 }
18680 [(set_attr "type" "bitmanip")
18681 (set_attr "mode" "<MODE>")])
18682
18683 (define_insn "*tbm_blcfill_<mode>"
18684 [(set (match_operand:SWI48 0 "register_operand" "=r")
18685 (and:SWI48
18686 (plus:SWI48
18687 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18688 (const_int 1))
18689 (match_dup 1)))
18690 (clobber (reg:CC FLAGS_REG))]
18691 "TARGET_TBM"
18692 "blcfill\t{%1, %0|%0, %1}"
18693 [(set_attr "type" "bitmanip")
18694 (set_attr "mode" "<MODE>")])
18695
18696 (define_insn "*tbm_blci_<mode>"
18697 [(set (match_operand:SWI48 0 "register_operand" "=r")
18698 (ior:SWI48
18699 (not:SWI48
18700 (plus:SWI48
18701 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18702 (const_int 1)))
18703 (match_dup 1)))
18704 (clobber (reg:CC FLAGS_REG))]
18705 "TARGET_TBM"
18706 "blci\t{%1, %0|%0, %1}"
18707 [(set_attr "type" "bitmanip")
18708 (set_attr "mode" "<MODE>")])
18709
18710 (define_insn "*tbm_blcic_<mode>"
18711 [(set (match_operand:SWI48 0 "register_operand" "=r")
18712 (and:SWI48
18713 (plus:SWI48
18714 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18715 (const_int 1))
18716 (not:SWI48
18717 (match_dup 1))))
18718 (clobber (reg:CC FLAGS_REG))]
18719 "TARGET_TBM"
18720 "blcic\t{%1, %0|%0, %1}"
18721 [(set_attr "type" "bitmanip")
18722 (set_attr "mode" "<MODE>")])
18723
18724 (define_insn "*tbm_blcmsk_<mode>"
18725 [(set (match_operand:SWI48 0 "register_operand" "=r")
18726 (xor:SWI48
18727 (plus:SWI48
18728 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18729 (const_int 1))
18730 (match_dup 1)))
18731 (clobber (reg:CC FLAGS_REG))]
18732 "TARGET_TBM"
18733 "blcmsk\t{%1, %0|%0, %1}"
18734 [(set_attr "type" "bitmanip")
18735 (set_attr "mode" "<MODE>")])
18736
18737 (define_insn "*tbm_blcs_<mode>"
18738 [(set (match_operand:SWI48 0 "register_operand" "=r")
18739 (ior:SWI48
18740 (plus:SWI48
18741 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18742 (const_int 1))
18743 (match_dup 1)))
18744 (clobber (reg:CC FLAGS_REG))]
18745 "TARGET_TBM"
18746 "blcs\t{%1, %0|%0, %1}"
18747 [(set_attr "type" "bitmanip")
18748 (set_attr "mode" "<MODE>")])
18749
18750 (define_insn "*tbm_blsfill_<mode>"
18751 [(set (match_operand:SWI48 0 "register_operand" "=r")
18752 (ior:SWI48
18753 (plus:SWI48
18754 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18755 (const_int -1))
18756 (match_dup 1)))
18757 (clobber (reg:CC FLAGS_REG))]
18758 "TARGET_TBM"
18759 "blsfill\t{%1, %0|%0, %1}"
18760 [(set_attr "type" "bitmanip")
18761 (set_attr "mode" "<MODE>")])
18762
18763 (define_insn "*tbm_blsic_<mode>"
18764 [(set (match_operand:SWI48 0 "register_operand" "=r")
18765 (ior:SWI48
18766 (plus:SWI48
18767 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18768 (const_int -1))
18769 (not:SWI48
18770 (match_dup 1))))
18771 (clobber (reg:CC FLAGS_REG))]
18772 "TARGET_TBM"
18773 "blsic\t{%1, %0|%0, %1}"
18774 [(set_attr "type" "bitmanip")
18775 (set_attr "mode" "<MODE>")])
18776
18777 (define_insn "*tbm_t1mskc_<mode>"
18778 [(set (match_operand:SWI48 0 "register_operand" "=r")
18779 (ior:SWI48
18780 (plus:SWI48
18781 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18782 (const_int 1))
18783 (not:SWI48
18784 (match_dup 1))))
18785 (clobber (reg:CC FLAGS_REG))]
18786 "TARGET_TBM"
18787 "t1mskc\t{%1, %0|%0, %1}"
18788 [(set_attr "type" "bitmanip")
18789 (set_attr "mode" "<MODE>")])
18790
18791 (define_insn "*tbm_tzmsk_<mode>"
18792 [(set (match_operand:SWI48 0 "register_operand" "=r")
18793 (and:SWI48
18794 (plus:SWI48
18795 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18796 (const_int -1))
18797 (not:SWI48
18798 (match_dup 1))))
18799 (clobber (reg:CC FLAGS_REG))]
18800 "TARGET_TBM"
18801 "tzmsk\t{%1, %0|%0, %1}"
18802 [(set_attr "type" "bitmanip")
18803 (set_attr "mode" "<MODE>")])
18804
18805 (define_insn_and_split "popcount<mode>2"
18806 [(set (match_operand:SWI48 0 "register_operand" "=r")
18807 (popcount:SWI48
18808 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18809 (clobber (reg:CC FLAGS_REG))]
18810 "TARGET_POPCNT"
18811 {
18812 #if TARGET_MACHO
18813 return "popcnt\t{%1, %0|%0, %1}";
18814 #else
18815 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18816 #endif
18817 }
18818 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18819 && optimize_function_for_speed_p (cfun)
18820 && !reg_mentioned_p (operands[0], operands[1])"
18821 [(parallel
18822 [(set (match_dup 0)
18823 (popcount:SWI48 (match_dup 1)))
18824 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18825 (clobber (reg:CC FLAGS_REG))])]
18826 "ix86_expand_clear (operands[0]);"
18827 [(set_attr "prefix_rep" "1")
18828 (set_attr "type" "bitmanip")
18829 (set_attr "mode" "<MODE>")])
18830
18831 ; False dependency happens when destination is only updated by tzcnt,
18832 ; lzcnt or popcnt. There is no false dependency when destination is
18833 ; also used in source.
18834 (define_insn "*popcount<mode>2_falsedep"
18835 [(set (match_operand:SWI48 0 "register_operand" "=r")
18836 (popcount:SWI48
18837 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18838 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18839 UNSPEC_INSN_FALSE_DEP)
18840 (clobber (reg:CC FLAGS_REG))]
18841 "TARGET_POPCNT"
18842 {
18843 #if TARGET_MACHO
18844 return "popcnt\t{%1, %0|%0, %1}";
18845 #else
18846 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18847 #endif
18848 }
18849 [(set_attr "prefix_rep" "1")
18850 (set_attr "type" "bitmanip")
18851 (set_attr "mode" "<MODE>")])
18852
18853 (define_insn_and_split "*popcountsi2_zext"
18854 [(set (match_operand:DI 0 "register_operand" "=r")
18855 (and:DI
18856 (subreg:DI
18857 (popcount:SI
18858 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18859 (const_int 63)))
18860 (clobber (reg:CC FLAGS_REG))]
18861 "TARGET_POPCNT && TARGET_64BIT"
18862 {
18863 #if TARGET_MACHO
18864 return "popcnt\t{%1, %k0|%k0, %1}";
18865 #else
18866 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18867 #endif
18868 }
18869 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18870 && optimize_function_for_speed_p (cfun)
18871 && !reg_mentioned_p (operands[0], operands[1])"
18872 [(parallel
18873 [(set (match_dup 0)
18874 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
18875 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18876 (clobber (reg:CC FLAGS_REG))])]
18877 "ix86_expand_clear (operands[0]);"
18878 [(set_attr "prefix_rep" "1")
18879 (set_attr "type" "bitmanip")
18880 (set_attr "mode" "SI")])
18881
18882 ; False dependency happens when destination is only updated by tzcnt,
18883 ; lzcnt or popcnt. There is no false dependency when destination is
18884 ; also used in source.
18885 (define_insn "*popcountsi2_zext_falsedep"
18886 [(set (match_operand:DI 0 "register_operand" "=r")
18887 (and:DI
18888 (subreg:DI
18889 (popcount:SI
18890 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18891 (const_int 63)))
18892 (unspec [(match_operand:DI 2 "register_operand" "0")]
18893 UNSPEC_INSN_FALSE_DEP)
18894 (clobber (reg:CC FLAGS_REG))]
18895 "TARGET_POPCNT && TARGET_64BIT"
18896 {
18897 #if TARGET_MACHO
18898 return "popcnt\t{%1, %k0|%k0, %1}";
18899 #else
18900 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18901 #endif
18902 }
18903 [(set_attr "prefix_rep" "1")
18904 (set_attr "type" "bitmanip")
18905 (set_attr "mode" "SI")])
18906
18907 (define_insn_and_split "*popcountsi2_zext_2"
18908 [(set (match_operand:DI 0 "register_operand" "=r")
18909 (zero_extend:DI
18910 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18911 (clobber (reg:CC FLAGS_REG))]
18912 "TARGET_POPCNT && TARGET_64BIT"
18913 {
18914 #if TARGET_MACHO
18915 return "popcnt\t{%1, %k0|%k0, %1}";
18916 #else
18917 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18918 #endif
18919 }
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 (zero_extend:DI (popcount:SI (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" "SI")])
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 "*popcountsi2_zext_2_falsedep"
18937 [(set (match_operand:DI 0 "register_operand" "=r")
18938 (zero_extend:DI
18939 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18940 (unspec [(match_operand:DI 2 "register_operand" "0")]
18941 UNSPEC_INSN_FALSE_DEP)
18942 (clobber (reg:CC FLAGS_REG))]
18943 "TARGET_POPCNT && TARGET_64BIT"
18944 {
18945 #if TARGET_MACHO
18946 return "popcnt\t{%1, %k0|%k0, %1}";
18947 #else
18948 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18949 #endif
18950 }
18951 [(set_attr "prefix_rep" "1")
18952 (set_attr "type" "bitmanip")
18953 (set_attr "mode" "SI")])
18954
18955 (define_insn_and_split "*popcounthi2_1"
18956 [(set (match_operand:SI 0 "register_operand")
18957 (popcount:SI
18958 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
18959 (clobber (reg:CC FLAGS_REG))]
18960 "TARGET_POPCNT
18961 && ix86_pre_reload_split ()"
18962 "#"
18963 "&& 1"
18964 [(const_int 0)]
18965 {
18966 rtx tmp = gen_reg_rtx (HImode);
18967
18968 emit_insn (gen_popcounthi2 (tmp, operands[1]));
18969 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
18970 DONE;
18971 })
18972
18973 (define_insn_and_split "*popcounthi2_2"
18974 [(set (match_operand:SI 0 "register_operand")
18975 (zero_extend:SI
18976 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
18977 (clobber (reg:CC FLAGS_REG))]
18978 "TARGET_POPCNT
18979 && ix86_pre_reload_split ()"
18980 "#"
18981 "&& 1"
18982 [(const_int 0)]
18983 {
18984 rtx tmp = gen_reg_rtx (HImode);
18985
18986 emit_insn (gen_popcounthi2 (tmp, operands[1]));
18987 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
18988 DONE;
18989 })
18990
18991 (define_insn "popcounthi2"
18992 [(set (match_operand:HI 0 "register_operand" "=r")
18993 (popcount:HI
18994 (match_operand:HI 1 "nonimmediate_operand" "rm")))
18995 (clobber (reg:CC FLAGS_REG))]
18996 "TARGET_POPCNT"
18997 {
18998 #if TARGET_MACHO
18999 return "popcnt\t{%1, %0|%0, %1}";
19000 #else
19001 return "popcnt{w}\t{%1, %0|%0, %1}";
19002 #endif
19003 }
19004 [(set_attr "prefix_rep" "1")
19005 (set_attr "type" "bitmanip")
19006 (set_attr "mode" "HI")])
19007
19008 (define_expand "bswapdi2"
19009 [(set (match_operand:DI 0 "register_operand")
19010 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19011 "TARGET_64BIT"
19012 {
19013 if (!TARGET_MOVBE)
19014 operands[1] = force_reg (DImode, operands[1]);
19015 })
19016
19017 (define_expand "bswapsi2"
19018 [(set (match_operand:SI 0 "register_operand")
19019 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19020 ""
19021 {
19022 if (TARGET_MOVBE)
19023 ;
19024 else if (TARGET_BSWAP)
19025 operands[1] = force_reg (SImode, operands[1]);
19026 else
19027 {
19028 rtx x = operands[0];
19029
19030 emit_move_insn (x, operands[1]);
19031 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19032 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19033 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19034 DONE;
19035 }
19036 })
19037
19038 (define_insn "*bswap<mode>2_movbe"
19039 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19040 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19041 "TARGET_MOVBE
19042 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19043 "@
19044 bswap\t%0
19045 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19046 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19047 [(set_attr "type" "bitmanip,imov,imov")
19048 (set_attr "modrm" "0,1,1")
19049 (set_attr "prefix_0f" "*,1,1")
19050 (set_attr "prefix_extra" "*,1,1")
19051 (set_attr "mode" "<MODE>")])
19052
19053 (define_insn "*bswap<mode>2"
19054 [(set (match_operand:SWI48 0 "register_operand" "=r")
19055 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19056 "TARGET_BSWAP"
19057 "bswap\t%0"
19058 [(set_attr "type" "bitmanip")
19059 (set_attr "modrm" "0")
19060 (set_attr "mode" "<MODE>")])
19061
19062 (define_expand "bswaphi2"
19063 [(set (match_operand:HI 0 "register_operand")
19064 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19065 "TARGET_MOVBE")
19066
19067 (define_insn "*bswaphi2_movbe"
19068 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19069 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19070 "TARGET_MOVBE
19071 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19072 "@
19073 xchg{b}\t{%h0, %b0|%b0, %h0}
19074 movbe{w}\t{%1, %0|%0, %1}
19075 movbe{w}\t{%1, %0|%0, %1}"
19076 [(set_attr "type" "imov")
19077 (set_attr "modrm" "*,1,1")
19078 (set_attr "prefix_0f" "*,1,1")
19079 (set_attr "prefix_extra" "*,1,1")
19080 (set_attr "pent_pair" "np,*,*")
19081 (set_attr "athlon_decode" "vector,*,*")
19082 (set_attr "amdfam10_decode" "double,*,*")
19083 (set_attr "bdver1_decode" "double,*,*")
19084 (set_attr "mode" "QI,HI,HI")])
19085
19086 (define_peephole2
19087 [(set (match_operand:HI 0 "general_reg_operand")
19088 (bswap:HI (match_dup 0)))]
19089 "TARGET_MOVBE
19090 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19091 && peep2_regno_dead_p (0, FLAGS_REG)"
19092 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19093 (clobber (reg:CC FLAGS_REG))])])
19094
19095 (define_insn "bswaphi_lowpart"
19096 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19097 (bswap:HI (match_dup 0)))
19098 (clobber (reg:CC FLAGS_REG))]
19099 ""
19100 "@
19101 xchg{b}\t{%h0, %b0|%b0, %h0}
19102 rol{w}\t{$8, %0|%0, 8}"
19103 [(set (attr "preferred_for_size")
19104 (cond [(eq_attr "alternative" "0")
19105 (symbol_ref "true")]
19106 (symbol_ref "false")))
19107 (set (attr "preferred_for_speed")
19108 (cond [(eq_attr "alternative" "0")
19109 (symbol_ref "TARGET_USE_XCHGB")]
19110 (symbol_ref "!TARGET_USE_XCHGB")))
19111 (set_attr "length" "2,4")
19112 (set_attr "mode" "QI,HI")])
19113
19114 (define_expand "paritydi2"
19115 [(set (match_operand:DI 0 "register_operand")
19116 (parity:DI (match_operand:DI 1 "register_operand")))]
19117 "! TARGET_POPCNT"
19118 {
19119 rtx scratch = gen_reg_rtx (QImode);
19120 rtx hipart1 = gen_reg_rtx (SImode);
19121 rtx lopart1 = gen_reg_rtx (SImode);
19122 rtx xor1 = gen_reg_rtx (SImode);
19123 rtx shift2 = gen_reg_rtx (SImode);
19124 rtx hipart2 = gen_reg_rtx (HImode);
19125 rtx lopart2 = gen_reg_rtx (HImode);
19126 rtx xor2 = gen_reg_rtx (HImode);
19127
19128 if (TARGET_64BIT)
19129 {
19130 rtx shift1 = gen_reg_rtx (DImode);
19131 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19132 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19133 }
19134 else
19135 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19136
19137 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19138 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19139
19140 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19141 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19142 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19143 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19144
19145 emit_insn (gen_parityhi2_cmp (xor2));
19146
19147 ix86_expand_setcc (scratch, ORDERED,
19148 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19149
19150 if (TARGET_64BIT)
19151 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19152 else
19153 {
19154 rtx tmp = gen_reg_rtx (SImode);
19155
19156 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19157 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19158 }
19159 DONE;
19160 })
19161
19162 (define_expand "paritysi2"
19163 [(set (match_operand:SI 0 "register_operand")
19164 (parity:SI (match_operand:SI 1 "register_operand")))]
19165 "! TARGET_POPCNT"
19166 {
19167 rtx scratch = gen_reg_rtx (QImode);
19168 rtx shift = gen_reg_rtx (SImode);
19169 rtx hipart = gen_reg_rtx (HImode);
19170 rtx lopart = gen_reg_rtx (HImode);
19171 rtx tmp = gen_reg_rtx (HImode);
19172
19173 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19174 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19175 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19176 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19177
19178 emit_insn (gen_parityhi2_cmp (tmp));
19179
19180 ix86_expand_setcc (scratch, ORDERED,
19181 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19182
19183 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19184 DONE;
19185 })
19186
19187 (define_expand "parityhi2"
19188 [(set (match_operand:HI 0 "register_operand")
19189 (parity:HI (match_operand:HI 1 "register_operand")))]
19190 "! TARGET_POPCNT"
19191 {
19192 rtx scratch = gen_reg_rtx (QImode);
19193
19194 emit_insn (gen_parityhi2_cmp (operands[1]));
19195
19196 ix86_expand_setcc (scratch, ORDERED,
19197 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19198
19199 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19200 DONE;
19201 })
19202
19203 (define_expand "parityqi2"
19204 [(set (match_operand:QI 0 "register_operand")
19205 (parity:QI (match_operand:QI 1 "register_operand")))]
19206 "! TARGET_POPCNT"
19207 {
19208 emit_insn (gen_parityqi2_cmp (operands[1]));
19209
19210 ix86_expand_setcc (operands[0], ORDERED,
19211 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19212 DONE;
19213 })
19214
19215 (define_insn "parityhi2_cmp"
19216 [(set (reg:CC FLAGS_REG)
19217 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19218 UNSPEC_PARITY))
19219 (clobber (match_dup 0))]
19220 ""
19221 "xor{b}\t{%h0, %b0|%b0, %h0}"
19222 [(set_attr "length" "2")
19223 (set_attr "mode" "QI")])
19224
19225 (define_insn "parityqi2_cmp"
19226 [(set (reg:CC FLAGS_REG)
19227 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19228 UNSPEC_PARITY))]
19229 ""
19230 "test{b}\t%0, %0"
19231 [(set_attr "mode" "QI")])
19232
19233 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19234 (define_peephole2
19235 [(set (match_operand:HI 0 "register_operand")
19236 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19237 (parallel [(set (reg:CC FLAGS_REG)
19238 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19239 (clobber (match_dup 0))])]
19240 ""
19241 [(set (reg:CC FLAGS_REG)
19242 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19243
19244 ;; Eliminate QImode popcount&1 using parity flag
19245 (define_peephole2
19246 [(set (match_operand:SI 0 "register_operand")
19247 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19248 (parallel [(set (match_operand:SI 2 "register_operand")
19249 (popcount:SI (match_dup 0)))
19250 (clobber (reg:CC FLAGS_REG))])
19251 (set (reg:CCZ FLAGS_REG)
19252 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19253 (const_int 1))
19254 (const_int 0)))
19255 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19256 [(reg:CCZ FLAGS_REG)
19257 (const_int 0)])
19258 (label_ref (match_operand 5))
19259 (pc)))]
19260 "REGNO (operands[2]) == REGNO (operands[3])
19261 && peep2_reg_dead_p (3, operands[0])
19262 && peep2_reg_dead_p (3, operands[2])
19263 && peep2_regno_dead_p (4, FLAGS_REG)"
19264 [(set (reg:CC FLAGS_REG)
19265 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19266 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19267 (const_int 0)])
19268 (label_ref (match_dup 5))
19269 (pc)))]
19270 {
19271 operands[4] = shallow_copy_rtx (operands[4]);
19272 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19273 })
19274
19275 ;; Eliminate HImode popcount&1 using parity flag
19276 (define_peephole2
19277 [(match_scratch:HI 0 "Q")
19278 (parallel [(set (match_operand:HI 1 "register_operand")
19279 (popcount:HI
19280 (match_operand:HI 2 "nonimmediate_operand")))
19281 (clobber (reg:CC FLAGS_REG))])
19282 (set (match_operand 3 "register_operand")
19283 (zero_extend (match_dup 1)))
19284 (set (reg:CCZ FLAGS_REG)
19285 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19286 (const_int 1))
19287 (const_int 0)))
19288 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19289 [(reg:CCZ FLAGS_REG)
19290 (const_int 0)])
19291 (label_ref (match_operand 6))
19292 (pc)))]
19293 "REGNO (operands[3]) == REGNO (operands[4])
19294 && peep2_reg_dead_p (3, operands[1])
19295 && peep2_reg_dead_p (3, operands[3])
19296 && peep2_regno_dead_p (4, FLAGS_REG)"
19297 [(set (match_dup 0) (match_dup 2))
19298 (parallel [(set (reg:CC FLAGS_REG)
19299 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19300 (clobber (match_dup 0))])
19301 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19302 (const_int 0)])
19303 (label_ref (match_dup 6))
19304 (pc)))]
19305 {
19306 operands[5] = shallow_copy_rtx (operands[5]);
19307 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19308 })
19309
19310 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19311 (define_peephole2
19312 [(match_scratch:HI 0 "Q")
19313 (parallel [(set (match_operand:HI 1 "register_operand")
19314 (popcount:HI
19315 (match_operand:HI 2 "nonimmediate_operand")))
19316 (clobber (reg:CC FLAGS_REG))])
19317 (set (reg:CCZ FLAGS_REG)
19318 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19319 (const_int 1))
19320 (const_int 0)))
19321 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19322 [(reg:CCZ FLAGS_REG)
19323 (const_int 0)])
19324 (label_ref (match_operand 5))
19325 (pc)))]
19326 "REGNO (operands[1]) == REGNO (operands[3])
19327 && peep2_reg_dead_p (2, operands[1])
19328 && peep2_reg_dead_p (2, operands[3])
19329 && peep2_regno_dead_p (3, FLAGS_REG)"
19330 [(set (match_dup 0) (match_dup 2))
19331 (parallel [(set (reg:CC FLAGS_REG)
19332 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19333 (clobber (match_dup 0))])
19334 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19335 (const_int 0)])
19336 (label_ref (match_dup 5))
19337 (pc)))]
19338 {
19339 operands[4] = shallow_copy_rtx (operands[4]);
19340 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19341 })
19342
19343 \f
19344 ;; Thread-local storage patterns for ELF.
19345 ;;
19346 ;; Note that these code sequences must appear exactly as shown
19347 ;; in order to allow linker relaxation.
19348
19349 (define_insn "*tls_global_dynamic_32_gnu"
19350 [(set (match_operand:SI 0 "register_operand" "=a")
19351 (unspec:SI
19352 [(match_operand:SI 1 "register_operand" "Yb")
19353 (match_operand 2 "tls_symbolic_operand")
19354 (match_operand 3 "constant_call_address_operand" "Bz")
19355 (reg:SI SP_REG)]
19356 UNSPEC_TLS_GD))
19357 (clobber (match_scratch:SI 4 "=d"))
19358 (clobber (match_scratch:SI 5 "=c"))
19359 (clobber (reg:CC FLAGS_REG))]
19360 "!TARGET_64BIT && TARGET_GNU_TLS"
19361 {
19362 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19363 output_asm_insn
19364 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19365 else
19366 output_asm_insn
19367 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19368 if (TARGET_SUN_TLS)
19369 #ifdef HAVE_AS_IX86_TLSGDPLT
19370 return "call\t%a2@tlsgdplt";
19371 #else
19372 return "call\t%p3@plt";
19373 #endif
19374 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19375 return "call\t%P3";
19376 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19377 }
19378 [(set_attr "type" "multi")
19379 (set_attr "length" "12")])
19380
19381 (define_expand "tls_global_dynamic_32"
19382 [(parallel
19383 [(set (match_operand:SI 0 "register_operand")
19384 (unspec:SI [(match_operand:SI 2 "register_operand")
19385 (match_operand 1 "tls_symbolic_operand")
19386 (match_operand 3 "constant_call_address_operand")
19387 (reg:SI SP_REG)]
19388 UNSPEC_TLS_GD))
19389 (clobber (scratch:SI))
19390 (clobber (scratch:SI))
19391 (clobber (reg:CC FLAGS_REG))])]
19392 ""
19393 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19394
19395 (define_insn "*tls_global_dynamic_64_<mode>"
19396 [(set (match_operand:P 0 "register_operand" "=a")
19397 (call:P
19398 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19399 (match_operand 3)))
19400 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19401 (reg:P SP_REG)]
19402 UNSPEC_TLS_GD)]
19403 "TARGET_64BIT"
19404 {
19405 if (!TARGET_X32)
19406 /* The .loc directive has effect for 'the immediately following assembly
19407 instruction'. So for a sequence:
19408 .loc f l
19409 .byte x
19410 insn1
19411 the 'immediately following assembly instruction' is insn1.
19412 We want to emit an insn prefix here, but if we use .byte (as shown in
19413 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19414 inside the insn sequence, rather than to the start. After relaxation
19415 of the sequence by the linker, the .loc might point inside an insn.
19416 Use data16 prefix instead, which doesn't have this problem. */
19417 fputs ("\tdata16", asm_out_file);
19418 output_asm_insn
19419 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19420 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19421 fputs (ASM_SHORT "0x6666\n", asm_out_file);
19422 else
19423 fputs (ASM_BYTE "0x66\n", asm_out_file);
19424 fputs ("\trex64\n", asm_out_file);
19425 if (TARGET_SUN_TLS)
19426 return "call\t%p2@plt";
19427 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19428 return "call\t%P2";
19429 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
19430 }
19431 [(set_attr "type" "multi")
19432 (set (attr "length")
19433 (symbol_ref "TARGET_X32 ? 15 : 16"))])
19434
19435 (define_insn "*tls_global_dynamic_64_largepic"
19436 [(set (match_operand:DI 0 "register_operand" "=a")
19437 (call:DI
19438 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
19439 (match_operand:DI 3 "immediate_operand" "i")))
19440 (match_operand 4)))
19441 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
19442 (reg:DI SP_REG)]
19443 UNSPEC_TLS_GD)]
19444 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19445 && GET_CODE (operands[3]) == CONST
19446 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
19447 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
19448 {
19449 output_asm_insn
19450 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19451 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
19452 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
19453 return "call\t{*%%rax|rax}";
19454 }
19455 [(set_attr "type" "multi")
19456 (set_attr "length" "22")])
19457
19458 (define_expand "@tls_global_dynamic_64_<mode>"
19459 [(parallel
19460 [(set (match_operand:P 0 "register_operand")
19461 (call:P
19462 (mem:QI (match_operand 2))
19463 (const_int 0)))
19464 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19465 (reg:P SP_REG)]
19466 UNSPEC_TLS_GD)])]
19467 "TARGET_64BIT"
19468 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19469
19470 (define_insn "*tls_local_dynamic_base_32_gnu"
19471 [(set (match_operand:SI 0 "register_operand" "=a")
19472 (unspec:SI
19473 [(match_operand:SI 1 "register_operand" "Yb")
19474 (match_operand 2 "constant_call_address_operand" "Bz")
19475 (reg:SI SP_REG)]
19476 UNSPEC_TLS_LD_BASE))
19477 (clobber (match_scratch:SI 3 "=d"))
19478 (clobber (match_scratch:SI 4 "=c"))
19479 (clobber (reg:CC FLAGS_REG))]
19480 "!TARGET_64BIT && TARGET_GNU_TLS"
19481 {
19482 output_asm_insn
19483 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
19484 if (TARGET_SUN_TLS)
19485 {
19486 if (HAVE_AS_IX86_TLSLDMPLT)
19487 return "call\t%&@tlsldmplt";
19488 else
19489 return "call\t%p2@plt";
19490 }
19491 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19492 return "call\t%P2";
19493 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
19494 }
19495 [(set_attr "type" "multi")
19496 (set_attr "length" "11")])
19497
19498 (define_expand "tls_local_dynamic_base_32"
19499 [(parallel
19500 [(set (match_operand:SI 0 "register_operand")
19501 (unspec:SI
19502 [(match_operand:SI 1 "register_operand")
19503 (match_operand 2 "constant_call_address_operand")
19504 (reg:SI SP_REG)]
19505 UNSPEC_TLS_LD_BASE))
19506 (clobber (scratch:SI))
19507 (clobber (scratch:SI))
19508 (clobber (reg:CC FLAGS_REG))])]
19509 ""
19510 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19511
19512 (define_insn "*tls_local_dynamic_base_64_<mode>"
19513 [(set (match_operand:P 0 "register_operand" "=a")
19514 (call:P
19515 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
19516 (match_operand 2)))
19517 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
19518 "TARGET_64BIT"
19519 {
19520 output_asm_insn
19521 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19522 if (TARGET_SUN_TLS)
19523 return "call\t%p1@plt";
19524 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19525 return "call\t%P1";
19526 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
19527 }
19528 [(set_attr "type" "multi")
19529 (set_attr "length" "12")])
19530
19531 (define_insn "*tls_local_dynamic_base_64_largepic"
19532 [(set (match_operand:DI 0 "register_operand" "=a")
19533 (call:DI
19534 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
19535 (match_operand:DI 2 "immediate_operand" "i")))
19536 (match_operand 3)))
19537 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
19538 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19539 && GET_CODE (operands[2]) == CONST
19540 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
19541 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
19542 {
19543 output_asm_insn
19544 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19545 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
19546 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
19547 return "call\t{*%%rax|rax}";
19548 }
19549 [(set_attr "type" "multi")
19550 (set_attr "length" "22")])
19551
19552 (define_expand "@tls_local_dynamic_base_64_<mode>"
19553 [(parallel
19554 [(set (match_operand:P 0 "register_operand")
19555 (call:P
19556 (mem:QI (match_operand 1))
19557 (const_int 0)))
19558 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
19559 "TARGET_64BIT"
19560 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19561
19562 ;; Local dynamic of a single variable is a lose. Show combine how
19563 ;; to convert that back to global dynamic.
19564
19565 (define_insn_and_split "*tls_local_dynamic_32_once"
19566 [(set (match_operand:SI 0 "register_operand" "=a")
19567 (plus:SI
19568 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
19569 (match_operand 2 "constant_call_address_operand" "Bz")
19570 (reg:SI SP_REG)]
19571 UNSPEC_TLS_LD_BASE)
19572 (const:SI (unspec:SI
19573 [(match_operand 3 "tls_symbolic_operand")]
19574 UNSPEC_DTPOFF))))
19575 (clobber (match_scratch:SI 4 "=d"))
19576 (clobber (match_scratch:SI 5 "=c"))
19577 (clobber (reg:CC FLAGS_REG))]
19578 ""
19579 "#"
19580 ""
19581 [(parallel
19582 [(set (match_dup 0)
19583 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
19584 (reg:SI SP_REG)]
19585 UNSPEC_TLS_GD))
19586 (clobber (match_dup 4))
19587 (clobber (match_dup 5))
19588 (clobber (reg:CC FLAGS_REG))])])
19589
19590 ;; Load and add the thread base pointer from %<tp_seg>:0.
19591 (define_expand "get_thread_pointer<mode>"
19592 [(set (match_operand:PTR 0 "register_operand")
19593 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19594 ""
19595 {
19596 /* targetm is not visible in the scope of the condition. */
19597 if (!targetm.have_tls)
19598 error ("%<__builtin_thread_pointer%> is not supported on this target");
19599 })
19600
19601 (define_insn_and_split "*load_tp_<mode>"
19602 [(set (match_operand:PTR 0 "register_operand" "=r")
19603 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19604 ""
19605 "#"
19606 ""
19607 [(set (match_dup 0)
19608 (match_dup 1))]
19609 {
19610 addr_space_t as = DEFAULT_TLS_SEG_REG;
19611
19612 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
19613 set_mem_addr_space (operands[1], as);
19614 })
19615
19616 (define_insn_and_split "*load_tp_x32_zext"
19617 [(set (match_operand:DI 0 "register_operand" "=r")
19618 (zero_extend:DI
19619 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
19620 "TARGET_X32"
19621 "#"
19622 "&& 1"
19623 [(set (match_dup 0)
19624 (zero_extend:DI (match_dup 1)))]
19625 {
19626 addr_space_t as = DEFAULT_TLS_SEG_REG;
19627
19628 operands[1] = gen_const_mem (SImode, const0_rtx);
19629 set_mem_addr_space (operands[1], as);
19630 })
19631
19632 (define_insn_and_split "*add_tp_<mode>"
19633 [(set (match_operand:PTR 0 "register_operand" "=r")
19634 (plus:PTR
19635 (unspec:PTR [(const_int 0)] UNSPEC_TP)
19636 (match_operand:PTR 1 "register_operand" "0")))
19637 (clobber (reg:CC FLAGS_REG))]
19638 ""
19639 "#"
19640 ""
19641 [(parallel
19642 [(set (match_dup 0)
19643 (plus:PTR (match_dup 1) (match_dup 2)))
19644 (clobber (reg:CC FLAGS_REG))])]
19645 {
19646 addr_space_t as = DEFAULT_TLS_SEG_REG;
19647
19648 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
19649 set_mem_addr_space (operands[2], as);
19650 })
19651
19652 (define_insn_and_split "*add_tp_x32_zext"
19653 [(set (match_operand:DI 0 "register_operand" "=r")
19654 (zero_extend:DI
19655 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
19656 (match_operand:SI 1 "register_operand" "0"))))
19657 (clobber (reg:CC FLAGS_REG))]
19658 "TARGET_X32"
19659 "#"
19660 "&& 1"
19661 [(parallel
19662 [(set (match_dup 0)
19663 (zero_extend:DI
19664 (plus:SI (match_dup 1) (match_dup 2))))
19665 (clobber (reg:CC FLAGS_REG))])]
19666 {
19667 addr_space_t as = DEFAULT_TLS_SEG_REG;
19668
19669 operands[2] = gen_const_mem (SImode, const0_rtx);
19670 set_mem_addr_space (operands[2], as);
19671 })
19672
19673 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
19674 ;; %rax as destination of the initial executable code sequence.
19675 (define_insn "tls_initial_exec_64_sun"
19676 [(set (match_operand:DI 0 "register_operand" "=a")
19677 (unspec:DI
19678 [(match_operand 1 "tls_symbolic_operand")]
19679 UNSPEC_TLS_IE_SUN))
19680 (clobber (reg:CC FLAGS_REG))]
19681 "TARGET_64BIT && TARGET_SUN_TLS"
19682 {
19683 output_asm_insn
19684 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
19685 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
19686 }
19687 [(set_attr "type" "multi")])
19688
19689 ;; GNU2 TLS patterns can be split.
19690
19691 (define_expand "tls_dynamic_gnu2_32"
19692 [(set (match_dup 3)
19693 (plus:SI (match_operand:SI 2 "register_operand")
19694 (const:SI
19695 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
19696 UNSPEC_TLSDESC))))
19697 (parallel
19698 [(set (match_operand:SI 0 "register_operand")
19699 (unspec:SI [(match_dup 1) (match_dup 3)
19700 (match_dup 2) (reg:SI SP_REG)]
19701 UNSPEC_TLSDESC))
19702 (clobber (reg:CC FLAGS_REG))])]
19703 "!TARGET_64BIT && TARGET_GNU2_TLS"
19704 {
19705 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
19706 ix86_tls_descriptor_calls_expanded_in_cfun = true;
19707 })
19708
19709 (define_insn "*tls_dynamic_gnu2_lea_32"
19710 [(set (match_operand:SI 0 "register_operand" "=r")
19711 (plus:SI (match_operand:SI 1 "register_operand" "b")
19712 (const:SI
19713 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
19714 UNSPEC_TLSDESC))))]
19715 "!TARGET_64BIT && TARGET_GNU2_TLS"
19716 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
19717 [(set_attr "type" "lea")
19718 (set_attr "mode" "SI")
19719 (set_attr "length" "6")
19720 (set_attr "length_address" "4")])
19721
19722 (define_insn "*tls_dynamic_gnu2_call_32"
19723 [(set (match_operand:SI 0 "register_operand" "=a")
19724 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
19725 (match_operand:SI 2 "register_operand" "0")
19726 ;; we have to make sure %ebx still points to the GOT
19727 (match_operand:SI 3 "register_operand" "b")
19728 (reg:SI SP_REG)]
19729 UNSPEC_TLSDESC))
19730 (clobber (reg:CC FLAGS_REG))]
19731 "!TARGET_64BIT && TARGET_GNU2_TLS"
19732 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
19733 [(set_attr "type" "call")
19734 (set_attr "length" "2")
19735 (set_attr "length_address" "0")])
19736
19737 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
19738 [(set (match_operand:SI 0 "register_operand" "=&a")
19739 (plus:SI
19740 (unspec:SI [(match_operand 3 "tls_modbase_operand")
19741 (match_operand:SI 4)
19742 (match_operand:SI 2 "register_operand" "b")
19743 (reg:SI SP_REG)]
19744 UNSPEC_TLSDESC)
19745 (const:SI (unspec:SI
19746 [(match_operand 1 "tls_symbolic_operand")]
19747 UNSPEC_DTPOFF))))
19748 (clobber (reg:CC FLAGS_REG))]
19749 "!TARGET_64BIT && TARGET_GNU2_TLS"
19750 "#"
19751 "&& 1"
19752 [(set (match_dup 0) (match_dup 5))]
19753 {
19754 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
19755 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
19756 })
19757
19758 (define_expand "@tls_dynamic_gnu2_64_<mode>"
19759 [(set (match_dup 2)
19760 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
19761 UNSPEC_TLSDESC))
19762 (parallel
19763 [(set (match_operand:PTR 0 "register_operand")
19764 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
19765 UNSPEC_TLSDESC))
19766 (clobber (reg:CC FLAGS_REG))])]
19767 "TARGET_64BIT && TARGET_GNU2_TLS"
19768 {
19769 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
19770 ix86_tls_descriptor_calls_expanded_in_cfun = true;
19771 })
19772
19773 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
19774 [(set (match_operand:PTR 0 "register_operand" "=r")
19775 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
19776 UNSPEC_TLSDESC))]
19777 "TARGET_64BIT && TARGET_GNU2_TLS"
19778 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
19779 [(set_attr "type" "lea")
19780 (set_attr "mode" "<MODE>")
19781 (set_attr "length" "7")
19782 (set_attr "length_address" "4")])
19783
19784 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
19785 [(set (match_operand:PTR 0 "register_operand" "=a")
19786 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
19787 (match_operand:PTR 2 "register_operand" "0")
19788 (reg:PTR SP_REG)]
19789 UNSPEC_TLSDESC))
19790 (clobber (reg:CC FLAGS_REG))]
19791 "TARGET_64BIT && TARGET_GNU2_TLS"
19792 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
19793 [(set_attr "type" "call")
19794 (set_attr "length" "2")
19795 (set_attr "length_address" "0")])
19796
19797 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
19798 [(set (match_operand:PTR 0 "register_operand" "=&a")
19799 (plus:PTR
19800 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
19801 (match_operand:PTR 3)
19802 (reg:PTR SP_REG)]
19803 UNSPEC_TLSDESC)
19804 (const:PTR (unspec:PTR
19805 [(match_operand 1 "tls_symbolic_operand")]
19806 UNSPEC_DTPOFF))))
19807 (clobber (reg:CC FLAGS_REG))]
19808 "TARGET_64BIT && TARGET_GNU2_TLS"
19809 "#"
19810 "&& 1"
19811 [(set (match_dup 0) (match_dup 4))]
19812 {
19813 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
19814 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
19815 })
19816
19817 (define_split
19818 [(match_operand 0 "tls_address_pattern")]
19819 "TARGET_TLS_DIRECT_SEG_REFS"
19820 [(match_dup 0)]
19821 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
19822
19823 \f
19824 ;; These patterns match the binary 387 instructions for addM3, subM3,
19825 ;; mulM3 and divM3. There are three patterns for each of DFmode and
19826 ;; SFmode. The first is the normal insn, the second the same insn but
19827 ;; with one operand a conversion, and the third the same insn but with
19828 ;; the other operand a conversion. The conversion may be SFmode or
19829 ;; SImode if the target mode DFmode, but only SImode if the target mode
19830 ;; is SFmode.
19831
19832 ;; Gcc is slightly more smart about handling normal two address instructions
19833 ;; so use special patterns for add and mull.
19834
19835 (define_insn "*fop_xf_comm_i387"
19836 [(set (match_operand:XF 0 "register_operand" "=f")
19837 (match_operator:XF 3 "binary_fp_operator"
19838 [(match_operand:XF 1 "register_operand" "%0")
19839 (match_operand:XF 2 "register_operand" "f")]))]
19840 "TARGET_80387
19841 && COMMUTATIVE_ARITH_P (operands[3])"
19842 "* return output_387_binary_op (insn, operands);"
19843 [(set (attr "type")
19844 (if_then_else (match_operand:XF 3 "mult_operator")
19845 (const_string "fmul")
19846 (const_string "fop")))
19847 (set_attr "mode" "XF")])
19848
19849 (define_insn "*fop_<mode>_comm"
19850 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
19851 (match_operator:MODEF 3 "binary_fp_operator"
19852 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
19853 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
19854 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19855 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
19856 && COMMUTATIVE_ARITH_P (operands[3])
19857 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
19858 "* return output_387_binary_op (insn, operands);"
19859 [(set (attr "type")
19860 (if_then_else (eq_attr "alternative" "1,2")
19861 (if_then_else (match_operand:MODEF 3 "mult_operator")
19862 (const_string "ssemul")
19863 (const_string "sseadd"))
19864 (if_then_else (match_operand:MODEF 3 "mult_operator")
19865 (const_string "fmul")
19866 (const_string "fop"))))
19867 (set_attr "isa" "*,noavx,avx")
19868 (set_attr "prefix" "orig,orig,vex")
19869 (set_attr "mode" "<MODE>")
19870 (set (attr "enabled")
19871 (if_then_else
19872 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
19873 (if_then_else
19874 (eq_attr "alternative" "0")
19875 (symbol_ref "TARGET_MIX_SSE_I387
19876 && X87_ENABLE_ARITH (<MODE>mode)")
19877 (const_string "*"))
19878 (if_then_else
19879 (eq_attr "alternative" "0")
19880 (symbol_ref "true")
19881 (symbol_ref "false"))))])
19882
19883 (define_insn "*<insn>hf"
19884 [(set (match_operand:HF 0 "register_operand" "=v")
19885 (plusminusmultdiv:HF
19886 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
19887 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
19888 "TARGET_AVX512FP16
19889 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
19890 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
19891 [(set_attr "prefix" "evex")
19892 (set_attr "mode" "HF")])
19893
19894 (define_insn "*rcpsf2_sse"
19895 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
19896 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
19897 UNSPEC_RCP))]
19898 "TARGET_SSE && TARGET_SSE_MATH"
19899 "@
19900 %vrcpss\t{%d1, %0|%0, %d1}
19901 %vrcpss\t{%d1, %0|%0, %d1}
19902 %vrcpss\t{%1, %d0|%d0, %1}"
19903 [(set_attr "type" "sse")
19904 (set_attr "atom_sse_attr" "rcp")
19905 (set_attr "btver2_sse_attr" "rcp")
19906 (set_attr "prefix" "maybe_vex")
19907 (set_attr "mode" "SF")
19908 (set_attr "avx_partial_xmm_update" "false,false,true")
19909 (set (attr "preferred_for_speed")
19910 (cond [(match_test "TARGET_AVX")
19911 (symbol_ref "true")
19912 (eq_attr "alternative" "1,2")
19913 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
19914 ]
19915 (symbol_ref "true")))])
19916
19917 (define_insn "rcphf2"
19918 [(set (match_operand:HF 0 "register_operand" "=v,v")
19919 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
19920 UNSPEC_RCP))]
19921 "TARGET_AVX512FP16"
19922 "@
19923 vrcpsh\t{%d1, %0|%0, %d1}
19924 vrcpsh\t{%1, %d0|%d0, %1}"
19925 [(set_attr "type" "sse")
19926 (set_attr "prefix" "evex")
19927 (set_attr "mode" "HF")
19928 (set_attr "avx_partial_xmm_update" "false,true")])
19929
19930 (define_insn "*fop_xf_1_i387"
19931 [(set (match_operand:XF 0 "register_operand" "=f,f")
19932 (match_operator:XF 3 "binary_fp_operator"
19933 [(match_operand:XF 1 "register_operand" "0,f")
19934 (match_operand:XF 2 "register_operand" "f,0")]))]
19935 "TARGET_80387
19936 && !COMMUTATIVE_ARITH_P (operands[3])"
19937 "* return output_387_binary_op (insn, operands);"
19938 [(set (attr "type")
19939 (if_then_else (match_operand:XF 3 "div_operator")
19940 (const_string "fdiv")
19941 (const_string "fop")))
19942 (set_attr "mode" "XF")])
19943
19944 (define_insn "*fop_<mode>_1"
19945 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
19946 (match_operator:MODEF 3 "binary_fp_operator"
19947 [(match_operand:MODEF 1
19948 "x87nonimm_ssenomem_operand" "0,fm,0,v")
19949 (match_operand:MODEF 2
19950 "nonimmediate_operand" "fm,0,xm,vm")]))]
19951 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19952 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
19953 && !COMMUTATIVE_ARITH_P (operands[3])
19954 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
19955 "* return output_387_binary_op (insn, operands);"
19956 [(set (attr "type")
19957 (if_then_else (eq_attr "alternative" "2,3")
19958 (if_then_else (match_operand:MODEF 3 "div_operator")
19959 (const_string "ssediv")
19960 (const_string "sseadd"))
19961 (if_then_else (match_operand:MODEF 3 "div_operator")
19962 (const_string "fdiv")
19963 (const_string "fop"))))
19964 (set_attr "isa" "*,*,noavx,avx")
19965 (set_attr "prefix" "orig,orig,orig,vex")
19966 (set_attr "mode" "<MODE>")
19967 (set (attr "enabled")
19968 (if_then_else
19969 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
19970 (if_then_else
19971 (eq_attr "alternative" "0,1")
19972 (symbol_ref "TARGET_MIX_SSE_I387
19973 && X87_ENABLE_ARITH (<MODE>mode)")
19974 (const_string "*"))
19975 (if_then_else
19976 (eq_attr "alternative" "0,1")
19977 (symbol_ref "true")
19978 (symbol_ref "false"))))])
19979
19980 (define_insn "*fop_<X87MODEF:mode>_2_i387"
19981 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
19982 (match_operator:X87MODEF 3 "binary_fp_operator"
19983 [(float:X87MODEF
19984 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
19985 (match_operand:X87MODEF 2 "register_operand" "0")]))]
19986 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
19987 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
19988 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
19989 || optimize_function_for_size_p (cfun))"
19990 "* return output_387_binary_op (insn, operands);"
19991 [(set (attr "type")
19992 (cond [(match_operand:X87MODEF 3 "mult_operator")
19993 (const_string "fmul")
19994 (match_operand:X87MODEF 3 "div_operator")
19995 (const_string "fdiv")
19996 ]
19997 (const_string "fop")))
19998 (set_attr "fp_int_src" "true")
19999 (set_attr "mode" "<SWI24:MODE>")])
20000
20001 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20002 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20003 (match_operator:X87MODEF 3 "binary_fp_operator"
20004 [(match_operand:X87MODEF 1 "register_operand" "0")
20005 (float:X87MODEF
20006 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20007 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20008 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20009 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20010 || optimize_function_for_size_p (cfun))"
20011 "* return output_387_binary_op (insn, operands);"
20012 [(set (attr "type")
20013 (cond [(match_operand:X87MODEF 3 "mult_operator")
20014 (const_string "fmul")
20015 (match_operand:X87MODEF 3 "div_operator")
20016 (const_string "fdiv")
20017 ]
20018 (const_string "fop")))
20019 (set_attr "fp_int_src" "true")
20020 (set_attr "mode" "<SWI24:MODE>")])
20021
20022 (define_insn "*fop_xf_4_i387"
20023 [(set (match_operand:XF 0 "register_operand" "=f,f")
20024 (match_operator:XF 3 "binary_fp_operator"
20025 [(float_extend:XF
20026 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20027 (match_operand:XF 2 "register_operand" "0,f")]))]
20028 "TARGET_80387"
20029 "* return output_387_binary_op (insn, operands);"
20030 [(set (attr "type")
20031 (cond [(match_operand:XF 3 "mult_operator")
20032 (const_string "fmul")
20033 (match_operand:XF 3 "div_operator")
20034 (const_string "fdiv")
20035 ]
20036 (const_string "fop")))
20037 (set_attr "mode" "<MODE>")])
20038
20039 (define_insn "*fop_df_4_i387"
20040 [(set (match_operand:DF 0 "register_operand" "=f,f")
20041 (match_operator:DF 3 "binary_fp_operator"
20042 [(float_extend:DF
20043 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20044 (match_operand:DF 2 "register_operand" "0,f")]))]
20045 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20046 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20047 "* return output_387_binary_op (insn, operands);"
20048 [(set (attr "type")
20049 (cond [(match_operand:DF 3 "mult_operator")
20050 (const_string "fmul")
20051 (match_operand:DF 3 "div_operator")
20052 (const_string "fdiv")
20053 ]
20054 (const_string "fop")))
20055 (set_attr "mode" "SF")])
20056
20057 (define_insn "*fop_xf_5_i387"
20058 [(set (match_operand:XF 0 "register_operand" "=f,f")
20059 (match_operator:XF 3 "binary_fp_operator"
20060 [(match_operand:XF 1 "register_operand" "0,f")
20061 (float_extend:XF
20062 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20063 "TARGET_80387"
20064 "* return output_387_binary_op (insn, operands);"
20065 [(set (attr "type")
20066 (cond [(match_operand:XF 3 "mult_operator")
20067 (const_string "fmul")
20068 (match_operand:XF 3 "div_operator")
20069 (const_string "fdiv")
20070 ]
20071 (const_string "fop")))
20072 (set_attr "mode" "<MODE>")])
20073
20074 (define_insn "*fop_df_5_i387"
20075 [(set (match_operand:DF 0 "register_operand" "=f,f")
20076 (match_operator:DF 3 "binary_fp_operator"
20077 [(match_operand:DF 1 "register_operand" "0,f")
20078 (float_extend:DF
20079 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20080 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20081 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20082 "* return output_387_binary_op (insn, operands);"
20083 [(set (attr "type")
20084 (cond [(match_operand:DF 3 "mult_operator")
20085 (const_string "fmul")
20086 (match_operand:DF 3 "div_operator")
20087 (const_string "fdiv")
20088 ]
20089 (const_string "fop")))
20090 (set_attr "mode" "SF")])
20091
20092 (define_insn "*fop_xf_6_i387"
20093 [(set (match_operand:XF 0 "register_operand" "=f,f")
20094 (match_operator:XF 3 "binary_fp_operator"
20095 [(float_extend:XF
20096 (match_operand:MODEF 1 "register_operand" "0,f"))
20097 (float_extend:XF
20098 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20099 "TARGET_80387"
20100 "* return output_387_binary_op (insn, operands);"
20101 [(set (attr "type")
20102 (cond [(match_operand:XF 3 "mult_operator")
20103 (const_string "fmul")
20104 (match_operand:XF 3 "div_operator")
20105 (const_string "fdiv")
20106 ]
20107 (const_string "fop")))
20108 (set_attr "mode" "<MODE>")])
20109
20110 (define_insn "*fop_df_6_i387"
20111 [(set (match_operand:DF 0 "register_operand" "=f,f")
20112 (match_operator:DF 3 "binary_fp_operator"
20113 [(float_extend:DF
20114 (match_operand:SF 1 "register_operand" "0,f"))
20115 (float_extend:DF
20116 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20117 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20118 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20119 "* return output_387_binary_op (insn, operands);"
20120 [(set (attr "type")
20121 (cond [(match_operand:DF 3 "mult_operator")
20122 (const_string "fmul")
20123 (match_operand:DF 3 "div_operator")
20124 (const_string "fdiv")
20125 ]
20126 (const_string "fop")))
20127 (set_attr "mode" "SF")])
20128 \f
20129 ;; FPU special functions.
20130
20131 ;; This pattern implements a no-op XFmode truncation for
20132 ;; all fancy i386 XFmode math functions.
20133
20134 (define_insn "truncxf<mode>2_i387_noop_unspec"
20135 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20136 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20137 UNSPEC_TRUNC_NOOP))]
20138 "TARGET_USE_FANCY_MATH_387"
20139 "* return output_387_reg_move (insn, operands);"
20140 [(set_attr "type" "fmov")
20141 (set_attr "mode" "<MODE>")])
20142
20143 (define_insn "sqrtxf2"
20144 [(set (match_operand:XF 0 "register_operand" "=f")
20145 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20146 "TARGET_USE_FANCY_MATH_387"
20147 "fsqrt"
20148 [(set_attr "type" "fpspc")
20149 (set_attr "mode" "XF")
20150 (set_attr "athlon_decode" "direct")
20151 (set_attr "amdfam10_decode" "direct")
20152 (set_attr "bdver1_decode" "direct")])
20153
20154 (define_insn "*rsqrtsf2_sse"
20155 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
20156 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
20157 UNSPEC_RSQRT))]
20158 "TARGET_SSE && TARGET_SSE_MATH"
20159 "@
20160 %vrsqrtss\t{%d1, %0|%0, %d1}
20161 %vrsqrtss\t{%d1, %0|%0, %d1}
20162 %vrsqrtss\t{%1, %d0|%d0, %1}"
20163 [(set_attr "type" "sse")
20164 (set_attr "atom_sse_attr" "rcp")
20165 (set_attr "btver2_sse_attr" "rcp")
20166 (set_attr "prefix" "maybe_vex")
20167 (set_attr "mode" "SF")
20168 (set_attr "avx_partial_xmm_update" "false,false,true")
20169 (set (attr "preferred_for_speed")
20170 (cond [(match_test "TARGET_AVX")
20171 (symbol_ref "true")
20172 (eq_attr "alternative" "1,2")
20173 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20174 ]
20175 (symbol_ref "true")))])
20176
20177 (define_expand "rsqrtsf2"
20178 [(set (match_operand:SF 0 "register_operand")
20179 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20180 UNSPEC_RSQRT))]
20181 "TARGET_SSE && TARGET_SSE_MATH"
20182 {
20183 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20184 DONE;
20185 })
20186
20187 (define_insn "rsqrthf2"
20188 [(set (match_operand:HF 0 "register_operand" "=v,v")
20189 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20190 UNSPEC_RSQRT))]
20191 "TARGET_AVX512FP16"
20192 "@
20193 vrsqrtsh\t{%d1, %0|%0, %d1}
20194 vrsqrtsh\t{%1, %d0|%d0, %1}"
20195 [(set_attr "type" "sse")
20196 (set_attr "prefix" "evex")
20197 (set_attr "avx_partial_xmm_update" "false,true")
20198 (set_attr "mode" "HF")])
20199
20200 (define_insn "sqrthf2"
20201 [(set (match_operand:HF 0 "register_operand" "=v,v")
20202 (sqrt:HF
20203 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20204 "TARGET_AVX512FP16"
20205 "@
20206 vsqrtsh\t{%d1, %0|%0, %d1}
20207 vsqrtsh\t{%1, %d0|%d0, %1}"
20208 [(set_attr "type" "sse")
20209 (set_attr "prefix" "evex")
20210 (set_attr "avx_partial_xmm_update" "false,true")
20211 (set_attr "mode" "HF")])
20212
20213 (define_insn "*sqrt<mode>2_sse"
20214 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20215 (sqrt:MODEF
20216 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20217 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20218 "@
20219 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20220 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20221 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20222 [(set_attr "type" "sse")
20223 (set_attr "atom_sse_attr" "sqrt")
20224 (set_attr "btver2_sse_attr" "sqrt")
20225 (set_attr "prefix" "maybe_vex")
20226 (set_attr "avx_partial_xmm_update" "false,false,true")
20227 (set_attr "mode" "<MODE>")
20228 (set (attr "preferred_for_speed")
20229 (cond [(match_test "TARGET_AVX")
20230 (symbol_ref "true")
20231 (eq_attr "alternative" "1,2")
20232 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20233 ]
20234 (symbol_ref "true")))])
20235
20236 (define_expand "sqrt<mode>2"
20237 [(set (match_operand:MODEF 0 "register_operand")
20238 (sqrt:MODEF
20239 (match_operand:MODEF 1 "nonimmediate_operand")))]
20240 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20241 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20242 {
20243 if (<MODE>mode == SFmode
20244 && TARGET_SSE && TARGET_SSE_MATH
20245 && TARGET_RECIP_SQRT
20246 && !optimize_function_for_size_p (cfun)
20247 && flag_finite_math_only && !flag_trapping_math
20248 && flag_unsafe_math_optimizations)
20249 {
20250 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20251 DONE;
20252 }
20253
20254 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20255 {
20256 rtx op0 = gen_reg_rtx (XFmode);
20257 rtx op1 = gen_reg_rtx (XFmode);
20258
20259 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20260 emit_insn (gen_sqrtxf2 (op0, op1));
20261 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20262 DONE;
20263 }
20264 })
20265
20266 (define_expand "hypot<mode>3"
20267 [(use (match_operand:MODEF 0 "register_operand"))
20268 (use (match_operand:MODEF 1 "general_operand"))
20269 (use (match_operand:MODEF 2 "general_operand"))]
20270 "TARGET_USE_FANCY_MATH_387
20271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20272 || TARGET_MIX_SSE_I387)
20273 && flag_finite_math_only
20274 && flag_unsafe_math_optimizations"
20275 {
20276 rtx op0 = gen_reg_rtx (XFmode);
20277 rtx op1 = gen_reg_rtx (XFmode);
20278 rtx op2 = gen_reg_rtx (XFmode);
20279
20280 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20281 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20282
20283 emit_insn (gen_mulxf3 (op1, op1, op1));
20284 emit_insn (gen_mulxf3 (op2, op2, op2));
20285 emit_insn (gen_addxf3 (op0, op2, op1));
20286 emit_insn (gen_sqrtxf2 (op0, op0));
20287
20288 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20289 DONE;
20290 })
20291
20292 (define_insn "x86_fnstsw_1"
20293 [(set (match_operand:HI 0 "register_operand" "=a")
20294 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20295 "TARGET_80387"
20296 "fnstsw\t%0"
20297 [(set_attr "length" "2")
20298 (set_attr "mode" "SI")
20299 (set_attr "unit" "i387")])
20300
20301 (define_insn "fpremxf4_i387"
20302 [(set (match_operand:XF 0 "register_operand" "=f")
20303 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20304 (match_operand:XF 3 "register_operand" "1")]
20305 UNSPEC_FPREM_F))
20306 (set (match_operand:XF 1 "register_operand" "=f")
20307 (unspec:XF [(match_dup 2) (match_dup 3)]
20308 UNSPEC_FPREM_U))
20309 (set (reg:CCFP FPSR_REG)
20310 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20311 UNSPEC_C2_FLAG))]
20312 "TARGET_USE_FANCY_MATH_387"
20313 "fprem"
20314 [(set_attr "type" "fpspc")
20315 (set_attr "znver1_decode" "vector")
20316 (set_attr "mode" "XF")])
20317
20318 (define_expand "fmodxf3"
20319 [(use (match_operand:XF 0 "register_operand"))
20320 (use (match_operand:XF 1 "general_operand"))
20321 (use (match_operand:XF 2 "general_operand"))]
20322 "TARGET_USE_FANCY_MATH_387"
20323 {
20324 rtx_code_label *label = gen_label_rtx ();
20325
20326 rtx op1 = gen_reg_rtx (XFmode);
20327 rtx op2 = gen_reg_rtx (XFmode);
20328
20329 emit_move_insn (op2, operands[2]);
20330 emit_move_insn (op1, operands[1]);
20331
20332 emit_label (label);
20333 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20334 ix86_emit_fp_unordered_jump (label);
20335 LABEL_NUSES (label) = 1;
20336
20337 emit_move_insn (operands[0], op1);
20338 DONE;
20339 })
20340
20341 (define_expand "fmod<mode>3"
20342 [(use (match_operand:MODEF 0 "register_operand"))
20343 (use (match_operand:MODEF 1 "general_operand"))
20344 (use (match_operand:MODEF 2 "general_operand"))]
20345 "TARGET_USE_FANCY_MATH_387"
20346 {
20347 rtx (*gen_truncxf) (rtx, rtx);
20348
20349 rtx_code_label *label = gen_label_rtx ();
20350
20351 rtx op1 = gen_reg_rtx (XFmode);
20352 rtx op2 = gen_reg_rtx (XFmode);
20353
20354 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20355 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20356
20357 emit_label (label);
20358 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20359 ix86_emit_fp_unordered_jump (label);
20360 LABEL_NUSES (label) = 1;
20361
20362 /* Truncate the result properly for strict SSE math. */
20363 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20364 && !TARGET_MIX_SSE_I387)
20365 gen_truncxf = gen_truncxf<mode>2;
20366 else
20367 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20368
20369 emit_insn (gen_truncxf (operands[0], op1));
20370 DONE;
20371 })
20372
20373 (define_insn "fprem1xf4_i387"
20374 [(set (match_operand:XF 0 "register_operand" "=f")
20375 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20376 (match_operand:XF 3 "register_operand" "1")]
20377 UNSPEC_FPREM1_F))
20378 (set (match_operand:XF 1 "register_operand" "=f")
20379 (unspec:XF [(match_dup 2) (match_dup 3)]
20380 UNSPEC_FPREM1_U))
20381 (set (reg:CCFP FPSR_REG)
20382 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20383 UNSPEC_C2_FLAG))]
20384 "TARGET_USE_FANCY_MATH_387"
20385 "fprem1"
20386 [(set_attr "type" "fpspc")
20387 (set_attr "znver1_decode" "vector")
20388 (set_attr "mode" "XF")])
20389
20390 (define_expand "remainderxf3"
20391 [(use (match_operand:XF 0 "register_operand"))
20392 (use (match_operand:XF 1 "general_operand"))
20393 (use (match_operand:XF 2 "general_operand"))]
20394 "TARGET_USE_FANCY_MATH_387"
20395 {
20396 rtx_code_label *label = gen_label_rtx ();
20397
20398 rtx op1 = gen_reg_rtx (XFmode);
20399 rtx op2 = gen_reg_rtx (XFmode);
20400
20401 emit_move_insn (op2, operands[2]);
20402 emit_move_insn (op1, operands[1]);
20403
20404 emit_label (label);
20405 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20406 ix86_emit_fp_unordered_jump (label);
20407 LABEL_NUSES (label) = 1;
20408
20409 emit_move_insn (operands[0], op1);
20410 DONE;
20411 })
20412
20413 (define_expand "remainder<mode>3"
20414 [(use (match_operand:MODEF 0 "register_operand"))
20415 (use (match_operand:MODEF 1 "general_operand"))
20416 (use (match_operand:MODEF 2 "general_operand"))]
20417 "TARGET_USE_FANCY_MATH_387"
20418 {
20419 rtx (*gen_truncxf) (rtx, rtx);
20420
20421 rtx_code_label *label = gen_label_rtx ();
20422
20423 rtx op1 = gen_reg_rtx (XFmode);
20424 rtx op2 = gen_reg_rtx (XFmode);
20425
20426 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20427 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20428
20429 emit_label (label);
20430
20431 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20432 ix86_emit_fp_unordered_jump (label);
20433 LABEL_NUSES (label) = 1;
20434
20435 /* Truncate the result properly for strict SSE math. */
20436 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20437 && !TARGET_MIX_SSE_I387)
20438 gen_truncxf = gen_truncxf<mode>2;
20439 else
20440 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20441
20442 emit_insn (gen_truncxf (operands[0], op1));
20443 DONE;
20444 })
20445
20446 (define_int_iterator SINCOS
20447 [UNSPEC_SIN
20448 UNSPEC_COS])
20449
20450 (define_int_attr sincos
20451 [(UNSPEC_SIN "sin")
20452 (UNSPEC_COS "cos")])
20453
20454 (define_insn "<sincos>xf2"
20455 [(set (match_operand:XF 0 "register_operand" "=f")
20456 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
20457 SINCOS))]
20458 "TARGET_USE_FANCY_MATH_387
20459 && flag_unsafe_math_optimizations"
20460 "f<sincos>"
20461 [(set_attr "type" "fpspc")
20462 (set_attr "znver1_decode" "vector")
20463 (set_attr "mode" "XF")])
20464
20465 (define_expand "<sincos><mode>2"
20466 [(set (match_operand:MODEF 0 "register_operand")
20467 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
20468 SINCOS))]
20469 "TARGET_USE_FANCY_MATH_387
20470 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20471 || TARGET_MIX_SSE_I387)
20472 && flag_unsafe_math_optimizations"
20473 {
20474 rtx op0 = gen_reg_rtx (XFmode);
20475 rtx op1 = gen_reg_rtx (XFmode);
20476
20477 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20478 emit_insn (gen_<sincos>xf2 (op0, op1));
20479 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20480 DONE;
20481 })
20482
20483 (define_insn "sincosxf3"
20484 [(set (match_operand:XF 0 "register_operand" "=f")
20485 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20486 UNSPEC_SINCOS_COS))
20487 (set (match_operand:XF 1 "register_operand" "=f")
20488 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
20489 "TARGET_USE_FANCY_MATH_387
20490 && flag_unsafe_math_optimizations"
20491 "fsincos"
20492 [(set_attr "type" "fpspc")
20493 (set_attr "znver1_decode" "vector")
20494 (set_attr "mode" "XF")])
20495
20496 (define_expand "sincos<mode>3"
20497 [(use (match_operand:MODEF 0 "register_operand"))
20498 (use (match_operand:MODEF 1 "register_operand"))
20499 (use (match_operand:MODEF 2 "general_operand"))]
20500 "TARGET_USE_FANCY_MATH_387
20501 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20502 || TARGET_MIX_SSE_I387)
20503 && flag_unsafe_math_optimizations"
20504 {
20505 rtx op0 = gen_reg_rtx (XFmode);
20506 rtx op1 = gen_reg_rtx (XFmode);
20507 rtx op2 = gen_reg_rtx (XFmode);
20508
20509 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20510 emit_insn (gen_sincosxf3 (op0, op1, op2));
20511 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20512 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
20513 DONE;
20514 })
20515
20516 (define_insn "fptanxf4_i387"
20517 [(set (match_operand:SF 0 "register_operand" "=f")
20518 (match_operand:SF 3 "const1_operand"))
20519 (set (match_operand:XF 1 "register_operand" "=f")
20520 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20521 UNSPEC_TAN))]
20522 "TARGET_USE_FANCY_MATH_387
20523 && flag_unsafe_math_optimizations"
20524 "fptan"
20525 [(set_attr "type" "fpspc")
20526 (set_attr "znver1_decode" "vector")
20527 (set_attr "mode" "XF")])
20528
20529 (define_expand "tanxf2"
20530 [(use (match_operand:XF 0 "register_operand"))
20531 (use (match_operand:XF 1 "register_operand"))]
20532 "TARGET_USE_FANCY_MATH_387
20533 && flag_unsafe_math_optimizations"
20534 {
20535 rtx one = gen_reg_rtx (SFmode);
20536 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
20537 CONST1_RTX (SFmode)));
20538 DONE;
20539 })
20540
20541 (define_expand "tan<mode>2"
20542 [(use (match_operand:MODEF 0 "register_operand"))
20543 (use (match_operand:MODEF 1 "general_operand"))]
20544 "TARGET_USE_FANCY_MATH_387
20545 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20546 || TARGET_MIX_SSE_I387)
20547 && flag_unsafe_math_optimizations"
20548 {
20549 rtx op0 = gen_reg_rtx (XFmode);
20550 rtx op1 = gen_reg_rtx (XFmode);
20551
20552 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20553 emit_insn (gen_tanxf2 (op0, op1));
20554 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20555 DONE;
20556 })
20557
20558 (define_insn "atan2xf3"
20559 [(set (match_operand:XF 0 "register_operand" "=f")
20560 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20561 (match_operand:XF 1 "register_operand" "f")]
20562 UNSPEC_FPATAN))
20563 (clobber (match_scratch:XF 3 "=1"))]
20564 "TARGET_USE_FANCY_MATH_387
20565 && flag_unsafe_math_optimizations"
20566 "fpatan"
20567 [(set_attr "type" "fpspc")
20568 (set_attr "znver1_decode" "vector")
20569 (set_attr "mode" "XF")])
20570
20571 (define_expand "atan2<mode>3"
20572 [(use (match_operand:MODEF 0 "register_operand"))
20573 (use (match_operand:MODEF 1 "general_operand"))
20574 (use (match_operand:MODEF 2 "general_operand"))]
20575 "TARGET_USE_FANCY_MATH_387
20576 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20577 || TARGET_MIX_SSE_I387)
20578 && flag_unsafe_math_optimizations"
20579 {
20580 rtx op0 = gen_reg_rtx (XFmode);
20581 rtx op1 = gen_reg_rtx (XFmode);
20582 rtx op2 = gen_reg_rtx (XFmode);
20583
20584 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20585 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20586
20587 emit_insn (gen_atan2xf3 (op0, op1, op2));
20588 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20589 DONE;
20590 })
20591
20592 (define_expand "atanxf2"
20593 [(parallel [(set (match_operand:XF 0 "register_operand")
20594 (unspec:XF [(match_dup 2)
20595 (match_operand:XF 1 "register_operand")]
20596 UNSPEC_FPATAN))
20597 (clobber (scratch:XF))])]
20598 "TARGET_USE_FANCY_MATH_387
20599 && flag_unsafe_math_optimizations"
20600 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
20601
20602 (define_expand "atan<mode>2"
20603 [(use (match_operand:MODEF 0 "register_operand"))
20604 (use (match_operand:MODEF 1 "general_operand"))]
20605 "TARGET_USE_FANCY_MATH_387
20606 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20607 || TARGET_MIX_SSE_I387)
20608 && flag_unsafe_math_optimizations"
20609 {
20610 rtx op0 = gen_reg_rtx (XFmode);
20611 rtx op1 = gen_reg_rtx (XFmode);
20612
20613 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20614 emit_insn (gen_atanxf2 (op0, op1));
20615 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20616 DONE;
20617 })
20618
20619 (define_expand "asinxf2"
20620 [(set (match_dup 2)
20621 (mult:XF (match_operand:XF 1 "register_operand")
20622 (match_dup 1)))
20623 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20624 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20625 (parallel [(set (match_operand:XF 0 "register_operand")
20626 (unspec:XF [(match_dup 5) (match_dup 1)]
20627 UNSPEC_FPATAN))
20628 (clobber (scratch:XF))])]
20629 "TARGET_USE_FANCY_MATH_387
20630 && flag_unsafe_math_optimizations"
20631 {
20632 int i;
20633
20634 for (i = 2; i < 6; i++)
20635 operands[i] = gen_reg_rtx (XFmode);
20636
20637 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20638 })
20639
20640 (define_expand "asin<mode>2"
20641 [(use (match_operand:MODEF 0 "register_operand"))
20642 (use (match_operand:MODEF 1 "general_operand"))]
20643 "TARGET_USE_FANCY_MATH_387
20644 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20645 || TARGET_MIX_SSE_I387)
20646 && flag_unsafe_math_optimizations"
20647 {
20648 rtx op0 = gen_reg_rtx (XFmode);
20649 rtx op1 = gen_reg_rtx (XFmode);
20650
20651 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20652 emit_insn (gen_asinxf2 (op0, op1));
20653 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20654 DONE;
20655 })
20656
20657 (define_expand "acosxf2"
20658 [(set (match_dup 2)
20659 (mult:XF (match_operand:XF 1 "register_operand")
20660 (match_dup 1)))
20661 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20662 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20663 (parallel [(set (match_operand:XF 0 "register_operand")
20664 (unspec:XF [(match_dup 1) (match_dup 5)]
20665 UNSPEC_FPATAN))
20666 (clobber (scratch:XF))])]
20667 "TARGET_USE_FANCY_MATH_387
20668 && flag_unsafe_math_optimizations"
20669 {
20670 int i;
20671
20672 for (i = 2; i < 6; i++)
20673 operands[i] = gen_reg_rtx (XFmode);
20674
20675 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20676 })
20677
20678 (define_expand "acos<mode>2"
20679 [(use (match_operand:MODEF 0 "register_operand"))
20680 (use (match_operand:MODEF 1 "general_operand"))]
20681 "TARGET_USE_FANCY_MATH_387
20682 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20683 || TARGET_MIX_SSE_I387)
20684 && flag_unsafe_math_optimizations"
20685 {
20686 rtx op0 = gen_reg_rtx (XFmode);
20687 rtx op1 = gen_reg_rtx (XFmode);
20688
20689 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20690 emit_insn (gen_acosxf2 (op0, op1));
20691 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20692 DONE;
20693 })
20694
20695 (define_expand "sinhxf2"
20696 [(use (match_operand:XF 0 "register_operand"))
20697 (use (match_operand:XF 1 "register_operand"))]
20698 "TARGET_USE_FANCY_MATH_387
20699 && flag_finite_math_only
20700 && flag_unsafe_math_optimizations"
20701 {
20702 ix86_emit_i387_sinh (operands[0], operands[1]);
20703 DONE;
20704 })
20705
20706 (define_expand "sinh<mode>2"
20707 [(use (match_operand:MODEF 0 "register_operand"))
20708 (use (match_operand:MODEF 1 "general_operand"))]
20709 "TARGET_USE_FANCY_MATH_387
20710 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20711 || TARGET_MIX_SSE_I387)
20712 && flag_finite_math_only
20713 && flag_unsafe_math_optimizations"
20714 {
20715 rtx op0 = gen_reg_rtx (XFmode);
20716 rtx op1 = gen_reg_rtx (XFmode);
20717
20718 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20719 emit_insn (gen_sinhxf2 (op0, op1));
20720 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20721 DONE;
20722 })
20723
20724 (define_expand "coshxf2"
20725 [(use (match_operand:XF 0 "register_operand"))
20726 (use (match_operand:XF 1 "register_operand"))]
20727 "TARGET_USE_FANCY_MATH_387
20728 && flag_unsafe_math_optimizations"
20729 {
20730 ix86_emit_i387_cosh (operands[0], operands[1]);
20731 DONE;
20732 })
20733
20734 (define_expand "cosh<mode>2"
20735 [(use (match_operand:MODEF 0 "register_operand"))
20736 (use (match_operand:MODEF 1 "general_operand"))]
20737 "TARGET_USE_FANCY_MATH_387
20738 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20739 || TARGET_MIX_SSE_I387)
20740 && flag_unsafe_math_optimizations"
20741 {
20742 rtx op0 = gen_reg_rtx (XFmode);
20743 rtx op1 = gen_reg_rtx (XFmode);
20744
20745 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20746 emit_insn (gen_coshxf2 (op0, op1));
20747 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20748 DONE;
20749 })
20750
20751 (define_expand "tanhxf2"
20752 [(use (match_operand:XF 0 "register_operand"))
20753 (use (match_operand:XF 1 "register_operand"))]
20754 "TARGET_USE_FANCY_MATH_387
20755 && flag_unsafe_math_optimizations"
20756 {
20757 ix86_emit_i387_tanh (operands[0], operands[1]);
20758 DONE;
20759 })
20760
20761 (define_expand "tanh<mode>2"
20762 [(use (match_operand:MODEF 0 "register_operand"))
20763 (use (match_operand:MODEF 1 "general_operand"))]
20764 "TARGET_USE_FANCY_MATH_387
20765 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20766 || TARGET_MIX_SSE_I387)
20767 && flag_unsafe_math_optimizations"
20768 {
20769 rtx op0 = gen_reg_rtx (XFmode);
20770 rtx op1 = gen_reg_rtx (XFmode);
20771
20772 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20773 emit_insn (gen_tanhxf2 (op0, op1));
20774 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20775 DONE;
20776 })
20777
20778 (define_expand "asinhxf2"
20779 [(use (match_operand:XF 0 "register_operand"))
20780 (use (match_operand:XF 1 "register_operand"))]
20781 "TARGET_USE_FANCY_MATH_387
20782 && flag_finite_math_only
20783 && flag_unsafe_math_optimizations"
20784 {
20785 ix86_emit_i387_asinh (operands[0], operands[1]);
20786 DONE;
20787 })
20788
20789 (define_expand "asinh<mode>2"
20790 [(use (match_operand:MODEF 0 "register_operand"))
20791 (use (match_operand:MODEF 1 "general_operand"))]
20792 "TARGET_USE_FANCY_MATH_387
20793 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20794 || TARGET_MIX_SSE_I387)
20795 && flag_finite_math_only
20796 && flag_unsafe_math_optimizations"
20797 {
20798 rtx op0 = gen_reg_rtx (XFmode);
20799 rtx op1 = gen_reg_rtx (XFmode);
20800
20801 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20802 emit_insn (gen_asinhxf2 (op0, op1));
20803 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20804 DONE;
20805 })
20806
20807 (define_expand "acoshxf2"
20808 [(use (match_operand:XF 0 "register_operand"))
20809 (use (match_operand:XF 1 "register_operand"))]
20810 "TARGET_USE_FANCY_MATH_387
20811 && flag_unsafe_math_optimizations"
20812 {
20813 ix86_emit_i387_acosh (operands[0], operands[1]);
20814 DONE;
20815 })
20816
20817 (define_expand "acosh<mode>2"
20818 [(use (match_operand:MODEF 0 "register_operand"))
20819 (use (match_operand:MODEF 1 "general_operand"))]
20820 "TARGET_USE_FANCY_MATH_387
20821 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20822 || TARGET_MIX_SSE_I387)
20823 && flag_unsafe_math_optimizations"
20824 {
20825 rtx op0 = gen_reg_rtx (XFmode);
20826 rtx op1 = gen_reg_rtx (XFmode);
20827
20828 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20829 emit_insn (gen_acoshxf2 (op0, op1));
20830 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20831 DONE;
20832 })
20833
20834 (define_expand "atanhxf2"
20835 [(use (match_operand:XF 0 "register_operand"))
20836 (use (match_operand:XF 1 "register_operand"))]
20837 "TARGET_USE_FANCY_MATH_387
20838 && flag_unsafe_math_optimizations"
20839 {
20840 ix86_emit_i387_atanh (operands[0], operands[1]);
20841 DONE;
20842 })
20843
20844 (define_expand "atanh<mode>2"
20845 [(use (match_operand:MODEF 0 "register_operand"))
20846 (use (match_operand:MODEF 1 "general_operand"))]
20847 "TARGET_USE_FANCY_MATH_387
20848 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20849 || TARGET_MIX_SSE_I387)
20850 && flag_unsafe_math_optimizations"
20851 {
20852 rtx op0 = gen_reg_rtx (XFmode);
20853 rtx op1 = gen_reg_rtx (XFmode);
20854
20855 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20856 emit_insn (gen_atanhxf2 (op0, op1));
20857 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20858 DONE;
20859 })
20860
20861 (define_insn "fyl2xxf3_i387"
20862 [(set (match_operand:XF 0 "register_operand" "=f")
20863 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
20864 (match_operand:XF 2 "register_operand" "f")]
20865 UNSPEC_FYL2X))
20866 (clobber (match_scratch:XF 3 "=2"))]
20867 "TARGET_USE_FANCY_MATH_387
20868 && flag_unsafe_math_optimizations"
20869 "fyl2x"
20870 [(set_attr "type" "fpspc")
20871 (set_attr "znver1_decode" "vector")
20872 (set_attr "mode" "XF")])
20873
20874 (define_expand "logxf2"
20875 [(parallel [(set (match_operand:XF 0 "register_operand")
20876 (unspec:XF [(match_operand:XF 1 "register_operand")
20877 (match_dup 2)] UNSPEC_FYL2X))
20878 (clobber (scratch:XF))])]
20879 "TARGET_USE_FANCY_MATH_387
20880 && flag_unsafe_math_optimizations"
20881 {
20882 operands[2]
20883 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
20884 })
20885
20886 (define_expand "log<mode>2"
20887 [(use (match_operand:MODEF 0 "register_operand"))
20888 (use (match_operand:MODEF 1 "general_operand"))]
20889 "TARGET_USE_FANCY_MATH_387
20890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20891 || TARGET_MIX_SSE_I387)
20892 && flag_unsafe_math_optimizations"
20893 {
20894 rtx op0 = gen_reg_rtx (XFmode);
20895 rtx op1 = gen_reg_rtx (XFmode);
20896
20897 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20898 emit_insn (gen_logxf2 (op0, op1));
20899 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20900 DONE;
20901 })
20902
20903 (define_expand "log10xf2"
20904 [(parallel [(set (match_operand:XF 0 "register_operand")
20905 (unspec:XF [(match_operand:XF 1 "register_operand")
20906 (match_dup 2)] UNSPEC_FYL2X))
20907 (clobber (scratch:XF))])]
20908 "TARGET_USE_FANCY_MATH_387
20909 && flag_unsafe_math_optimizations"
20910 {
20911 operands[2]
20912 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
20913 })
20914
20915 (define_expand "log10<mode>2"
20916 [(use (match_operand:MODEF 0 "register_operand"))
20917 (use (match_operand:MODEF 1 "general_operand"))]
20918 "TARGET_USE_FANCY_MATH_387
20919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20920 || TARGET_MIX_SSE_I387)
20921 && flag_unsafe_math_optimizations"
20922 {
20923 rtx op0 = gen_reg_rtx (XFmode);
20924 rtx op1 = gen_reg_rtx (XFmode);
20925
20926 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20927 emit_insn (gen_log10xf2 (op0, op1));
20928 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20929 DONE;
20930 })
20931
20932 (define_expand "log2xf2"
20933 [(parallel [(set (match_operand:XF 0 "register_operand")
20934 (unspec:XF [(match_operand:XF 1 "register_operand")
20935 (match_dup 2)] UNSPEC_FYL2X))
20936 (clobber (scratch:XF))])]
20937 "TARGET_USE_FANCY_MATH_387
20938 && flag_unsafe_math_optimizations"
20939 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
20940
20941 (define_expand "log2<mode>2"
20942 [(use (match_operand:MODEF 0 "register_operand"))
20943 (use (match_operand:MODEF 1 "general_operand"))]
20944 "TARGET_USE_FANCY_MATH_387
20945 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20946 || TARGET_MIX_SSE_I387)
20947 && flag_unsafe_math_optimizations"
20948 {
20949 rtx op0 = gen_reg_rtx (XFmode);
20950 rtx op1 = gen_reg_rtx (XFmode);
20951
20952 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20953 emit_insn (gen_log2xf2 (op0, op1));
20954 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20955 DONE;
20956 })
20957
20958 (define_insn "fyl2xp1xf3_i387"
20959 [(set (match_operand:XF 0 "register_operand" "=f")
20960 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
20961 (match_operand:XF 2 "register_operand" "f")]
20962 UNSPEC_FYL2XP1))
20963 (clobber (match_scratch:XF 3 "=2"))]
20964 "TARGET_USE_FANCY_MATH_387
20965 && flag_unsafe_math_optimizations"
20966 "fyl2xp1"
20967 [(set_attr "type" "fpspc")
20968 (set_attr "znver1_decode" "vector")
20969 (set_attr "mode" "XF")])
20970
20971 (define_expand "log1pxf2"
20972 [(use (match_operand:XF 0 "register_operand"))
20973 (use (match_operand:XF 1 "register_operand"))]
20974 "TARGET_USE_FANCY_MATH_387
20975 && flag_unsafe_math_optimizations"
20976 {
20977 ix86_emit_i387_log1p (operands[0], operands[1]);
20978 DONE;
20979 })
20980
20981 (define_expand "log1p<mode>2"
20982 [(use (match_operand:MODEF 0 "register_operand"))
20983 (use (match_operand:MODEF 1 "general_operand"))]
20984 "TARGET_USE_FANCY_MATH_387
20985 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20986 || TARGET_MIX_SSE_I387)
20987 && flag_unsafe_math_optimizations"
20988 {
20989 rtx op0 = gen_reg_rtx (XFmode);
20990 rtx op1 = gen_reg_rtx (XFmode);
20991
20992 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20993 emit_insn (gen_log1pxf2 (op0, op1));
20994 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20995 DONE;
20996 })
20997
20998 (define_insn "fxtractxf3_i387"
20999 [(set (match_operand:XF 0 "register_operand" "=f")
21000 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21001 UNSPEC_XTRACT_FRACT))
21002 (set (match_operand:XF 1 "register_operand" "=f")
21003 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21004 "TARGET_USE_FANCY_MATH_387
21005 && flag_unsafe_math_optimizations"
21006 "fxtract"
21007 [(set_attr "type" "fpspc")
21008 (set_attr "znver1_decode" "vector")
21009 (set_attr "mode" "XF")])
21010
21011 (define_expand "logbxf2"
21012 [(parallel [(set (match_dup 2)
21013 (unspec:XF [(match_operand:XF 1 "register_operand")]
21014 UNSPEC_XTRACT_FRACT))
21015 (set (match_operand:XF 0 "register_operand")
21016 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21017 "TARGET_USE_FANCY_MATH_387
21018 && flag_unsafe_math_optimizations"
21019 "operands[2] = gen_reg_rtx (XFmode);")
21020
21021 (define_expand "logb<mode>2"
21022 [(use (match_operand:MODEF 0 "register_operand"))
21023 (use (match_operand:MODEF 1 "general_operand"))]
21024 "TARGET_USE_FANCY_MATH_387
21025 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21026 || TARGET_MIX_SSE_I387)
21027 && flag_unsafe_math_optimizations"
21028 {
21029 rtx op0 = gen_reg_rtx (XFmode);
21030 rtx op1 = gen_reg_rtx (XFmode);
21031
21032 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21033 emit_insn (gen_logbxf2 (op0, op1));
21034 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21035 DONE;
21036 })
21037
21038 (define_expand "ilogbxf2"
21039 [(use (match_operand:SI 0 "register_operand"))
21040 (use (match_operand:XF 1 "register_operand"))]
21041 "TARGET_USE_FANCY_MATH_387
21042 && flag_unsafe_math_optimizations"
21043 {
21044 rtx op0, op1;
21045
21046 if (optimize_insn_for_size_p ())
21047 FAIL;
21048
21049 op0 = gen_reg_rtx (XFmode);
21050 op1 = gen_reg_rtx (XFmode);
21051
21052 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21053 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21054 DONE;
21055 })
21056
21057 (define_expand "ilogb<mode>2"
21058 [(use (match_operand:SI 0 "register_operand"))
21059 (use (match_operand:MODEF 1 "general_operand"))]
21060 "TARGET_USE_FANCY_MATH_387
21061 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21062 || TARGET_MIX_SSE_I387)
21063 && flag_unsafe_math_optimizations"
21064 {
21065 rtx op0, op1, op2;
21066
21067 if (optimize_insn_for_size_p ())
21068 FAIL;
21069
21070 op0 = gen_reg_rtx (XFmode);
21071 op1 = gen_reg_rtx (XFmode);
21072 op2 = gen_reg_rtx (XFmode);
21073
21074 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21075 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21076 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21077 DONE;
21078 })
21079
21080 (define_insn "*f2xm1xf2_i387"
21081 [(set (match_operand:XF 0 "register_operand" "=f")
21082 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21083 UNSPEC_F2XM1))]
21084 "TARGET_USE_FANCY_MATH_387
21085 && flag_unsafe_math_optimizations"
21086 "f2xm1"
21087 [(set_attr "type" "fpspc")
21088 (set_attr "znver1_decode" "vector")
21089 (set_attr "mode" "XF")])
21090
21091 (define_insn "fscalexf4_i387"
21092 [(set (match_operand:XF 0 "register_operand" "=f")
21093 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21094 (match_operand:XF 3 "register_operand" "1")]
21095 UNSPEC_FSCALE_FRACT))
21096 (set (match_operand:XF 1 "register_operand" "=f")
21097 (unspec:XF [(match_dup 2) (match_dup 3)]
21098 UNSPEC_FSCALE_EXP))]
21099 "TARGET_USE_FANCY_MATH_387
21100 && flag_unsafe_math_optimizations"
21101 "fscale"
21102 [(set_attr "type" "fpspc")
21103 (set_attr "znver1_decode" "vector")
21104 (set_attr "mode" "XF")])
21105
21106 (define_expand "expNcorexf3"
21107 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21108 (match_operand:XF 2 "register_operand")))
21109 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21110 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21111 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21112 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21113 (parallel [(set (match_operand:XF 0 "register_operand")
21114 (unspec:XF [(match_dup 8) (match_dup 4)]
21115 UNSPEC_FSCALE_FRACT))
21116 (set (match_dup 9)
21117 (unspec:XF [(match_dup 8) (match_dup 4)]
21118 UNSPEC_FSCALE_EXP))])]
21119 "TARGET_USE_FANCY_MATH_387
21120 && flag_unsafe_math_optimizations"
21121 {
21122 int i;
21123
21124 for (i = 3; i < 10; i++)
21125 operands[i] = gen_reg_rtx (XFmode);
21126
21127 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21128 })
21129
21130 (define_expand "expxf2"
21131 [(use (match_operand:XF 0 "register_operand"))
21132 (use (match_operand:XF 1 "register_operand"))]
21133 "TARGET_USE_FANCY_MATH_387
21134 && flag_unsafe_math_optimizations"
21135 {
21136 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21137
21138 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21139 DONE;
21140 })
21141
21142 (define_expand "exp<mode>2"
21143 [(use (match_operand:MODEF 0 "register_operand"))
21144 (use (match_operand:MODEF 1 "general_operand"))]
21145 "TARGET_USE_FANCY_MATH_387
21146 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21147 || TARGET_MIX_SSE_I387)
21148 && flag_unsafe_math_optimizations"
21149 {
21150 rtx op0 = gen_reg_rtx (XFmode);
21151 rtx op1 = gen_reg_rtx (XFmode);
21152
21153 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21154 emit_insn (gen_expxf2 (op0, op1));
21155 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21156 DONE;
21157 })
21158
21159 (define_expand "exp10xf2"
21160 [(use (match_operand:XF 0 "register_operand"))
21161 (use (match_operand:XF 1 "register_operand"))]
21162 "TARGET_USE_FANCY_MATH_387
21163 && flag_unsafe_math_optimizations"
21164 {
21165 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21166
21167 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21168 DONE;
21169 })
21170
21171 (define_expand "exp10<mode>2"
21172 [(use (match_operand:MODEF 0 "register_operand"))
21173 (use (match_operand:MODEF 1 "general_operand"))]
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_exp10xf2 (op0, op1));
21184 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21185 DONE;
21186 })
21187
21188 (define_expand "exp2xf2"
21189 [(use (match_operand:XF 0 "register_operand"))
21190 (use (match_operand:XF 1 "register_operand"))]
21191 "TARGET_USE_FANCY_MATH_387
21192 && flag_unsafe_math_optimizations"
21193 {
21194 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21195
21196 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21197 DONE;
21198 })
21199
21200 (define_expand "exp2<mode>2"
21201 [(use (match_operand:MODEF 0 "register_operand"))
21202 (use (match_operand:MODEF 1 "general_operand"))]
21203 "TARGET_USE_FANCY_MATH_387
21204 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21205 || TARGET_MIX_SSE_I387)
21206 && flag_unsafe_math_optimizations"
21207 {
21208 rtx op0 = gen_reg_rtx (XFmode);
21209 rtx op1 = gen_reg_rtx (XFmode);
21210
21211 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21212 emit_insn (gen_exp2xf2 (op0, op1));
21213 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21214 DONE;
21215 })
21216
21217 (define_expand "expm1xf2"
21218 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21219 (match_dup 2)))
21220 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21221 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21222 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21223 (parallel [(set (match_dup 7)
21224 (unspec:XF [(match_dup 6) (match_dup 4)]
21225 UNSPEC_FSCALE_FRACT))
21226 (set (match_dup 8)
21227 (unspec:XF [(match_dup 6) (match_dup 4)]
21228 UNSPEC_FSCALE_EXP))])
21229 (parallel [(set (match_dup 10)
21230 (unspec:XF [(match_dup 9) (match_dup 8)]
21231 UNSPEC_FSCALE_FRACT))
21232 (set (match_dup 11)
21233 (unspec:XF [(match_dup 9) (match_dup 8)]
21234 UNSPEC_FSCALE_EXP))])
21235 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21236 (set (match_operand:XF 0 "register_operand")
21237 (plus:XF (match_dup 12) (match_dup 7)))]
21238 "TARGET_USE_FANCY_MATH_387
21239 && flag_unsafe_math_optimizations"
21240 {
21241 int i;
21242
21243 for (i = 2; i < 13; i++)
21244 operands[i] = gen_reg_rtx (XFmode);
21245
21246 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21247 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21248 })
21249
21250 (define_expand "expm1<mode>2"
21251 [(use (match_operand:MODEF 0 "register_operand"))
21252 (use (match_operand:MODEF 1 "general_operand"))]
21253 "TARGET_USE_FANCY_MATH_387
21254 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21255 || TARGET_MIX_SSE_I387)
21256 && flag_unsafe_math_optimizations"
21257 {
21258 rtx op0 = gen_reg_rtx (XFmode);
21259 rtx op1 = gen_reg_rtx (XFmode);
21260
21261 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21262 emit_insn (gen_expm1xf2 (op0, op1));
21263 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21264 DONE;
21265 })
21266
21267 (define_insn "avx512f_scalef<mode>2"
21268 [(set (match_operand:MODEF 0 "register_operand" "=v")
21269 (unspec:MODEF
21270 [(match_operand:MODEF 1 "register_operand" "v")
21271 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21272 UNSPEC_SCALEF))]
21273 "TARGET_AVX512F"
21274 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21275 [(set_attr "prefix" "evex")
21276 (set_attr "mode" "<MODE>")])
21277
21278 (define_expand "ldexpxf3"
21279 [(match_operand:XF 0 "register_operand")
21280 (match_operand:XF 1 "register_operand")
21281 (match_operand:SI 2 "register_operand")]
21282 "TARGET_USE_FANCY_MATH_387
21283 && flag_unsafe_math_optimizations"
21284 {
21285 rtx tmp1 = gen_reg_rtx (XFmode);
21286 rtx tmp2 = gen_reg_rtx (XFmode);
21287
21288 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21289 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21290 operands[1], tmp1));
21291 DONE;
21292 })
21293
21294 (define_expand "ldexp<mode>3"
21295 [(use (match_operand:MODEF 0 "register_operand"))
21296 (use (match_operand:MODEF 1 "general_operand"))
21297 (use (match_operand:SI 2 "register_operand"))]
21298 "((TARGET_USE_FANCY_MATH_387
21299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21300 || TARGET_MIX_SSE_I387))
21301 || (TARGET_AVX512F && TARGET_SSE_MATH))
21302 && flag_unsafe_math_optimizations"
21303 {
21304 /* Prefer avx512f version. */
21305 if (TARGET_AVX512F && TARGET_SSE_MATH)
21306 {
21307 rtx op2 = gen_reg_rtx (<MODE>mode);
21308 operands[1] = force_reg (<MODE>mode, operands[1]);
21309
21310 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21311 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21312 }
21313 else
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_ldexpxf3 (op0, op1, operands[2]));
21320 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21321 }
21322 DONE;
21323 })
21324
21325 (define_expand "scalbxf3"
21326 [(parallel [(set (match_operand:XF 0 " register_operand")
21327 (unspec:XF [(match_operand:XF 1 "register_operand")
21328 (match_operand:XF 2 "register_operand")]
21329 UNSPEC_FSCALE_FRACT))
21330 (set (match_dup 3)
21331 (unspec:XF [(match_dup 1) (match_dup 2)]
21332 UNSPEC_FSCALE_EXP))])]
21333 "TARGET_USE_FANCY_MATH_387
21334 && flag_unsafe_math_optimizations"
21335 "operands[3] = gen_reg_rtx (XFmode);")
21336
21337 (define_expand "scalb<mode>3"
21338 [(use (match_operand:MODEF 0 "register_operand"))
21339 (use (match_operand:MODEF 1 "general_operand"))
21340 (use (match_operand:MODEF 2 "general_operand"))]
21341 "TARGET_USE_FANCY_MATH_387
21342 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21343 || TARGET_MIX_SSE_I387)
21344 && flag_unsafe_math_optimizations"
21345 {
21346 rtx op0 = gen_reg_rtx (XFmode);
21347 rtx op1 = gen_reg_rtx (XFmode);
21348 rtx op2 = gen_reg_rtx (XFmode);
21349
21350 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21351 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21352 emit_insn (gen_scalbxf3 (op0, op1, op2));
21353 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21354 DONE;
21355 })
21356
21357 (define_expand "significandxf2"
21358 [(parallel [(set (match_operand:XF 0 "register_operand")
21359 (unspec:XF [(match_operand:XF 1 "register_operand")]
21360 UNSPEC_XTRACT_FRACT))
21361 (set (match_dup 2)
21362 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21363 "TARGET_USE_FANCY_MATH_387
21364 && flag_unsafe_math_optimizations"
21365 "operands[2] = gen_reg_rtx (XFmode);")
21366
21367 (define_expand "significand<mode>2"
21368 [(use (match_operand:MODEF 0 "register_operand"))
21369 (use (match_operand:MODEF 1 "general_operand"))]
21370 "TARGET_USE_FANCY_MATH_387
21371 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21372 || TARGET_MIX_SSE_I387)
21373 && flag_unsafe_math_optimizations"
21374 {
21375 rtx op0 = gen_reg_rtx (XFmode);
21376 rtx op1 = gen_reg_rtx (XFmode);
21377
21378 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21379 emit_insn (gen_significandxf2 (op0, op1));
21380 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21381 DONE;
21382 })
21383 \f
21384
21385 (define_insn "sse4_1_round<mode>2"
21386 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21387 (unspec:MODEFH
21388 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,m,v,m")
21389 (match_operand:SI 2 "const_0_to_15_operand")]
21390 UNSPEC_ROUND))]
21391 "TARGET_SSE4_1"
21392 "@
21393 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21394 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21395 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21396 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21397 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21398 [(set_attr "type" "ssecvt")
21399 (set_attr "prefix_extra" "1,1,1,*,*")
21400 (set_attr "length_immediate" "*,*,*,1,1")
21401 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21402 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21403 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21404 (set_attr "mode" "<MODE>")
21405 (set (attr "preferred_for_speed")
21406 (cond [(match_test "TARGET_AVX")
21407 (symbol_ref "true")
21408 (eq_attr "alternative" "1,2")
21409 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21410 ]
21411 (symbol_ref "true")))])
21412
21413 (define_insn "rintxf2"
21414 [(set (match_operand:XF 0 "register_operand" "=f")
21415 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21416 UNSPEC_FRNDINT))]
21417 "TARGET_USE_FANCY_MATH_387"
21418 "frndint"
21419 [(set_attr "type" "fpspc")
21420 (set_attr "znver1_decode" "vector")
21421 (set_attr "mode" "XF")])
21422
21423 (define_expand "rinthf2"
21424 [(match_operand:HF 0 "register_operand")
21425 (match_operand:HF 1 "nonimmediate_operand")]
21426 "TARGET_AVX512FP16"
21427 {
21428 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21429 operands[1],
21430 GEN_INT (ROUND_MXCSR)));
21431 DONE;
21432 })
21433
21434 (define_expand "rint<mode>2"
21435 [(use (match_operand:MODEF 0 "register_operand"))
21436 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21437 "TARGET_USE_FANCY_MATH_387
21438 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21439 {
21440 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21441 {
21442 if (TARGET_SSE4_1)
21443 emit_insn (gen_sse4_1_round<mode>2
21444 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
21445 else
21446 ix86_expand_rint (operands[0], operands[1]);
21447 }
21448 else
21449 {
21450 rtx op0 = gen_reg_rtx (XFmode);
21451 rtx op1 = gen_reg_rtx (XFmode);
21452
21453 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21454 emit_insn (gen_rintxf2 (op0, op1));
21455 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21456 }
21457 DONE;
21458 })
21459
21460 (define_expand "nearbyintxf2"
21461 [(set (match_operand:XF 0 "register_operand")
21462 (unspec:XF [(match_operand:XF 1 "register_operand")]
21463 UNSPEC_FRNDINT))]
21464 "TARGET_USE_FANCY_MATH_387
21465 && !flag_trapping_math")
21466
21467 (define_expand "nearbyinthf2"
21468 [(match_operand:HF 0 "register_operand")
21469 (match_operand:HF 1 "nonimmediate_operand")]
21470 "TARGET_AVX512FP16"
21471 {
21472 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21473 operands[1],
21474 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
21475 DONE;
21476 })
21477
21478 (define_expand "nearbyint<mode>2"
21479 [(use (match_operand:MODEF 0 "register_operand"))
21480 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21481 "(TARGET_USE_FANCY_MATH_387
21482 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21483 || TARGET_MIX_SSE_I387)
21484 && !flag_trapping_math)
21485 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
21486 {
21487 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
21488 emit_insn (gen_sse4_1_round<mode>2
21489 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
21490 | ROUND_NO_EXC)));
21491 else
21492 {
21493 rtx op0 = gen_reg_rtx (XFmode);
21494 rtx op1 = gen_reg_rtx (XFmode);
21495
21496 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21497 emit_insn (gen_nearbyintxf2 (op0, op1));
21498 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21499 }
21500 DONE;
21501 })
21502
21503 (define_expand "round<mode>2"
21504 [(match_operand:X87MODEF 0 "register_operand")
21505 (match_operand:X87MODEF 1 "nonimmediate_operand")]
21506 "(TARGET_USE_FANCY_MATH_387
21507 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21508 || TARGET_MIX_SSE_I387)
21509 && flag_unsafe_math_optimizations
21510 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21511 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21512 && !flag_trapping_math && !flag_rounding_math)"
21513 {
21514 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21515 && !flag_trapping_math && !flag_rounding_math)
21516 {
21517 if (TARGET_SSE4_1)
21518 {
21519 operands[1] = force_reg (<MODE>mode, operands[1]);
21520 ix86_expand_round_sse4 (operands[0], operands[1]);
21521 }
21522 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21523 ix86_expand_round (operands[0], operands[1]);
21524 else
21525 ix86_expand_rounddf_32 (operands[0], operands[1]);
21526 }
21527 else
21528 {
21529 operands[1] = force_reg (<MODE>mode, operands[1]);
21530 ix86_emit_i387_round (operands[0], operands[1]);
21531 }
21532 DONE;
21533 })
21534
21535 (define_insn "lrintxfdi2"
21536 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21537 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21538 UNSPEC_FIST))
21539 (clobber (match_scratch:XF 2 "=&f"))]
21540 "TARGET_USE_FANCY_MATH_387"
21541 "* return output_fix_trunc (insn, operands, false);"
21542 [(set_attr "type" "fpspc")
21543 (set_attr "mode" "DI")])
21544
21545 (define_insn "lrintxf<mode>2"
21546 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21547 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21548 UNSPEC_FIST))]
21549 "TARGET_USE_FANCY_MATH_387"
21550 "* return output_fix_trunc (insn, operands, false);"
21551 [(set_attr "type" "fpspc")
21552 (set_attr "mode" "<MODE>")])
21553
21554 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
21555 [(set (match_operand:SWI48 0 "register_operand")
21556 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
21557 UNSPEC_FIX_NOTRUNC))]
21558 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
21559
21560 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
21561 [(match_operand:SWI248x 0 "nonimmediate_operand")
21562 (match_operand:X87MODEF 1 "register_operand")]
21563 "(TARGET_USE_FANCY_MATH_387
21564 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
21565 || TARGET_MIX_SSE_I387)
21566 && flag_unsafe_math_optimizations)
21567 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21568 && <SWI248x:MODE>mode != HImode
21569 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21570 && !flag_trapping_math && !flag_rounding_math)"
21571 {
21572 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21573 && <SWI248x:MODE>mode != HImode
21574 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21575 && !flag_trapping_math && !flag_rounding_math)
21576 ix86_expand_lround (operands[0], operands[1]);
21577 else
21578 ix86_emit_i387_round (operands[0], operands[1]);
21579 DONE;
21580 })
21581
21582 (define_int_iterator FRNDINT_ROUNDING
21583 [UNSPEC_FRNDINT_ROUNDEVEN
21584 UNSPEC_FRNDINT_FLOOR
21585 UNSPEC_FRNDINT_CEIL
21586 UNSPEC_FRNDINT_TRUNC])
21587
21588 (define_int_iterator FIST_ROUNDING
21589 [UNSPEC_FIST_FLOOR
21590 UNSPEC_FIST_CEIL])
21591
21592 ;; Base name for define_insn
21593 (define_int_attr rounding_insn
21594 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21595 (UNSPEC_FRNDINT_FLOOR "floor")
21596 (UNSPEC_FRNDINT_CEIL "ceil")
21597 (UNSPEC_FRNDINT_TRUNC "btrunc")
21598 (UNSPEC_FIST_FLOOR "floor")
21599 (UNSPEC_FIST_CEIL "ceil")])
21600
21601 (define_int_attr rounding
21602 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21603 (UNSPEC_FRNDINT_FLOOR "floor")
21604 (UNSPEC_FRNDINT_CEIL "ceil")
21605 (UNSPEC_FRNDINT_TRUNC "trunc")
21606 (UNSPEC_FIST_FLOOR "floor")
21607 (UNSPEC_FIST_CEIL "ceil")])
21608
21609 (define_int_attr ROUNDING
21610 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
21611 (UNSPEC_FRNDINT_FLOOR "FLOOR")
21612 (UNSPEC_FRNDINT_CEIL "CEIL")
21613 (UNSPEC_FRNDINT_TRUNC "TRUNC")
21614 (UNSPEC_FIST_FLOOR "FLOOR")
21615 (UNSPEC_FIST_CEIL "CEIL")])
21616
21617 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21618 (define_insn_and_split "frndintxf2_<rounding>"
21619 [(set (match_operand:XF 0 "register_operand")
21620 (unspec:XF [(match_operand:XF 1 "register_operand")]
21621 FRNDINT_ROUNDING))
21622 (clobber (reg:CC FLAGS_REG))]
21623 "TARGET_USE_FANCY_MATH_387
21624 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
21625 && ix86_pre_reload_split ()"
21626 "#"
21627 "&& 1"
21628 [(const_int 0)]
21629 {
21630 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
21631
21632 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
21633 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
21634
21635 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
21636 operands[2], operands[3]));
21637 DONE;
21638 }
21639 [(set_attr "type" "frndint")
21640 (set_attr "i387_cw" "<rounding>")
21641 (set_attr "mode" "XF")])
21642
21643 (define_insn "frndintxf2_<rounding>_i387"
21644 [(set (match_operand:XF 0 "register_operand" "=f")
21645 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21646 FRNDINT_ROUNDING))
21647 (use (match_operand:HI 2 "memory_operand" "m"))
21648 (use (match_operand:HI 3 "memory_operand" "m"))]
21649 "TARGET_USE_FANCY_MATH_387
21650 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
21651 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
21652 [(set_attr "type" "frndint")
21653 (set_attr "i387_cw" "<rounding>")
21654 (set_attr "mode" "XF")])
21655
21656 (define_expand "<rounding_insn>xf2"
21657 [(parallel [(set (match_operand:XF 0 "register_operand")
21658 (unspec:XF [(match_operand:XF 1 "register_operand")]
21659 FRNDINT_ROUNDING))
21660 (clobber (reg:CC FLAGS_REG))])]
21661 "TARGET_USE_FANCY_MATH_387
21662 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
21663
21664 (define_expand "<rounding_insn>hf2"
21665 [(parallel [(set (match_operand:HF 0 "register_operand")
21666 (unspec:HF [(match_operand:HF 1 "register_operand")]
21667 FRNDINT_ROUNDING))
21668 (clobber (reg:CC FLAGS_REG))])]
21669 "TARGET_AVX512FP16"
21670 {
21671 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
21672 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
21673 DONE;
21674 })
21675
21676 (define_expand "<rounding_insn><mode>2"
21677 [(parallel [(set (match_operand:MODEF 0 "register_operand")
21678 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
21679 FRNDINT_ROUNDING))
21680 (clobber (reg:CC FLAGS_REG))])]
21681 "(TARGET_USE_FANCY_MATH_387
21682 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21683 || TARGET_MIX_SSE_I387)
21684 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21685 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21686 && (TARGET_SSE4_1
21687 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
21688 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
21689 {
21690 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21691 && (TARGET_SSE4_1
21692 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
21693 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
21694 {
21695 if (TARGET_SSE4_1)
21696 emit_insn (gen_sse4_1_round<mode>2
21697 (operands[0], operands[1],
21698 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
21699 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21700 {
21701 if (ROUND_<ROUNDING> == ROUND_FLOOR)
21702 ix86_expand_floorceil (operands[0], operands[1], true);
21703 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21704 ix86_expand_floorceil (operands[0], operands[1], false);
21705 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
21706 ix86_expand_trunc (operands[0], operands[1]);
21707 else
21708 gcc_unreachable ();
21709 }
21710 else
21711 {
21712 if (ROUND_<ROUNDING> == ROUND_FLOOR)
21713 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
21714 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21715 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
21716 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
21717 ix86_expand_truncdf_32 (operands[0], operands[1]);
21718 else
21719 gcc_unreachable ();
21720 }
21721 }
21722 else
21723 {
21724 rtx op0 = gen_reg_rtx (XFmode);
21725 rtx op1 = gen_reg_rtx (XFmode);
21726
21727 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21728 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
21729 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21730 }
21731 DONE;
21732 })
21733
21734 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21735 (define_insn_and_split "*fist<mode>2_<rounding>_1"
21736 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
21737 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
21738 FIST_ROUNDING))
21739 (clobber (reg:CC FLAGS_REG))]
21740 "TARGET_USE_FANCY_MATH_387
21741 && flag_unsafe_math_optimizations
21742 && ix86_pre_reload_split ()"
21743 "#"
21744 "&& 1"
21745 [(const_int 0)]
21746 {
21747 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
21748
21749 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
21750 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
21751
21752 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
21753 operands[2], operands[3]));
21754 DONE;
21755 }
21756 [(set_attr "type" "fistp")
21757 (set_attr "i387_cw" "<rounding>")
21758 (set_attr "mode" "<MODE>")])
21759
21760 (define_insn "fistdi2_<rounding>"
21761 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21762 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21763 FIST_ROUNDING))
21764 (use (match_operand:HI 2 "memory_operand" "m"))
21765 (use (match_operand:HI 3 "memory_operand" "m"))
21766 (clobber (match_scratch:XF 4 "=&f"))]
21767 "TARGET_USE_FANCY_MATH_387
21768 && flag_unsafe_math_optimizations"
21769 "* return output_fix_trunc (insn, operands, false);"
21770 [(set_attr "type" "fistp")
21771 (set_attr "i387_cw" "<rounding>")
21772 (set_attr "mode" "DI")])
21773
21774 (define_insn "fist<mode>2_<rounding>"
21775 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21776 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21777 FIST_ROUNDING))
21778 (use (match_operand:HI 2 "memory_operand" "m"))
21779 (use (match_operand:HI 3 "memory_operand" "m"))]
21780 "TARGET_USE_FANCY_MATH_387
21781 && flag_unsafe_math_optimizations"
21782 "* return output_fix_trunc (insn, operands, false);"
21783 [(set_attr "type" "fistp")
21784 (set_attr "i387_cw" "<rounding>")
21785 (set_attr "mode" "<MODE>")])
21786
21787 (define_expand "l<rounding_insn>xf<mode>2"
21788 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
21789 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
21790 FIST_ROUNDING))
21791 (clobber (reg:CC FLAGS_REG))])]
21792 "TARGET_USE_FANCY_MATH_387
21793 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
21794 && flag_unsafe_math_optimizations")
21795
21796 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
21797 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
21798 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
21799 FIST_ROUNDING))
21800 (clobber (reg:CC FLAGS_REG))])]
21801 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
21802 && (TARGET_SSE4_1 || !flag_trapping_math)"
21803 {
21804 if (TARGET_SSE4_1)
21805 {
21806 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
21807
21808 emit_insn (gen_sse4_1_round<MODEF:mode>2
21809 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
21810 | ROUND_NO_EXC)));
21811 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
21812 (operands[0], tmp));
21813 }
21814 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
21815 ix86_expand_lfloorceil (operands[0], operands[1], true);
21816 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21817 ix86_expand_lfloorceil (operands[0], operands[1], false);
21818 else
21819 gcc_unreachable ();
21820
21821 DONE;
21822 })
21823
21824 (define_insn "fxam<mode>2_i387"
21825 [(set (match_operand:HI 0 "register_operand" "=a")
21826 (unspec:HI
21827 [(match_operand:X87MODEF 1 "register_operand" "f")]
21828 UNSPEC_FXAM))]
21829 "TARGET_USE_FANCY_MATH_387"
21830 "fxam\n\tfnstsw\t%0"
21831 [(set_attr "type" "multi")
21832 (set_attr "length" "4")
21833 (set_attr "unit" "i387")
21834 (set_attr "mode" "<MODE>")])
21835
21836 (define_expand "signbittf2"
21837 [(use (match_operand:SI 0 "register_operand"))
21838 (use (match_operand:TF 1 "register_operand"))]
21839 "TARGET_SSE"
21840 {
21841 if (TARGET_SSE4_1)
21842 {
21843 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
21844 rtx scratch = gen_reg_rtx (QImode);
21845
21846 emit_insn (gen_ptesttf2 (operands[1], mask));
21847 ix86_expand_setcc (scratch, NE,
21848 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
21849
21850 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
21851 }
21852 else
21853 {
21854 emit_insn (gen_sse_movmskps (operands[0],
21855 gen_lowpart (V4SFmode, operands[1])));
21856 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
21857 }
21858 DONE;
21859 })
21860
21861 (define_expand "signbitxf2"
21862 [(use (match_operand:SI 0 "register_operand"))
21863 (use (match_operand:XF 1 "register_operand"))]
21864 "TARGET_USE_FANCY_MATH_387"
21865 {
21866 rtx scratch = gen_reg_rtx (HImode);
21867
21868 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
21869 emit_insn (gen_andsi3 (operands[0],
21870 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
21871 DONE;
21872 })
21873
21874 (define_insn "movmsk_df"
21875 [(set (match_operand:SI 0 "register_operand" "=r")
21876 (unspec:SI
21877 [(match_operand:DF 1 "register_operand" "x")]
21878 UNSPEC_MOVMSK))]
21879 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
21880 "%vmovmskpd\t{%1, %0|%0, %1}"
21881 [(set_attr "type" "ssemov")
21882 (set_attr "prefix" "maybe_vex")
21883 (set_attr "mode" "DF")])
21884
21885 ;; Use movmskpd in SSE mode to avoid store forwarding stall
21886 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
21887 (define_expand "signbitdf2"
21888 [(use (match_operand:SI 0 "register_operand"))
21889 (use (match_operand:DF 1 "register_operand"))]
21890 "TARGET_USE_FANCY_MATH_387
21891 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
21892 {
21893 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
21894 {
21895 emit_insn (gen_movmsk_df (operands[0], operands[1]));
21896 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
21897 }
21898 else
21899 {
21900 rtx scratch = gen_reg_rtx (HImode);
21901
21902 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
21903 emit_insn (gen_andsi3 (operands[0],
21904 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
21905 }
21906 DONE;
21907 })
21908
21909 (define_expand "signbitsf2"
21910 [(use (match_operand:SI 0 "register_operand"))
21911 (use (match_operand:SF 1 "register_operand"))]
21912 "TARGET_USE_FANCY_MATH_387
21913 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
21914 {
21915 rtx scratch = gen_reg_rtx (HImode);
21916
21917 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
21918 emit_insn (gen_andsi3 (operands[0],
21919 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
21920 DONE;
21921 })
21922 \f
21923 ;; Block operation instructions
21924
21925 (define_insn "cld"
21926 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
21927 ""
21928 "cld"
21929 [(set_attr "length" "1")
21930 (set_attr "length_immediate" "0")
21931 (set_attr "modrm" "0")])
21932
21933 (define_expand "cpymem<mode>"
21934 [(use (match_operand:BLK 0 "memory_operand"))
21935 (use (match_operand:BLK 1 "memory_operand"))
21936 (use (match_operand:SWI48 2 "nonmemory_operand"))
21937 (use (match_operand:SWI48 3 "const_int_operand"))
21938 (use (match_operand:SI 4 "const_int_operand"))
21939 (use (match_operand:SI 5 "const_int_operand"))
21940 (use (match_operand:SI 6 ""))
21941 (use (match_operand:SI 7 ""))
21942 (use (match_operand:SI 8 ""))]
21943 ""
21944 {
21945 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
21946 operands[2], NULL, operands[3],
21947 operands[4], operands[5],
21948 operands[6], operands[7],
21949 operands[8], false))
21950 DONE;
21951 else
21952 FAIL;
21953 })
21954
21955 ;; Most CPUs don't like single string operations
21956 ;; Handle this case here to simplify previous expander.
21957
21958 (define_expand "strmov"
21959 [(set (match_dup 4) (match_operand 3 "memory_operand"))
21960 (set (match_operand 1 "memory_operand") (match_dup 4))
21961 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
21962 (clobber (reg:CC FLAGS_REG))])
21963 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
21964 (clobber (reg:CC FLAGS_REG))])]
21965 ""
21966 {
21967 /* Can't use this for non-default address spaces. */
21968 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
21969 FAIL;
21970
21971 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
21972
21973 /* If .md ever supports :P for Pmode, these can be directly
21974 in the pattern above. */
21975 operands[5] = plus_constant (Pmode, operands[0], piece_size);
21976 operands[6] = plus_constant (Pmode, operands[2], piece_size);
21977
21978 /* Can't use this if the user has appropriated esi or edi. */
21979 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
21980 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
21981 {
21982 emit_insn (gen_strmov_singleop (operands[0], operands[1],
21983 operands[2], operands[3],
21984 operands[5], operands[6]));
21985 DONE;
21986 }
21987
21988 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
21989 })
21990
21991 (define_expand "strmov_singleop"
21992 [(parallel [(set (match_operand 1 "memory_operand")
21993 (match_operand 3 "memory_operand"))
21994 (set (match_operand 0 "register_operand")
21995 (match_operand 4))
21996 (set (match_operand 2 "register_operand")
21997 (match_operand 5))])]
21998 ""
21999 {
22000 if (TARGET_CLD)
22001 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22002 })
22003
22004 (define_insn "*strmovdi_rex_1"
22005 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22006 (mem:DI (match_operand:P 3 "register_operand" "1")))
22007 (set (match_operand:P 0 "register_operand" "=D")
22008 (plus:P (match_dup 2)
22009 (const_int 8)))
22010 (set (match_operand:P 1 "register_operand" "=S")
22011 (plus:P (match_dup 3)
22012 (const_int 8)))]
22013 "TARGET_64BIT
22014 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22015 && ix86_check_no_addr_space (insn)"
22016 "%^movsq"
22017 [(set_attr "type" "str")
22018 (set_attr "memory" "both")
22019 (set_attr "mode" "DI")])
22020
22021 (define_insn "*strmovsi_1"
22022 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22023 (mem:SI (match_operand:P 3 "register_operand" "1")))
22024 (set (match_operand:P 0 "register_operand" "=D")
22025 (plus:P (match_dup 2)
22026 (const_int 4)))
22027 (set (match_operand:P 1 "register_operand" "=S")
22028 (plus:P (match_dup 3)
22029 (const_int 4)))]
22030 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22031 && ix86_check_no_addr_space (insn)"
22032 "%^movs{l|d}"
22033 [(set_attr "type" "str")
22034 (set_attr "memory" "both")
22035 (set_attr "mode" "SI")])
22036
22037 (define_insn "*strmovhi_1"
22038 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22039 (mem:HI (match_operand:P 3 "register_operand" "1")))
22040 (set (match_operand:P 0 "register_operand" "=D")
22041 (plus:P (match_dup 2)
22042 (const_int 2)))
22043 (set (match_operand:P 1 "register_operand" "=S")
22044 (plus:P (match_dup 3)
22045 (const_int 2)))]
22046 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22047 && ix86_check_no_addr_space (insn)"
22048 "%^movsw"
22049 [(set_attr "type" "str")
22050 (set_attr "memory" "both")
22051 (set_attr "mode" "HI")])
22052
22053 (define_insn "*strmovqi_1"
22054 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22055 (mem:QI (match_operand:P 3 "register_operand" "1")))
22056 (set (match_operand:P 0 "register_operand" "=D")
22057 (plus:P (match_dup 2)
22058 (const_int 1)))
22059 (set (match_operand:P 1 "register_operand" "=S")
22060 (plus:P (match_dup 3)
22061 (const_int 1)))]
22062 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22063 && ix86_check_no_addr_space (insn)"
22064 "%^movsb"
22065 [(set_attr "type" "str")
22066 (set_attr "memory" "both")
22067 (set (attr "prefix_rex")
22068 (if_then_else
22069 (match_test "<P:MODE>mode == DImode")
22070 (const_string "0")
22071 (const_string "*")))
22072 (set_attr "mode" "QI")])
22073
22074 (define_expand "rep_mov"
22075 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22076 (set (match_operand 0 "register_operand")
22077 (match_operand 5))
22078 (set (match_operand 2 "register_operand")
22079 (match_operand 6))
22080 (set (match_operand 1 "memory_operand")
22081 (match_operand 3 "memory_operand"))
22082 (use (match_dup 4))])]
22083 ""
22084 {
22085 if (TARGET_CLD)
22086 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22087 })
22088
22089 (define_insn "*rep_movdi_rex64"
22090 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22091 (set (match_operand:P 0 "register_operand" "=D")
22092 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22093 (const_int 3))
22094 (match_operand:P 3 "register_operand" "0")))
22095 (set (match_operand:P 1 "register_operand" "=S")
22096 (plus:P (ashift:P (match_dup 5) (const_int 3))
22097 (match_operand:P 4 "register_operand" "1")))
22098 (set (mem:BLK (match_dup 3))
22099 (mem:BLK (match_dup 4)))
22100 (use (match_dup 5))]
22101 "TARGET_64BIT
22102 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22103 && ix86_check_no_addr_space (insn)"
22104 "%^rep{%;} movsq"
22105 [(set_attr "type" "str")
22106 (set_attr "prefix_rep" "1")
22107 (set_attr "memory" "both")
22108 (set_attr "mode" "DI")])
22109
22110 (define_insn "*rep_movsi"
22111 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22112 (set (match_operand:P 0 "register_operand" "=D")
22113 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22114 (const_int 2))
22115 (match_operand:P 3 "register_operand" "0")))
22116 (set (match_operand:P 1 "register_operand" "=S")
22117 (plus:P (ashift:P (match_dup 5) (const_int 2))
22118 (match_operand:P 4 "register_operand" "1")))
22119 (set (mem:BLK (match_dup 3))
22120 (mem:BLK (match_dup 4)))
22121 (use (match_dup 5))]
22122 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22123 && ix86_check_no_addr_space (insn)"
22124 "%^rep{%;} movs{l|d}"
22125 [(set_attr "type" "str")
22126 (set_attr "prefix_rep" "1")
22127 (set_attr "memory" "both")
22128 (set_attr "mode" "SI")])
22129
22130 (define_insn "*rep_movqi"
22131 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22132 (set (match_operand:P 0 "register_operand" "=D")
22133 (plus:P (match_operand:P 3 "register_operand" "0")
22134 (match_operand:P 5 "register_operand" "2")))
22135 (set (match_operand:P 1 "register_operand" "=S")
22136 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22137 (set (mem:BLK (match_dup 3))
22138 (mem:BLK (match_dup 4)))
22139 (use (match_dup 5))]
22140 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22141 && ix86_check_no_addr_space (insn)"
22142 "%^rep{%;} movsb"
22143 [(set_attr "type" "str")
22144 (set_attr "prefix_rep" "1")
22145 (set_attr "memory" "both")
22146 (set_attr "mode" "QI")])
22147
22148 (define_expand "setmem<mode>"
22149 [(use (match_operand:BLK 0 "memory_operand"))
22150 (use (match_operand:SWI48 1 "nonmemory_operand"))
22151 (use (match_operand:QI 2 "nonmemory_operand"))
22152 (use (match_operand 3 "const_int_operand"))
22153 (use (match_operand:SI 4 "const_int_operand"))
22154 (use (match_operand:SI 5 "const_int_operand"))
22155 (use (match_operand:SI 6 ""))
22156 (use (match_operand:SI 7 ""))
22157 (use (match_operand:SI 8 ""))]
22158 ""
22159 {
22160 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22161 operands[1], operands[2],
22162 operands[3], operands[4],
22163 operands[5], operands[6],
22164 operands[7], operands[8], true))
22165 DONE;
22166 else
22167 FAIL;
22168 })
22169
22170 ;; Most CPUs don't like single string operations
22171 ;; Handle this case here to simplify previous expander.
22172
22173 (define_expand "strset"
22174 [(set (match_operand 1 "memory_operand")
22175 (match_operand 2 "register_operand"))
22176 (parallel [(set (match_operand 0 "register_operand")
22177 (match_dup 3))
22178 (clobber (reg:CC FLAGS_REG))])]
22179 ""
22180 {
22181 /* Can't use this for non-default address spaces. */
22182 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22183 FAIL;
22184
22185 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22186 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22187
22188 /* If .md ever supports :P for Pmode, this can be directly
22189 in the pattern above. */
22190 operands[3] = plus_constant (Pmode, operands[0],
22191 GET_MODE_SIZE (GET_MODE (operands[2])));
22192
22193 /* Can't use this if the user has appropriated eax or edi. */
22194 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22195 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22196 {
22197 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22198 operands[3]));
22199 DONE;
22200 }
22201 })
22202
22203 (define_expand "strset_singleop"
22204 [(parallel [(set (match_operand 1 "memory_operand")
22205 (match_operand 2 "register_operand"))
22206 (set (match_operand 0 "register_operand")
22207 (match_operand 3))
22208 (unspec [(const_int 0)] UNSPEC_STOS)])]
22209 ""
22210 {
22211 if (TARGET_CLD)
22212 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22213 })
22214
22215 (define_insn "*strsetdi_rex_1"
22216 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22217 (match_operand:DI 2 "register_operand" "a"))
22218 (set (match_operand:P 0 "register_operand" "=D")
22219 (plus:P (match_dup 1)
22220 (const_int 8)))
22221 (unspec [(const_int 0)] UNSPEC_STOS)]
22222 "TARGET_64BIT
22223 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22224 && ix86_check_no_addr_space (insn)"
22225 "%^stosq"
22226 [(set_attr "type" "str")
22227 (set_attr "memory" "store")
22228 (set_attr "mode" "DI")])
22229
22230 (define_insn "*strsetsi_1"
22231 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22232 (match_operand:SI 2 "register_operand" "a"))
22233 (set (match_operand:P 0 "register_operand" "=D")
22234 (plus:P (match_dup 1)
22235 (const_int 4)))
22236 (unspec [(const_int 0)] UNSPEC_STOS)]
22237 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22238 && ix86_check_no_addr_space (insn)"
22239 "%^stos{l|d}"
22240 [(set_attr "type" "str")
22241 (set_attr "memory" "store")
22242 (set_attr "mode" "SI")])
22243
22244 (define_insn "*strsethi_1"
22245 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22246 (match_operand:HI 2 "register_operand" "a"))
22247 (set (match_operand:P 0 "register_operand" "=D")
22248 (plus:P (match_dup 1)
22249 (const_int 2)))
22250 (unspec [(const_int 0)] UNSPEC_STOS)]
22251 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22252 && ix86_check_no_addr_space (insn)"
22253 "%^stosw"
22254 [(set_attr "type" "str")
22255 (set_attr "memory" "store")
22256 (set_attr "mode" "HI")])
22257
22258 (define_insn "*strsetqi_1"
22259 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22260 (match_operand:QI 2 "register_operand" "a"))
22261 (set (match_operand:P 0 "register_operand" "=D")
22262 (plus:P (match_dup 1)
22263 (const_int 1)))
22264 (unspec [(const_int 0)] UNSPEC_STOS)]
22265 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22266 && ix86_check_no_addr_space (insn)"
22267 "%^stosb"
22268 [(set_attr "type" "str")
22269 (set_attr "memory" "store")
22270 (set (attr "prefix_rex")
22271 (if_then_else
22272 (match_test "<P:MODE>mode == DImode")
22273 (const_string "0")
22274 (const_string "*")))
22275 (set_attr "mode" "QI")])
22276
22277 (define_expand "rep_stos"
22278 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22279 (set (match_operand 0 "register_operand")
22280 (match_operand 4))
22281 (set (match_operand 2 "memory_operand") (const_int 0))
22282 (use (match_operand 3 "register_operand"))
22283 (use (match_dup 1))])]
22284 ""
22285 {
22286 if (TARGET_CLD)
22287 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22288 })
22289
22290 (define_insn "*rep_stosdi_rex64"
22291 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22292 (set (match_operand:P 0 "register_operand" "=D")
22293 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22294 (const_int 3))
22295 (match_operand:P 3 "register_operand" "0")))
22296 (set (mem:BLK (match_dup 3))
22297 (const_int 0))
22298 (use (match_operand:DI 2 "register_operand" "a"))
22299 (use (match_dup 4))]
22300 "TARGET_64BIT
22301 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22302 && ix86_check_no_addr_space (insn)"
22303 "%^rep{%;} stosq"
22304 [(set_attr "type" "str")
22305 (set_attr "prefix_rep" "1")
22306 (set_attr "memory" "store")
22307 (set_attr "mode" "DI")])
22308
22309 (define_insn "*rep_stossi"
22310 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22311 (set (match_operand:P 0 "register_operand" "=D")
22312 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22313 (const_int 2))
22314 (match_operand:P 3 "register_operand" "0")))
22315 (set (mem:BLK (match_dup 3))
22316 (const_int 0))
22317 (use (match_operand:SI 2 "register_operand" "a"))
22318 (use (match_dup 4))]
22319 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22320 && ix86_check_no_addr_space (insn)"
22321 "%^rep{%;} stos{l|d}"
22322 [(set_attr "type" "str")
22323 (set_attr "prefix_rep" "1")
22324 (set_attr "memory" "store")
22325 (set_attr "mode" "SI")])
22326
22327 (define_insn "*rep_stosqi"
22328 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22329 (set (match_operand:P 0 "register_operand" "=D")
22330 (plus:P (match_operand:P 3 "register_operand" "0")
22331 (match_operand:P 4 "register_operand" "1")))
22332 (set (mem:BLK (match_dup 3))
22333 (const_int 0))
22334 (use (match_operand:QI 2 "register_operand" "a"))
22335 (use (match_dup 4))]
22336 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22337 && ix86_check_no_addr_space (insn)"
22338 "%^rep{%;} stosb"
22339 [(set_attr "type" "str")
22340 (set_attr "prefix_rep" "1")
22341 (set_attr "memory" "store")
22342 (set (attr "prefix_rex")
22343 (if_then_else
22344 (match_test "<P:MODE>mode == DImode")
22345 (const_string "0")
22346 (const_string "*")))
22347 (set_attr "mode" "QI")])
22348
22349 (define_expand "cmpmemsi"
22350 [(set (match_operand:SI 0 "register_operand" "")
22351 (compare:SI (match_operand:BLK 1 "memory_operand" "")
22352 (match_operand:BLK 2 "memory_operand" "") ) )
22353 (use (match_operand 3 "general_operand"))
22354 (use (match_operand 4 "immediate_operand"))]
22355 ""
22356 {
22357 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22358 operands[2], operands[3],
22359 operands[4], false))
22360 DONE;
22361 else
22362 FAIL;
22363 })
22364
22365 (define_expand "cmpstrnsi"
22366 [(set (match_operand:SI 0 "register_operand")
22367 (compare:SI (match_operand:BLK 1 "general_operand")
22368 (match_operand:BLK 2 "general_operand")))
22369 (use (match_operand 3 "general_operand"))
22370 (use (match_operand 4 "immediate_operand"))]
22371 ""
22372 {
22373 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22374 operands[2], operands[3],
22375 operands[4], true))
22376 DONE;
22377 else
22378 FAIL;
22379 })
22380
22381 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
22382
22383 (define_expand "cmpintqi"
22384 [(set (match_dup 1)
22385 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22386 (set (match_dup 2)
22387 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22388 (parallel [(set (match_operand:QI 0 "register_operand")
22389 (minus:QI (match_dup 1)
22390 (match_dup 2)))
22391 (clobber (reg:CC FLAGS_REG))])]
22392 ""
22393 {
22394 operands[1] = gen_reg_rtx (QImode);
22395 operands[2] = gen_reg_rtx (QImode);
22396 })
22397
22398 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
22399 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
22400
22401 (define_expand "cmpstrnqi_nz_1"
22402 [(parallel [(set (reg:CC FLAGS_REG)
22403 (compare:CC (match_operand 4 "memory_operand")
22404 (match_operand 5 "memory_operand")))
22405 (use (match_operand 2 "register_operand"))
22406 (use (match_operand:SI 3 "immediate_operand"))
22407 (clobber (match_operand 0 "register_operand"))
22408 (clobber (match_operand 1 "register_operand"))
22409 (clobber (match_dup 2))])]
22410 ""
22411 {
22412 if (TARGET_CLD)
22413 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22414 })
22415
22416 (define_insn "*cmpstrnqi_nz_1"
22417 [(set (reg:CC FLAGS_REG)
22418 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22419 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
22420 (use (match_operand:P 6 "register_operand" "2"))
22421 (use (match_operand:SI 3 "immediate_operand" "i"))
22422 (clobber (match_operand:P 0 "register_operand" "=S"))
22423 (clobber (match_operand:P 1 "register_operand" "=D"))
22424 (clobber (match_operand:P 2 "register_operand" "=c"))]
22425 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22426 && ix86_check_no_addr_space (insn)"
22427 "%^repz{%;} cmpsb"
22428 [(set_attr "type" "str")
22429 (set_attr "mode" "QI")
22430 (set (attr "prefix_rex")
22431 (if_then_else
22432 (match_test "<P:MODE>mode == DImode")
22433 (const_string "0")
22434 (const_string "*")))
22435 (set_attr "prefix_rep" "1")])
22436
22437 ;; The same, but the count is not known to not be zero.
22438
22439 (define_expand "cmpstrnqi_1"
22440 [(parallel [(set (reg:CC FLAGS_REG)
22441 (if_then_else:CC (ne (match_operand 2 "register_operand")
22442 (const_int 0))
22443 (compare:CC (match_operand 4 "memory_operand")
22444 (match_operand 5 "memory_operand"))
22445 (const_int 0)))
22446 (use (match_operand:SI 3 "immediate_operand"))
22447 (use (reg:CC FLAGS_REG))
22448 (clobber (match_operand 0 "register_operand"))
22449 (clobber (match_operand 1 "register_operand"))
22450 (clobber (match_dup 2))])]
22451 ""
22452 {
22453 if (TARGET_CLD)
22454 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22455 })
22456
22457 (define_insn "*cmpstrnqi_1"
22458 [(set (reg:CC FLAGS_REG)
22459 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
22460 (const_int 0))
22461 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22462 (mem:BLK (match_operand:P 5 "register_operand" "1")))
22463 (const_int 0)))
22464 (use (match_operand:SI 3 "immediate_operand" "i"))
22465 (use (reg:CC FLAGS_REG))
22466 (clobber (match_operand:P 0 "register_operand" "=S"))
22467 (clobber (match_operand:P 1 "register_operand" "=D"))
22468 (clobber (match_operand:P 2 "register_operand" "=c"))]
22469 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22470 && ix86_check_no_addr_space (insn)"
22471 "%^repz{%;} cmpsb"
22472 [(set_attr "type" "str")
22473 (set_attr "mode" "QI")
22474 (set (attr "prefix_rex")
22475 (if_then_else
22476 (match_test "<P:MODE>mode == DImode")
22477 (const_string "0")
22478 (const_string "*")))
22479 (set_attr "prefix_rep" "1")])
22480
22481 (define_expand "strlen<mode>"
22482 [(set (match_operand:P 0 "register_operand")
22483 (unspec:P [(match_operand:BLK 1 "general_operand")
22484 (match_operand:QI 2 "immediate_operand")
22485 (match_operand 3 "immediate_operand")]
22486 UNSPEC_SCAS))]
22487 ""
22488 {
22489 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
22490 DONE;
22491 else
22492 FAIL;
22493 })
22494
22495 (define_expand "strlenqi_1"
22496 [(parallel [(set (match_operand 0 "register_operand")
22497 (match_operand 2))
22498 (clobber (match_operand 1 "register_operand"))
22499 (clobber (reg:CC FLAGS_REG))])]
22500 ""
22501 {
22502 if (TARGET_CLD)
22503 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22504 })
22505
22506 (define_insn "*strlenqi_1"
22507 [(set (match_operand:P 0 "register_operand" "=&c")
22508 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
22509 (match_operand:QI 2 "register_operand" "a")
22510 (match_operand:P 3 "immediate_operand" "i")
22511 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
22512 (clobber (match_operand:P 1 "register_operand" "=D"))
22513 (clobber (reg:CC FLAGS_REG))]
22514 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22515 && ix86_check_no_addr_space (insn)"
22516 "%^repnz{%;} scasb"
22517 [(set_attr "type" "str")
22518 (set_attr "mode" "QI")
22519 (set (attr "prefix_rex")
22520 (if_then_else
22521 (match_test "<P:MODE>mode == DImode")
22522 (const_string "0")
22523 (const_string "*")))
22524 (set_attr "prefix_rep" "1")])
22525
22526 ;; Peephole optimizations to clean up after cmpstrn*. This should be
22527 ;; handled in combine, but it is not currently up to the task.
22528 ;; When used for their truth value, the cmpstrn* expanders generate
22529 ;; code like this:
22530 ;;
22531 ;; repz cmpsb
22532 ;; seta %al
22533 ;; setb %dl
22534 ;; cmpb %al, %dl
22535 ;; jcc label
22536 ;;
22537 ;; The intermediate three instructions are unnecessary.
22538
22539 ;; This one handles cmpstrn*_nz_1...
22540 (define_peephole2
22541 [(parallel[
22542 (set (reg:CC FLAGS_REG)
22543 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22544 (mem:BLK (match_operand 5 "register_operand"))))
22545 (use (match_operand 6 "register_operand"))
22546 (use (match_operand:SI 3 "immediate_operand"))
22547 (clobber (match_operand 0 "register_operand"))
22548 (clobber (match_operand 1 "register_operand"))
22549 (clobber (match_operand 2 "register_operand"))])
22550 (set (match_operand:QI 7 "register_operand")
22551 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22552 (set (match_operand:QI 8 "register_operand")
22553 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22554 (set (reg FLAGS_REG)
22555 (compare (match_dup 7) (match_dup 8)))
22556 ]
22557 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22558 [(parallel[
22559 (set (reg:CC FLAGS_REG)
22560 (compare:CC (mem:BLK (match_dup 4))
22561 (mem:BLK (match_dup 5))))
22562 (use (match_dup 6))
22563 (use (match_dup 3))
22564 (clobber (match_dup 0))
22565 (clobber (match_dup 1))
22566 (clobber (match_dup 2))])])
22567
22568 ;; ...and this one handles cmpstrn*_1.
22569 (define_peephole2
22570 [(parallel[
22571 (set (reg:CC FLAGS_REG)
22572 (if_then_else:CC (ne (match_operand 6 "register_operand")
22573 (const_int 0))
22574 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22575 (mem:BLK (match_operand 5 "register_operand")))
22576 (const_int 0)))
22577 (use (match_operand:SI 3 "immediate_operand"))
22578 (use (reg:CC FLAGS_REG))
22579 (clobber (match_operand 0 "register_operand"))
22580 (clobber (match_operand 1 "register_operand"))
22581 (clobber (match_operand 2 "register_operand"))])
22582 (set (match_operand:QI 7 "register_operand")
22583 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22584 (set (match_operand:QI 8 "register_operand")
22585 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22586 (set (reg FLAGS_REG)
22587 (compare (match_dup 7) (match_dup 8)))
22588 ]
22589 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22590 [(parallel[
22591 (set (reg:CC FLAGS_REG)
22592 (if_then_else:CC (ne (match_dup 6)
22593 (const_int 0))
22594 (compare:CC (mem:BLK (match_dup 4))
22595 (mem:BLK (match_dup 5)))
22596 (const_int 0)))
22597 (use (match_dup 3))
22598 (use (reg:CC FLAGS_REG))
22599 (clobber (match_dup 0))
22600 (clobber (match_dup 1))
22601 (clobber (match_dup 2))])])
22602 \f
22603 ;; Conditional move instructions.
22604
22605 (define_expand "mov<mode>cc"
22606 [(set (match_operand:SWIM 0 "register_operand")
22607 (if_then_else:SWIM (match_operand 1 "comparison_operator")
22608 (match_operand:SWIM 2 "<general_operand>")
22609 (match_operand:SWIM 3 "<general_operand>")))]
22610 ""
22611 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
22612
22613 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
22614 ;; the register first winds up with `sbbl $0,reg', which is also weird.
22615 ;; So just document what we're doing explicitly.
22616
22617 (define_expand "x86_mov<mode>cc_0_m1"
22618 [(parallel
22619 [(set (match_operand:SWI48 0 "register_operand")
22620 (if_then_else:SWI48
22621 (match_operator:SWI48 2 "ix86_carry_flag_operator"
22622 [(match_operand 1 "flags_reg_operand")
22623 (const_int 0)])
22624 (const_int -1)
22625 (const_int 0)))
22626 (clobber (reg:CC FLAGS_REG))])])
22627
22628 (define_insn "*x86_mov<mode>cc_0_m1"
22629 [(set (match_operand:SWI48 0 "register_operand" "=r")
22630 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
22631 [(reg FLAGS_REG) (const_int 0)])
22632 (const_int -1)
22633 (const_int 0)))
22634 (clobber (reg:CC FLAGS_REG))]
22635 ""
22636 "sbb{<imodesuffix>}\t%0, %0"
22637 [(set_attr "type" "alu1")
22638 (set_attr "use_carry" "1")
22639 (set_attr "pent_pair" "pu")
22640 (set_attr "mode" "<MODE>")
22641 (set_attr "length_immediate" "0")])
22642
22643 (define_insn "*x86_mov<mode>cc_0_m1_se"
22644 [(set (match_operand:SWI48 0 "register_operand" "=r")
22645 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
22646 [(reg FLAGS_REG) (const_int 0)])
22647 (const_int 1)
22648 (const_int 0)))
22649 (clobber (reg:CC FLAGS_REG))]
22650 ""
22651 "sbb{<imodesuffix>}\t%0, %0"
22652 [(set_attr "type" "alu1")
22653 (set_attr "use_carry" "1")
22654 (set_attr "pent_pair" "pu")
22655 (set_attr "mode" "<MODE>")
22656 (set_attr "length_immediate" "0")])
22657
22658 (define_insn "*x86_mov<mode>cc_0_m1_neg"
22659 [(set (match_operand:SWI 0 "register_operand" "=<r>")
22660 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
22661 [(reg FLAGS_REG) (const_int 0)])))
22662 (clobber (reg:CC FLAGS_REG))]
22663 ""
22664 "sbb{<imodesuffix>}\t%0, %0"
22665 [(set_attr "type" "alu1")
22666 (set_attr "use_carry" "1")
22667 (set_attr "pent_pair" "pu")
22668 (set_attr "mode" "<MODE>")
22669 (set_attr "length_immediate" "0")])
22670
22671 (define_expand "x86_mov<mode>cc_0_m1_neg"
22672 [(parallel
22673 [(set (match_operand:SWI48 0 "register_operand")
22674 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
22675 (clobber (reg:CC FLAGS_REG))])])
22676
22677 (define_split
22678 [(set (match_operand:SWI48 0 "register_operand")
22679 (neg:SWI48
22680 (leu:SWI48
22681 (match_operand 1 "int_nonimmediate_operand")
22682 (match_operand 2 "const_int_operand"))))]
22683 "x86_64_immediate_operand (operands[2], VOIDmode)
22684 && INTVAL (operands[2]) != -1
22685 && INTVAL (operands[2]) != 2147483647"
22686 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
22687 (set (match_dup 0)
22688 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
22689 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
22690
22691 (define_split
22692 [(set (match_operand:SWI 0 "register_operand")
22693 (neg:SWI
22694 (eq:SWI
22695 (match_operand 1 "int_nonimmediate_operand")
22696 (const_int 0))))]
22697 ""
22698 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
22699 (set (match_dup 0)
22700 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
22701
22702 (define_split
22703 [(set (match_operand:SWI 0 "register_operand")
22704 (neg:SWI
22705 (ne:SWI
22706 (match_operand 1 "int_nonimmediate_operand")
22707 (const_int 0))))]
22708 ""
22709 [(set (reg:CCC FLAGS_REG)
22710 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
22711 (set (match_dup 0)
22712 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
22713
22714 (define_insn "*mov<mode>cc_noc"
22715 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
22716 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22717 [(reg FLAGS_REG) (const_int 0)])
22718 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
22719 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
22720 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22721 "@
22722 cmov%O2%C1\t{%2, %0|%0, %2}
22723 cmov%O2%c1\t{%3, %0|%0, %3}"
22724 [(set_attr "type" "icmov")
22725 (set_attr "mode" "<MODE>")])
22726
22727 (define_insn "*movsicc_noc_zext"
22728 [(set (match_operand:DI 0 "register_operand" "=r,r")
22729 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
22730 [(reg FLAGS_REG) (const_int 0)])
22731 (zero_extend:DI
22732 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
22733 (zero_extend:DI
22734 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
22735 "TARGET_64BIT
22736 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22737 "@
22738 cmov%O2%C1\t{%2, %k0|%k0, %2}
22739 cmov%O2%c1\t{%3, %k0|%k0, %3}"
22740 [(set_attr "type" "icmov")
22741 (set_attr "mode" "SI")])
22742
22743 (define_insn "*movsicc_noc_zext_1"
22744 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
22745 (zero_extend:DI
22746 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
22747 [(reg FLAGS_REG) (const_int 0)])
22748 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
22749 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
22750 "TARGET_64BIT
22751 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22752 "@
22753 cmov%O2%C1\t{%2, %k0|%k0, %2}
22754 cmov%O2%c1\t{%3, %k0|%k0, %3}"
22755 [(set_attr "type" "icmov")
22756 (set_attr "mode" "SI")])
22757
22758
22759 ;; Don't do conditional moves with memory inputs. This splitter helps
22760 ;; register starved x86_32 by forcing inputs into registers before reload.
22761 (define_split
22762 [(set (match_operand:SWI248 0 "register_operand")
22763 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22764 [(reg FLAGS_REG) (const_int 0)])
22765 (match_operand:SWI248 2 "nonimmediate_operand")
22766 (match_operand:SWI248 3 "nonimmediate_operand")))]
22767 "!TARGET_64BIT && TARGET_CMOVE
22768 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22769 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22770 && can_create_pseudo_p ()
22771 && optimize_insn_for_speed_p ()"
22772 [(set (match_dup 0)
22773 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
22774 {
22775 operands[2] = force_reg (<MODE>mode, operands[2]);
22776 operands[3] = force_reg (<MODE>mode, operands[3]);
22777 })
22778
22779 (define_insn "*movqicc_noc"
22780 [(set (match_operand:QI 0 "register_operand" "=r,r")
22781 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
22782 [(reg FLAGS_REG) (const_int 0)])
22783 (match_operand:QI 2 "register_operand" "r,0")
22784 (match_operand:QI 3 "register_operand" "0,r")))]
22785 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
22786 "#"
22787 [(set_attr "type" "icmov")
22788 (set_attr "mode" "QI")])
22789
22790 (define_split
22791 [(set (match_operand:SWI12 0 "register_operand")
22792 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
22793 [(reg FLAGS_REG) (const_int 0)])
22794 (match_operand:SWI12 2 "register_operand")
22795 (match_operand:SWI12 3 "register_operand")))]
22796 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
22797 && reload_completed"
22798 [(set (match_dup 0)
22799 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
22800 {
22801 operands[0] = gen_lowpart (SImode, operands[0]);
22802 operands[2] = gen_lowpart (SImode, operands[2]);
22803 operands[3] = gen_lowpart (SImode, operands[3]);
22804 })
22805
22806 ;; Don't do conditional moves with memory inputs
22807 (define_peephole2
22808 [(match_scratch:SWI248 4 "r")
22809 (set (match_operand:SWI248 0 "register_operand")
22810 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22811 [(reg FLAGS_REG) (const_int 0)])
22812 (match_operand:SWI248 2 "nonimmediate_operand")
22813 (match_operand:SWI248 3 "nonimmediate_operand")))]
22814 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22815 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22816 && optimize_insn_for_speed_p ()"
22817 [(set (match_dup 4) (match_dup 5))
22818 (set (match_dup 0)
22819 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
22820 {
22821 if (MEM_P (operands[2]))
22822 {
22823 operands[5] = operands[2];
22824 operands[2] = operands[4];
22825 }
22826 else if (MEM_P (operands[3]))
22827 {
22828 operands[5] = operands[3];
22829 operands[3] = operands[4];
22830 }
22831 else
22832 gcc_unreachable ();
22833 })
22834
22835 (define_peephole2
22836 [(match_scratch:SI 4 "r")
22837 (set (match_operand:DI 0 "register_operand")
22838 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
22839 [(reg FLAGS_REG) (const_int 0)])
22840 (zero_extend:DI
22841 (match_operand:SI 2 "nonimmediate_operand"))
22842 (zero_extend:DI
22843 (match_operand:SI 3 "nonimmediate_operand"))))]
22844 "TARGET_64BIT
22845 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22846 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22847 && optimize_insn_for_speed_p ()"
22848 [(set (match_dup 4) (match_dup 5))
22849 (set (match_dup 0)
22850 (if_then_else:DI (match_dup 1)
22851 (zero_extend:DI (match_dup 2))
22852 (zero_extend:DI (match_dup 3))))]
22853 {
22854 if (MEM_P (operands[2]))
22855 {
22856 operands[5] = operands[2];
22857 operands[2] = operands[4];
22858 }
22859 else if (MEM_P (operands[3]))
22860 {
22861 operands[5] = operands[3];
22862 operands[3] = operands[4];
22863 }
22864 else
22865 gcc_unreachable ();
22866 })
22867
22868 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
22869 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
22870 (define_peephole2
22871 [(set (match_operand:SWI248 0 "general_reg_operand")
22872 (match_operand:SWI248 1 "general_reg_operand"))
22873 (parallel [(set (reg FLAGS_REG) (match_operand 5))
22874 (set (match_dup 0) (match_operand:SWI248 6))])
22875 (set (match_operand:SWI248 2 "general_reg_operand")
22876 (match_operand:SWI248 3 "general_gr_operand"))
22877 (set (match_dup 0)
22878 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
22879 [(reg FLAGS_REG) (const_int 0)])
22880 (match_dup 0)
22881 (match_dup 2)))]
22882 "TARGET_CMOVE
22883 && REGNO (operands[2]) != REGNO (operands[0])
22884 && REGNO (operands[2]) != REGNO (operands[1])
22885 && peep2_reg_dead_p (1, operands[1])
22886 && peep2_reg_dead_p (4, operands[2])
22887 && !reg_overlap_mentioned_p (operands[0], operands[3])"
22888 [(parallel [(set (match_dup 7) (match_dup 8))
22889 (set (match_dup 1) (match_dup 9))])
22890 (set (match_dup 0) (match_dup 3))
22891 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
22892 (match_dup 1)
22893 (match_dup 0)))]
22894 {
22895 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
22896 operands[8]
22897 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
22898 operands[9]
22899 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
22900 })
22901
22902 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
22903 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
22904 (define_peephole2
22905 [(set (match_operand:SWI248 2 "general_reg_operand")
22906 (match_operand:SWI248 3 "general_gr_operand"))
22907 (set (match_operand:SWI248 0 "general_reg_operand")
22908 (match_operand:SWI248 1 "general_reg_operand"))
22909 (parallel [(set (reg FLAGS_REG) (match_operand 5))
22910 (set (match_dup 0) (match_operand:SWI248 6))])
22911 (set (match_dup 0)
22912 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
22913 [(reg FLAGS_REG) (const_int 0)])
22914 (match_dup 0)
22915 (match_dup 2)))]
22916 "TARGET_CMOVE
22917 && REGNO (operands[2]) != REGNO (operands[0])
22918 && REGNO (operands[2]) != REGNO (operands[1])
22919 && peep2_reg_dead_p (2, operands[1])
22920 && peep2_reg_dead_p (4, operands[2])
22921 && !reg_overlap_mentioned_p (operands[0], operands[3])
22922 && !reg_mentioned_p (operands[2], operands[6])"
22923 [(parallel [(set (match_dup 7) (match_dup 8))
22924 (set (match_dup 1) (match_dup 9))])
22925 (set (match_dup 0) (match_dup 3))
22926 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
22927 (match_dup 1)
22928 (match_dup 0)))]
22929 {
22930 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
22931 operands[8]
22932 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
22933 operands[9]
22934 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
22935 })
22936
22937 (define_insn "movhf_mask"
22938 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
22939 (unspec:HF
22940 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
22941 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
22942 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
22943 UNSPEC_MOVCC_MASK))]
22944 "TARGET_AVX512FP16"
22945 "@
22946 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
22947 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
22948 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
22949 [(set_attr "type" "ssemov")
22950 (set_attr "prefix" "evex")
22951 (set_attr "mode" "HF")])
22952
22953 (define_expand "movhfcc"
22954 [(set (match_operand:HF 0 "register_operand")
22955 (if_then_else:HF
22956 (match_operand 1 "comparison_operator")
22957 (match_operand:HF 2 "register_operand")
22958 (match_operand:HF 3 "register_operand")))]
22959 "TARGET_AVX512FP16"
22960 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
22961
22962 (define_expand "mov<mode>cc"
22963 [(set (match_operand:X87MODEF 0 "register_operand")
22964 (if_then_else:X87MODEF
22965 (match_operand 1 "comparison_operator")
22966 (match_operand:X87MODEF 2 "register_operand")
22967 (match_operand:X87MODEF 3 "register_operand")))]
22968 "(TARGET_80387 && TARGET_CMOVE)
22969 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
22970 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
22971
22972 (define_insn "*movxfcc_1"
22973 [(set (match_operand:XF 0 "register_operand" "=f,f")
22974 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
22975 [(reg FLAGS_REG) (const_int 0)])
22976 (match_operand:XF 2 "register_operand" "f,0")
22977 (match_operand:XF 3 "register_operand" "0,f")))]
22978 "TARGET_80387 && TARGET_CMOVE"
22979 "@
22980 fcmov%F1\t{%2, %0|%0, %2}
22981 fcmov%f1\t{%3, %0|%0, %3}"
22982 [(set_attr "type" "fcmov")
22983 (set_attr "mode" "XF")])
22984
22985 (define_insn "*movdfcc_1"
22986 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
22987 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
22988 [(reg FLAGS_REG) (const_int 0)])
22989 (match_operand:DF 2 "nonimmediate_operand"
22990 "f ,0,rm,0 ,rm,0")
22991 (match_operand:DF 3 "nonimmediate_operand"
22992 "0 ,f,0 ,rm,0, rm")))]
22993 "TARGET_80387 && TARGET_CMOVE
22994 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22995 "@
22996 fcmov%F1\t{%2, %0|%0, %2}
22997 fcmov%f1\t{%3, %0|%0, %3}
22998 #
22999 #
23000 cmov%O2%C1\t{%2, %0|%0, %2}
23001 cmov%O2%c1\t{%3, %0|%0, %3}"
23002 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23003 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23004 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23005
23006 (define_split
23007 [(set (match_operand:DF 0 "general_reg_operand")
23008 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23009 [(reg FLAGS_REG) (const_int 0)])
23010 (match_operand:DF 2 "nonimmediate_operand")
23011 (match_operand:DF 3 "nonimmediate_operand")))]
23012 "!TARGET_64BIT && reload_completed"
23013 [(set (match_dup 2)
23014 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23015 (set (match_dup 3)
23016 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23017 {
23018 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23019 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23020 })
23021
23022 (define_insn "*movsfcc_1_387"
23023 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23024 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23025 [(reg FLAGS_REG) (const_int 0)])
23026 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23027 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23028 "TARGET_80387 && TARGET_CMOVE
23029 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23030 "@
23031 fcmov%F1\t{%2, %0|%0, %2}
23032 fcmov%f1\t{%3, %0|%0, %3}
23033 cmov%O2%C1\t{%2, %0|%0, %2}
23034 cmov%O2%c1\t{%3, %0|%0, %3}"
23035 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23036 (set_attr "mode" "SF,SF,SI,SI")])
23037
23038 ;; Don't do conditional moves with memory inputs. This splitter helps
23039 ;; register starved x86_32 by forcing inputs into registers before reload.
23040 (define_split
23041 [(set (match_operand:MODEF 0 "register_operand")
23042 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23043 [(reg FLAGS_REG) (const_int 0)])
23044 (match_operand:MODEF 2 "nonimmediate_operand")
23045 (match_operand:MODEF 3 "nonimmediate_operand")))]
23046 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23047 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23048 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23049 && can_create_pseudo_p ()
23050 && optimize_insn_for_speed_p ()"
23051 [(set (match_dup 0)
23052 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23053 {
23054 operands[2] = force_reg (<MODE>mode, operands[2]);
23055 operands[3] = force_reg (<MODE>mode, operands[3]);
23056 })
23057
23058 ;; Don't do conditional moves with memory inputs
23059 (define_peephole2
23060 [(match_scratch:MODEF 4 "r")
23061 (set (match_operand:MODEF 0 "general_reg_operand")
23062 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23063 [(reg FLAGS_REG) (const_int 0)])
23064 (match_operand:MODEF 2 "nonimmediate_operand")
23065 (match_operand:MODEF 3 "nonimmediate_operand")))]
23066 "(<MODE>mode != DFmode || TARGET_64BIT)
23067 && TARGET_80387 && TARGET_CMOVE
23068 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23069 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23070 && optimize_insn_for_speed_p ()"
23071 [(set (match_dup 4) (match_dup 5))
23072 (set (match_dup 0)
23073 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23074 {
23075 if (MEM_P (operands[2]))
23076 {
23077 operands[5] = operands[2];
23078 operands[2] = operands[4];
23079 }
23080 else if (MEM_P (operands[3]))
23081 {
23082 operands[5] = operands[3];
23083 operands[3] = operands[4];
23084 }
23085 else
23086 gcc_unreachable ();
23087 })
23088
23089 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23090 ;; the scalar versions to have only XMM registers as operands.
23091
23092 ;; XOP conditional move
23093 (define_insn "*xop_pcmov_<mode>"
23094 [(set (match_operand:MODEF 0 "register_operand" "=x")
23095 (if_then_else:MODEF
23096 (match_operand:MODEF 1 "register_operand" "x")
23097 (match_operand:MODEF 2 "register_operand" "x")
23098 (match_operand:MODEF 3 "register_operand" "x")))]
23099 "TARGET_XOP"
23100 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23101 [(set_attr "type" "sse4arg")])
23102
23103 ;; These versions of the min/max patterns are intentionally ignorant of
23104 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23105 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23106 ;; are undefined in this condition, we're certain this is correct.
23107
23108 (define_insn "<code><mode>3"
23109 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23110 (smaxmin:MODEF
23111 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23112 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23113 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23114 "@
23115 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23116 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23117 [(set_attr "isa" "noavx,avx")
23118 (set_attr "prefix" "orig,vex")
23119 (set_attr "type" "sseadd")
23120 (set_attr "mode" "<MODE>")])
23121
23122 (define_insn "<code>hf3"
23123 [(set (match_operand:HF 0 "register_operand" "=v")
23124 (smaxmin:HF
23125 (match_operand:HF 1 "nonimmediate_operand" "%v")
23126 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23127 "TARGET_AVX512FP16"
23128 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23129 [(set_attr "prefix" "evex")
23130 (set_attr "type" "sseadd")
23131 (set_attr "mode" "HF")])
23132
23133 ;; These versions of the min/max patterns implement exactly the operations
23134 ;; min = (op1 < op2 ? op1 : op2)
23135 ;; max = (!(op1 < op2) ? op1 : op2)
23136 ;; Their operands are not commutative, and thus they may be used in the
23137 ;; presence of -0.0 and NaN.
23138
23139 (define_insn "*ieee_s<ieee_maxmin>hf3"
23140 [(set (match_operand:HF 0 "register_operand" "=v")
23141 (unspec:HF
23142 [(match_operand:HF 1 "register_operand" "v")
23143 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23144 IEEE_MAXMIN))]
23145 "TARGET_AVX512FP16"
23146 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23147 [(set_attr "prefix" "evex")
23148 (set_attr "type" "sseadd")
23149 (set_attr "mode" "HF")])
23150
23151 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23152 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23153 (unspec:MODEF
23154 [(match_operand:MODEF 1 "register_operand" "0,v")
23155 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23156 IEEE_MAXMIN))]
23157 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23158 "@
23159 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23160 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23161 [(set_attr "isa" "noavx,avx")
23162 (set_attr "prefix" "orig,maybe_evex")
23163 (set_attr "type" "sseadd")
23164 (set_attr "mode" "<MODE>")])
23165
23166 ;; Operands order in min/max instruction matters for signed zero and NANs.
23167 (define_insn_and_split "*ieee_max<mode>3_1"
23168 [(set (match_operand:MODEF 0 "register_operand")
23169 (unspec:MODEF
23170 [(match_operand:MODEF 1 "register_operand")
23171 (match_operand:MODEF 2 "register_operand")
23172 (lt:MODEF
23173 (match_operand:MODEF 3 "register_operand")
23174 (match_operand:MODEF 4 "register_operand"))]
23175 UNSPEC_BLENDV))]
23176 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23177 && (rtx_equal_p (operands[1], operands[3])
23178 && rtx_equal_p (operands[2], operands[4]))
23179 && ix86_pre_reload_split ()"
23180 "#"
23181 "&& 1"
23182 [(set (match_dup 0)
23183 (unspec:MODEF
23184 [(match_dup 2)
23185 (match_dup 1)]
23186 UNSPEC_IEEE_MAX))])
23187
23188 (define_insn_and_split "*ieee_min<mode>3_1"
23189 [(set (match_operand:MODEF 0 "register_operand")
23190 (unspec:MODEF
23191 [(match_operand:MODEF 1 "register_operand")
23192 (match_operand:MODEF 2 "register_operand")
23193 (lt:MODEF
23194 (match_operand:MODEF 3 "register_operand")
23195 (match_operand:MODEF 4 "register_operand"))]
23196 UNSPEC_BLENDV))]
23197 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23198 && (rtx_equal_p (operands[1], operands[4])
23199 && rtx_equal_p (operands[2], operands[3]))
23200 && ix86_pre_reload_split ()"
23201 "#"
23202 "&& 1"
23203 [(set (match_dup 0)
23204 (unspec:MODEF
23205 [(match_dup 2)
23206 (match_dup 1)]
23207 UNSPEC_IEEE_MIN))])
23208
23209 ;; Make two stack loads independent:
23210 ;; fld aa fld aa
23211 ;; fld %st(0) -> fld bb
23212 ;; fmul bb fmul %st(1), %st
23213 ;;
23214 ;; Actually we only match the last two instructions for simplicity.
23215
23216 (define_peephole2
23217 [(set (match_operand 0 "fp_register_operand")
23218 (match_operand 1 "fp_register_operand"))
23219 (set (match_dup 0)
23220 (match_operator 2 "binary_fp_operator"
23221 [(match_dup 0)
23222 (match_operand 3 "memory_operand")]))]
23223 "REGNO (operands[0]) != REGNO (operands[1])"
23224 [(set (match_dup 0) (match_dup 3))
23225 (set (match_dup 0)
23226 (match_op_dup 2
23227 [(match_dup 5) (match_dup 4)]))]
23228 {
23229 operands[4] = operands[0];
23230 operands[5] = operands[1];
23231
23232 /* The % modifier is not operational anymore in peephole2's, so we have to
23233 swap the operands manually in the case of addition and multiplication. */
23234 if (COMMUTATIVE_ARITH_P (operands[2]))
23235 std::swap (operands[4], operands[5]);
23236 })
23237
23238 (define_peephole2
23239 [(set (match_operand 0 "fp_register_operand")
23240 (match_operand 1 "fp_register_operand"))
23241 (set (match_dup 0)
23242 (match_operator 2 "binary_fp_operator"
23243 [(match_operand 3 "memory_operand")
23244 (match_dup 0)]))]
23245 "REGNO (operands[0]) != REGNO (operands[1])"
23246 [(set (match_dup 0) (match_dup 3))
23247 (set (match_dup 0)
23248 (match_op_dup 2
23249 [(match_dup 4) (match_dup 5)]))]
23250 {
23251 operands[4] = operands[0];
23252 operands[5] = operands[1];
23253
23254 /* The % modifier is not operational anymore in peephole2's, so we have to
23255 swap the operands manually in the case of addition and multiplication. */
23256 if (COMMUTATIVE_ARITH_P (operands[2]))
23257 std::swap (operands[4], operands[5]);
23258 })
23259
23260 ;; Conditional addition patterns
23261 (define_expand "add<mode>cc"
23262 [(match_operand:SWI 0 "register_operand")
23263 (match_operand 1 "ordered_comparison_operator")
23264 (match_operand:SWI 2 "register_operand")
23265 (match_operand:SWI 3 "const_int_operand")]
23266 ""
23267 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23268
23269 ;; min/max patterns
23270
23271 (define_code_attr maxmin_rel
23272 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23273
23274 (define_expand "<code><mode>3"
23275 [(parallel
23276 [(set (match_operand:SDWIM 0 "register_operand")
23277 (maxmin:SDWIM
23278 (match_operand:SDWIM 1 "register_operand")
23279 (match_operand:SDWIM 2 "general_operand")))
23280 (clobber (reg:CC FLAGS_REG))])]
23281 "TARGET_CMOVE
23282 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23283
23284 (define_insn_and_split "*<code><dwi>3_doubleword"
23285 [(set (match_operand:<DWI> 0 "register_operand")
23286 (maxmin:<DWI>
23287 (match_operand:<DWI> 1 "register_operand")
23288 (match_operand:<DWI> 2 "general_operand")))
23289 (clobber (reg:CC FLAGS_REG))]
23290 "TARGET_CMOVE
23291 && ix86_pre_reload_split ()"
23292 "#"
23293 "&& 1"
23294 [(set (match_dup 0)
23295 (if_then_else:DWIH (match_dup 6)
23296 (match_dup 1)
23297 (match_dup 2)))
23298 (set (match_dup 3)
23299 (if_then_else:DWIH (match_dup 6)
23300 (match_dup 4)
23301 (match_dup 5)))]
23302 {
23303 operands[2] = force_reg (<DWI>mode, operands[2]);
23304
23305 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23306
23307 rtx cmplo[2] = { operands[1], operands[2] };
23308 rtx cmphi[2] = { operands[4], operands[5] };
23309
23310 enum rtx_code code = <maxmin_rel>;
23311
23312 switch (code)
23313 {
23314 case LE: case LEU:
23315 std::swap (cmplo[0], cmplo[1]);
23316 std::swap (cmphi[0], cmphi[1]);
23317 code = swap_condition (code);
23318 /* FALLTHRU */
23319
23320 case GE: case GEU:
23321 {
23322 bool uns = (code == GEU);
23323 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23324 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23325
23326 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23327
23328 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23329 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23330
23331 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23332 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23333
23334 break;
23335 }
23336
23337 default:
23338 gcc_unreachable ();
23339 }
23340 })
23341
23342 (define_insn_and_split "*<code><mode>3_1"
23343 [(set (match_operand:SWI 0 "register_operand")
23344 (maxmin:SWI
23345 (match_operand:SWI 1 "register_operand")
23346 (match_operand:SWI 2 "general_operand")))
23347 (clobber (reg:CC FLAGS_REG))]
23348 "TARGET_CMOVE
23349 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23350 && ix86_pre_reload_split ()"
23351 "#"
23352 "&& 1"
23353 [(set (match_dup 0)
23354 (if_then_else:SWI (match_dup 3)
23355 (match_dup 1)
23356 (match_dup 2)))]
23357 {
23358 machine_mode mode = <MODE>mode;
23359 rtx cmp_op = operands[2];
23360
23361 operands[2] = force_reg (mode, cmp_op);
23362
23363 enum rtx_code code = <maxmin_rel>;
23364
23365 if (cmp_op == const1_rtx)
23366 {
23367 /* Convert smax (x, 1) into (x > 0 ? x : 1).
23368 Convert umax (x, 1) into (x != 0 ? x : 1).
23369 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
23370 cmp_op = const0_rtx;
23371 if (code == GE)
23372 code = GT;
23373 else if (code == GEU)
23374 code = NE;
23375 }
23376 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
23377 else if (cmp_op == constm1_rtx && code == LE)
23378 {
23379 cmp_op = const0_rtx;
23380 code = LT;
23381 }
23382 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
23383 else if (cmp_op == constm1_rtx && code == GE)
23384 cmp_op = const0_rtx;
23385 else if (cmp_op != const0_rtx)
23386 cmp_op = operands[2];
23387
23388 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
23389 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
23390
23391 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
23392 emit_insn (gen_rtx_SET (flags, tmp));
23393
23394 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23395 })
23396
23397 ;; Avoid clearing a register between a flags setting comparison and its use,
23398 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
23399 (define_peephole2
23400 [(set (reg FLAGS_REG) (match_operand 0))
23401 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
23402 "peep2_regno_dead_p (0, FLAGS_REG)
23403 && !reg_overlap_mentioned_p (operands[1], operands[0])"
23404 [(set (match_dup 2) (match_dup 0))]
23405 {
23406 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
23407 ix86_expand_clear (operands[1]);
23408 })
23409
23410 ;; When optimizing for size, zeroing memory should use a register.
23411 (define_peephole2
23412 [(match_scratch:SWI48 0 "r")
23413 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23414 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23415 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23416 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23417 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23418 [(const_int 0)]
23419 {
23420 ix86_expand_clear (operands[0]);
23421 emit_move_insn (operands[1], operands[0]);
23422 emit_move_insn (operands[2], operands[0]);
23423 emit_move_insn (operands[3], operands[0]);
23424 ix86_last_zero_store_uid
23425 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23426 DONE;
23427 })
23428
23429 (define_peephole2
23430 [(match_scratch:SWI48 0 "r")
23431 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23432 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23433 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23434 [(const_int 0)]
23435 {
23436 ix86_expand_clear (operands[0]);
23437 emit_move_insn (operands[1], operands[0]);
23438 ix86_last_zero_store_uid
23439 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23440 DONE;
23441 })
23442
23443 (define_peephole2
23444 [(match_scratch:SWI48 0 "r")
23445 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23446 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23447 [(const_int 0)]
23448 {
23449 ix86_expand_clear (operands[0]);
23450 ix86_last_zero_store_uid
23451 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23452 DONE;
23453 })
23454
23455 (define_peephole2
23456 [(set (match_operand:SWI48 5 "memory_operand")
23457 (match_operand:SWI48 0 "general_reg_operand"))
23458 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23459 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23460 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23461 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23462 "optimize_insn_for_size_p ()
23463 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23464 [(const_int 0)]
23465 {
23466 emit_move_insn (operands[5], operands[0]);
23467 emit_move_insn (operands[1], operands[0]);
23468 emit_move_insn (operands[2], operands[0]);
23469 emit_move_insn (operands[3], operands[0]);
23470 ix86_last_zero_store_uid
23471 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23472 DONE;
23473 })
23474
23475 (define_peephole2
23476 [(set (match_operand:SWI48 3 "memory_operand")
23477 (match_operand:SWI48 0 "general_reg_operand"))
23478 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23479 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23480 "optimize_insn_for_size_p ()
23481 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23482 [(const_int 0)]
23483 {
23484 emit_move_insn (operands[3], operands[0]);
23485 emit_move_insn (operands[1], operands[0]);
23486 ix86_last_zero_store_uid
23487 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23488 DONE;
23489 })
23490
23491 (define_peephole2
23492 [(set (match_operand:SWI48 2 "memory_operand")
23493 (match_operand:SWI48 0 "general_reg_operand"))
23494 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23495 "optimize_insn_for_size_p ()
23496 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23497 [(const_int 0)]
23498 {
23499 emit_move_insn (operands[2], operands[0]);
23500 ix86_last_zero_store_uid
23501 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23502 DONE;
23503 })
23504
23505 ;; Reload dislikes loading constants directly into class_likely_spilled
23506 ;; hard registers. Try to tidy things up here.
23507 (define_peephole2
23508 [(set (match_operand:SWI 0 "general_reg_operand")
23509 (match_operand:SWI 1 "x86_64_general_operand"))
23510 (set (match_operand:SWI 2 "general_reg_operand")
23511 (match_dup 0))]
23512 "peep2_reg_dead_p (2, operands[0])"
23513 [(set (match_dup 2) (match_dup 1))])
23514 \f
23515 ;; Misc patterns (?)
23516
23517 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
23518 ;; Otherwise there will be nothing to keep
23519 ;;
23520 ;; [(set (reg ebp) (reg esp))]
23521 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
23522 ;; (clobber (eflags)]
23523 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
23524 ;;
23525 ;; in proper program order.
23526
23527 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
23528 [(set (match_operand:P 0 "register_operand" "=r,r")
23529 (plus:P (match_operand:P 1 "register_operand" "0,r")
23530 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
23531 (clobber (reg:CC FLAGS_REG))
23532 (clobber (mem:BLK (scratch)))]
23533 ""
23534 {
23535 switch (get_attr_type (insn))
23536 {
23537 case TYPE_IMOV:
23538 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
23539
23540 case TYPE_ALU:
23541 gcc_assert (rtx_equal_p (operands[0], operands[1]));
23542 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
23543 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
23544
23545 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
23546
23547 default:
23548 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
23549 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
23550 }
23551 }
23552 [(set (attr "type")
23553 (cond [(and (eq_attr "alternative" "0")
23554 (not (match_test "TARGET_OPT_AGU")))
23555 (const_string "alu")
23556 (match_operand:<MODE> 2 "const0_operand")
23557 (const_string "imov")
23558 ]
23559 (const_string "lea")))
23560 (set (attr "length_immediate")
23561 (cond [(eq_attr "type" "imov")
23562 (const_string "0")
23563 (and (eq_attr "type" "alu")
23564 (match_operand 2 "const128_operand"))
23565 (const_string "1")
23566 ]
23567 (const_string "*")))
23568 (set_attr "mode" "<MODE>")])
23569
23570 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
23571 [(set (match_operand:P 0 "register_operand" "=r")
23572 (minus:P (match_operand:P 1 "register_operand" "0")
23573 (match_operand:P 2 "register_operand" "r")))
23574 (clobber (reg:CC FLAGS_REG))
23575 (clobber (mem:BLK (scratch)))]
23576 ""
23577 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
23578 [(set_attr "type" "alu")
23579 (set_attr "mode" "<MODE>")])
23580
23581 (define_insn "@allocate_stack_worker_probe_<mode>"
23582 [(set (match_operand:P 0 "register_operand" "=a")
23583 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23584 UNSPECV_STACK_PROBE))
23585 (clobber (reg:CC FLAGS_REG))]
23586 "ix86_target_stack_probe ()"
23587 "call\t___chkstk_ms"
23588 [(set_attr "type" "multi")
23589 (set_attr "length" "5")])
23590
23591 (define_expand "allocate_stack"
23592 [(match_operand 0 "register_operand")
23593 (match_operand 1 "general_operand")]
23594 "ix86_target_stack_probe ()"
23595 {
23596 rtx x;
23597
23598 #ifndef CHECK_STACK_LIMIT
23599 #define CHECK_STACK_LIMIT 0
23600 #endif
23601
23602 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
23603 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
23604 x = operands[1];
23605 else
23606 {
23607 x = copy_to_mode_reg (Pmode, operands[1]);
23608
23609 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
23610 }
23611
23612 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
23613 stack_pointer_rtx, 0, OPTAB_DIRECT);
23614
23615 if (x != stack_pointer_rtx)
23616 emit_move_insn (stack_pointer_rtx, x);
23617
23618 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
23619 DONE;
23620 })
23621
23622 (define_expand "probe_stack"
23623 [(match_operand 0 "memory_operand")]
23624 ""
23625 {
23626 emit_insn (gen_probe_stack_1
23627 (word_mode, operands[0], const0_rtx));
23628 DONE;
23629 })
23630
23631 ;; Use OR for stack probes, this is shorter.
23632 (define_insn "@probe_stack_1_<mode>"
23633 [(set (match_operand:W 0 "memory_operand" "=m")
23634 (unspec:W [(match_operand:W 1 "const0_operand")]
23635 UNSPEC_PROBE_STACK))
23636 (clobber (reg:CC FLAGS_REG))]
23637 ""
23638 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
23639 [(set_attr "type" "alu1")
23640 (set_attr "mode" "<MODE>")
23641 (set_attr "length_immediate" "1")])
23642
23643 (define_insn "@adjust_stack_and_probe_<mode>"
23644 [(set (match_operand:P 0 "register_operand" "=r")
23645 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23646 UNSPECV_PROBE_STACK_RANGE))
23647 (set (reg:P SP_REG)
23648 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
23649 (clobber (reg:CC FLAGS_REG))
23650 (clobber (mem:BLK (scratch)))]
23651 ""
23652 "* return output_adjust_stack_and_probe (operands[0]);"
23653 [(set_attr "type" "multi")])
23654
23655 (define_insn "@probe_stack_range_<mode>"
23656 [(set (match_operand:P 0 "register_operand" "=r")
23657 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
23658 (match_operand:P 2 "const_int_operand")]
23659 UNSPECV_PROBE_STACK_RANGE))
23660 (clobber (reg:CC FLAGS_REG))]
23661 ""
23662 "* return output_probe_stack_range (operands[0], operands[2]);"
23663 [(set_attr "type" "multi")])
23664
23665 (define_expand "builtin_setjmp_receiver"
23666 [(label_ref (match_operand 0))]
23667 "!TARGET_64BIT && flag_pic"
23668 {
23669 #if TARGET_MACHO
23670 if (TARGET_MACHO)
23671 {
23672 rtx xops[3];
23673 rtx_code_label *label_rtx = gen_label_rtx ();
23674 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
23675 xops[0] = xops[1] = pic_offset_table_rtx;
23676 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
23677 ix86_expand_binary_operator (MINUS, SImode, xops);
23678 }
23679 else
23680 #endif
23681 emit_insn (gen_set_got (pic_offset_table_rtx));
23682 DONE;
23683 })
23684
23685 (define_expand "save_stack_nonlocal"
23686 [(set (match_operand 0 "memory_operand")
23687 (match_operand 1 "register_operand"))]
23688 ""
23689 {
23690 rtx stack_slot;
23691
23692 if (flag_cf_protection & CF_RETURN)
23693 {
23694 /* Copy shadow stack pointer to the first slot
23695 and stack pointer to the second slot. */
23696 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
23697 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
23698
23699 rtx reg_ssp = force_reg (word_mode, const0_rtx);
23700 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
23701 emit_move_insn (ssp_slot, reg_ssp);
23702 }
23703 else
23704 stack_slot = adjust_address (operands[0], Pmode, 0);
23705 emit_move_insn (stack_slot, operands[1]);
23706 DONE;
23707 })
23708
23709 (define_expand "restore_stack_nonlocal"
23710 [(set (match_operand 0 "register_operand" "")
23711 (match_operand 1 "memory_operand" ""))]
23712 ""
23713 {
23714 rtx stack_slot;
23715
23716 if (flag_cf_protection & CF_RETURN)
23717 {
23718 /* Restore shadow stack pointer from the first slot
23719 and stack pointer from the second slot. */
23720 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
23721 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
23722
23723 /* Get the current shadow stack pointer. The code below will check if
23724 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
23725 is a NOP. */
23726 rtx reg_ssp = force_reg (word_mode, const0_rtx);
23727 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
23728
23729 /* Compare through subtraction the saved and the current ssp
23730 to decide if ssp has to be adjusted. */
23731 reg_ssp = expand_simple_binop (word_mode, MINUS,
23732 reg_ssp, ssp_slot,
23733 reg_ssp, 1, OPTAB_DIRECT);
23734
23735 /* Compare and jump over adjustment code. */
23736 rtx noadj_label = gen_label_rtx ();
23737 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
23738 word_mode, 1, noadj_label);
23739
23740 /* Compute the number of frames to adjust. */
23741 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
23742 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
23743 NULL_RTX, 1);
23744
23745 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
23746 GEN_INT (exact_log2 (UNITS_PER_WORD)),
23747 reg_adj, 1, OPTAB_DIRECT);
23748
23749 /* Check if number of frames <= 255 so no loop is needed. */
23750 rtx inc_label = gen_label_rtx ();
23751 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
23752 ptr_mode, 1, inc_label);
23753
23754 /* Adjust the ssp in a loop. */
23755 rtx loop_label = gen_label_rtx ();
23756 emit_label (loop_label);
23757 LABEL_NUSES (loop_label) = 1;
23758
23759 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
23760 emit_insn (gen_incssp (word_mode, reg_255));
23761
23762 reg_adj = expand_simple_binop (ptr_mode, MINUS,
23763 reg_adj, GEN_INT (255),
23764 reg_adj, 1, OPTAB_DIRECT);
23765
23766 /* Compare and jump to the loop label. */
23767 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
23768 ptr_mode, 1, loop_label);
23769
23770 emit_label (inc_label);
23771 LABEL_NUSES (inc_label) = 1;
23772
23773 emit_insn (gen_incssp (word_mode, reg_ssp));
23774
23775 emit_label (noadj_label);
23776 LABEL_NUSES (noadj_label) = 1;
23777 }
23778 else
23779 stack_slot = adjust_address (operands[1], Pmode, 0);
23780 emit_move_insn (operands[0], stack_slot);
23781 DONE;
23782 })
23783
23784
23785 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
23786 ;; Do not split instructions with mask registers.
23787 (define_split
23788 [(set (match_operand 0 "general_reg_operand")
23789 (match_operator 3 "promotable_binary_operator"
23790 [(match_operand 1 "general_reg_operand")
23791 (match_operand 2 "aligned_operand")]))
23792 (clobber (reg:CC FLAGS_REG))]
23793 "! TARGET_PARTIAL_REG_STALL && reload_completed
23794 && ((GET_MODE (operands[0]) == HImode
23795 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
23796 /* ??? next two lines just !satisfies_constraint_K (...) */
23797 || !CONST_INT_P (operands[2])
23798 || satisfies_constraint_K (operands[2])))
23799 || (GET_MODE (operands[0]) == QImode
23800 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
23801 [(parallel [(set (match_dup 0)
23802 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
23803 (clobber (reg:CC FLAGS_REG))])]
23804 {
23805 operands[0] = gen_lowpart (SImode, operands[0]);
23806 operands[1] = gen_lowpart (SImode, operands[1]);
23807 if (GET_CODE (operands[3]) != ASHIFT)
23808 operands[2] = gen_lowpart (SImode, operands[2]);
23809 operands[3] = shallow_copy_rtx (operands[3]);
23810 PUT_MODE (operands[3], SImode);
23811 })
23812
23813 ; Promote the QImode tests, as i386 has encoding of the AND
23814 ; instruction with 32-bit sign-extended immediate and thus the
23815 ; instruction size is unchanged, except in the %eax case for
23816 ; which it is increased by one byte, hence the ! optimize_size.
23817 (define_split
23818 [(set (match_operand 0 "flags_reg_operand")
23819 (match_operator 2 "compare_operator"
23820 [(and (match_operand 3 "aligned_operand")
23821 (match_operand 4 "const_int_operand"))
23822 (const_int 0)]))
23823 (set (match_operand 1 "register_operand")
23824 (and (match_dup 3) (match_dup 4)))]
23825 "! TARGET_PARTIAL_REG_STALL && reload_completed
23826 && optimize_insn_for_speed_p ()
23827 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
23828 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
23829 /* Ensure that the operand will remain sign-extended immediate. */
23830 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
23831 [(parallel [(set (match_dup 0)
23832 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
23833 (const_int 0)]))
23834 (set (match_dup 1)
23835 (and:SI (match_dup 3) (match_dup 4)))])]
23836 {
23837 operands[4]
23838 = gen_int_mode (INTVAL (operands[4])
23839 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
23840 operands[1] = gen_lowpart (SImode, operands[1]);
23841 operands[3] = gen_lowpart (SImode, operands[3]);
23842 })
23843
23844 ; Don't promote the QImode tests, as i386 doesn't have encoding of
23845 ; the TEST instruction with 32-bit sign-extended immediate and thus
23846 ; the instruction size would at least double, which is not what we
23847 ; want even with ! optimize_size.
23848 (define_split
23849 [(set (match_operand 0 "flags_reg_operand")
23850 (match_operator 1 "compare_operator"
23851 [(and (match_operand:HI 2 "aligned_operand")
23852 (match_operand:HI 3 "const_int_operand"))
23853 (const_int 0)]))]
23854 "! TARGET_PARTIAL_REG_STALL && reload_completed
23855 && ! TARGET_FAST_PREFIX
23856 && optimize_insn_for_speed_p ()
23857 /* Ensure that the operand will remain sign-extended immediate. */
23858 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
23859 [(set (match_dup 0)
23860 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
23861 (const_int 0)]))]
23862 {
23863 operands[3]
23864 = gen_int_mode (INTVAL (operands[3])
23865 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
23866 operands[2] = gen_lowpart (SImode, operands[2]);
23867 })
23868
23869 (define_split
23870 [(set (match_operand 0 "register_operand")
23871 (neg (match_operand 1 "register_operand")))
23872 (clobber (reg:CC FLAGS_REG))]
23873 "! TARGET_PARTIAL_REG_STALL && reload_completed
23874 && (GET_MODE (operands[0]) == HImode
23875 || (GET_MODE (operands[0]) == QImode
23876 && (TARGET_PROMOTE_QImode
23877 || optimize_insn_for_size_p ())))"
23878 [(parallel [(set (match_dup 0)
23879 (neg:SI (match_dup 1)))
23880 (clobber (reg:CC FLAGS_REG))])]
23881 {
23882 operands[0] = gen_lowpart (SImode, operands[0]);
23883 operands[1] = gen_lowpart (SImode, operands[1]);
23884 })
23885
23886 ;; Do not split instructions with mask regs.
23887 (define_split
23888 [(set (match_operand 0 "general_reg_operand")
23889 (not (match_operand 1 "general_reg_operand")))]
23890 "! TARGET_PARTIAL_REG_STALL && reload_completed
23891 && (GET_MODE (operands[0]) == HImode
23892 || (GET_MODE (operands[0]) == QImode
23893 && (TARGET_PROMOTE_QImode
23894 || optimize_insn_for_size_p ())))"
23895 [(set (match_dup 0)
23896 (not:SI (match_dup 1)))]
23897 {
23898 operands[0] = gen_lowpart (SImode, operands[0]);
23899 operands[1] = gen_lowpart (SImode, operands[1]);
23900 })
23901 \f
23902 ;; RTL Peephole optimizations, run before sched2. These primarily look to
23903 ;; transform a complex memory operation into two memory to register operations.
23904
23905 ;; Don't push memory operands
23906 (define_peephole2
23907 [(set (match_operand:SWI 0 "push_operand")
23908 (match_operand:SWI 1 "memory_operand"))
23909 (match_scratch:SWI 2 "<r>")]
23910 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
23911 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
23912 [(set (match_dup 2) (match_dup 1))
23913 (set (match_dup 0) (match_dup 2))])
23914
23915 ;; We need to handle SFmode only, because DFmode and XFmode are split to
23916 ;; SImode pushes.
23917 (define_peephole2
23918 [(set (match_operand:SF 0 "push_operand")
23919 (match_operand:SF 1 "memory_operand"))
23920 (match_scratch:SF 2 "r")]
23921 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
23922 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
23923 [(set (match_dup 2) (match_dup 1))
23924 (set (match_dup 0) (match_dup 2))])
23925
23926 ;; Don't move an immediate directly to memory when the instruction
23927 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
23928 (define_peephole2
23929 [(match_scratch:SWI124 1 "<r>")
23930 (set (match_operand:SWI124 0 "memory_operand")
23931 (const_int 0))]
23932 "optimize_insn_for_speed_p ()
23933 && ((<MODE>mode == HImode
23934 && TARGET_LCP_STALL)
23935 || (!TARGET_USE_MOV0
23936 && TARGET_SPLIT_LONG_MOVES
23937 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
23938 && peep2_regno_dead_p (0, FLAGS_REG)"
23939 [(parallel [(set (match_dup 2) (const_int 0))
23940 (clobber (reg:CC FLAGS_REG))])
23941 (set (match_dup 0) (match_dup 1))]
23942 "operands[2] = gen_lowpart (SImode, operands[1]);")
23943
23944 (define_peephole2
23945 [(match_scratch:SWI124 2 "<r>")
23946 (set (match_operand:SWI124 0 "memory_operand")
23947 (match_operand:SWI124 1 "immediate_operand"))]
23948 "optimize_insn_for_speed_p ()
23949 && ((<MODE>mode == HImode
23950 && TARGET_LCP_STALL)
23951 || (TARGET_SPLIT_LONG_MOVES
23952 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
23953 [(set (match_dup 2) (match_dup 1))
23954 (set (match_dup 0) (match_dup 2))])
23955
23956 ;; Don't compare memory with zero, load and use a test instead.
23957 (define_peephole2
23958 [(set (match_operand 0 "flags_reg_operand")
23959 (match_operator 1 "compare_operator"
23960 [(match_operand:SI 2 "memory_operand")
23961 (const_int 0)]))
23962 (match_scratch:SI 3 "r")]
23963 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
23964 [(set (match_dup 3) (match_dup 2))
23965 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
23966
23967 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
23968 ;; Don't split NOTs with a displacement operand, because resulting XOR
23969 ;; will not be pairable anyway.
23970 ;;
23971 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
23972 ;; represented using a modRM byte. The XOR replacement is long decoded,
23973 ;; so this split helps here as well.
23974 ;;
23975 ;; Note: Can't do this as a regular split because we can't get proper
23976 ;; lifetime information then.
23977
23978 (define_peephole2
23979 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
23980 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
23981 "optimize_insn_for_speed_p ()
23982 && ((TARGET_NOT_UNPAIRABLE
23983 && (!MEM_P (operands[0])
23984 || !memory_displacement_operand (operands[0], <MODE>mode)))
23985 || (TARGET_NOT_VECTORMODE
23986 && long_memory_operand (operands[0], <MODE>mode)))
23987 && peep2_regno_dead_p (0, FLAGS_REG)"
23988 [(parallel [(set (match_dup 0)
23989 (xor:SWI124 (match_dup 1) (const_int -1)))
23990 (clobber (reg:CC FLAGS_REG))])])
23991
23992 ;; Non pairable "test imm, reg" instructions can be translated to
23993 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
23994 ;; byte opcode instead of two, have a short form for byte operands),
23995 ;; so do it for other CPUs as well. Given that the value was dead,
23996 ;; this should not create any new dependencies. Pass on the sub-word
23997 ;; versions if we're concerned about partial register stalls.
23998
23999 (define_peephole2
24000 [(set (match_operand 0 "flags_reg_operand")
24001 (match_operator 1 "compare_operator"
24002 [(and:SI (match_operand:SI 2 "register_operand")
24003 (match_operand:SI 3 "immediate_operand"))
24004 (const_int 0)]))]
24005 "ix86_match_ccmode (insn, CCNOmode)
24006 && (REGNO (operands[2]) != AX_REG
24007 || satisfies_constraint_K (operands[3]))
24008 && peep2_reg_dead_p (1, operands[2])"
24009 [(parallel
24010 [(set (match_dup 0)
24011 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24012 (const_int 0)]))
24013 (set (match_dup 2)
24014 (and:SI (match_dup 2) (match_dup 3)))])])
24015
24016 ;; We don't need to handle HImode case, because it will be promoted to SImode
24017 ;; on ! TARGET_PARTIAL_REG_STALL
24018
24019 (define_peephole2
24020 [(set (match_operand 0 "flags_reg_operand")
24021 (match_operator 1 "compare_operator"
24022 [(and:QI (match_operand:QI 2 "register_operand")
24023 (match_operand:QI 3 "immediate_operand"))
24024 (const_int 0)]))]
24025 "! TARGET_PARTIAL_REG_STALL
24026 && ix86_match_ccmode (insn, CCNOmode)
24027 && REGNO (operands[2]) != AX_REG
24028 && peep2_reg_dead_p (1, operands[2])"
24029 [(parallel
24030 [(set (match_dup 0)
24031 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24032 (const_int 0)]))
24033 (set (match_dup 2)
24034 (and:QI (match_dup 2) (match_dup 3)))])])
24035
24036 (define_peephole2
24037 [(set (match_operand 0 "flags_reg_operand")
24038 (match_operator 1 "compare_operator"
24039 [(and:QI
24040 (subreg:QI
24041 (match_operator:SWI248 4 "extract_operator"
24042 [(match_operand 2 "int248_register_operand")
24043 (const_int 8)
24044 (const_int 8)]) 0)
24045 (match_operand 3 "const_int_operand"))
24046 (const_int 0)]))]
24047 "! TARGET_PARTIAL_REG_STALL
24048 && ix86_match_ccmode (insn, CCNOmode)
24049 && REGNO (operands[2]) != AX_REG
24050 && peep2_reg_dead_p (1, operands[2])"
24051 [(parallel
24052 [(set (match_dup 0)
24053 (match_op_dup 1
24054 [(and:QI
24055 (subreg:QI
24056 (match_op_dup 4 [(match_dup 2)
24057 (const_int 8)
24058 (const_int 8)]) 0)
24059 (match_dup 3))
24060 (const_int 0)]))
24061 (set (zero_extract:SWI248 (match_dup 2)
24062 (const_int 8)
24063 (const_int 8))
24064 (subreg:SWI248
24065 (and:QI
24066 (subreg:QI
24067 (match_op_dup 4 [(match_dup 2)
24068 (const_int 8)
24069 (const_int 8)]) 0)
24070 (match_dup 3)) 0))])])
24071
24072 ;; Don't do logical operations with memory inputs.
24073 (define_peephole2
24074 [(match_scratch:SWI 2 "<r>")
24075 (parallel [(set (match_operand:SWI 0 "register_operand")
24076 (match_operator:SWI 3 "arith_or_logical_operator"
24077 [(match_dup 0)
24078 (match_operand:SWI 1 "memory_operand")]))
24079 (clobber (reg:CC FLAGS_REG))])]
24080 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24081 [(set (match_dup 2) (match_dup 1))
24082 (parallel [(set (match_dup 0)
24083 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24084 (clobber (reg:CC FLAGS_REG))])])
24085
24086 (define_peephole2
24087 [(match_scratch:SWI 2 "<r>")
24088 (parallel [(set (match_operand:SWI 0 "register_operand")
24089 (match_operator:SWI 3 "arith_or_logical_operator"
24090 [(match_operand:SWI 1 "memory_operand")
24091 (match_dup 0)]))
24092 (clobber (reg:CC FLAGS_REG))])]
24093 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24094 [(set (match_dup 2) (match_dup 1))
24095 (parallel [(set (match_dup 0)
24096 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24097 (clobber (reg:CC FLAGS_REG))])])
24098
24099 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
24100 ;; the memory address refers to the destination of the load!
24101
24102 (define_peephole2
24103 [(set (match_operand:SWI 0 "general_reg_operand")
24104 (match_operand:SWI 1 "general_reg_operand"))
24105 (parallel [(set (match_dup 0)
24106 (match_operator:SWI 3 "commutative_operator"
24107 [(match_dup 0)
24108 (match_operand:SWI 2 "memory_operand")]))
24109 (clobber (reg:CC FLAGS_REG))])]
24110 "REGNO (operands[0]) != REGNO (operands[1])
24111 && (<MODE>mode != QImode
24112 || any_QIreg_operand (operands[1], QImode))"
24113 [(set (match_dup 0) (match_dup 4))
24114 (parallel [(set (match_dup 0)
24115 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24116 (clobber (reg:CC FLAGS_REG))])]
24117 {
24118 operands[4]
24119 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24120 })
24121
24122 (define_peephole2
24123 [(set (match_operand 0 "mmx_reg_operand")
24124 (match_operand 1 "mmx_reg_operand"))
24125 (set (match_dup 0)
24126 (match_operator 3 "commutative_operator"
24127 [(match_dup 0)
24128 (match_operand 2 "memory_operand")]))]
24129 "REGNO (operands[0]) != REGNO (operands[1])"
24130 [(set (match_dup 0) (match_dup 2))
24131 (set (match_dup 0)
24132 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24133
24134 (define_peephole2
24135 [(set (match_operand 0 "sse_reg_operand")
24136 (match_operand 1 "sse_reg_operand"))
24137 (set (match_dup 0)
24138 (match_operator 3 "commutative_operator"
24139 [(match_dup 0)
24140 (match_operand 2 "memory_operand")]))]
24141 "REGNO (operands[0]) != REGNO (operands[1])
24142 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
24143 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
24144 instructions require AVX512BW and AVX512VL, but with the original
24145 instructions it might require just AVX512VL.
24146 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
24147 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
24148 || TARGET_AVX512BW
24149 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
24150 || logic_operator (operands[3], VOIDmode))"
24151 [(set (match_dup 0) (match_dup 2))
24152 (set (match_dup 0)
24153 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24154
24155 ; Don't do logical operations with memory outputs
24156 ;
24157 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
24158 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
24159 ; the same decoder scheduling characteristics as the original.
24160
24161 (define_peephole2
24162 [(match_scratch:SWI 2 "<r>")
24163 (parallel [(set (match_operand:SWI 0 "memory_operand")
24164 (match_operator:SWI 3 "arith_or_logical_operator"
24165 [(match_dup 0)
24166 (match_operand:SWI 1 "<nonmemory_operand>")]))
24167 (clobber (reg:CC FLAGS_REG))])]
24168 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24169 [(set (match_dup 2) (match_dup 0))
24170 (parallel [(set (match_dup 2)
24171 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
24172 (clobber (reg:CC FLAGS_REG))])
24173 (set (match_dup 0) (match_dup 2))])
24174
24175 (define_peephole2
24176 [(match_scratch:SWI 2 "<r>")
24177 (parallel [(set (match_operand:SWI 0 "memory_operand")
24178 (match_operator:SWI 3 "arith_or_logical_operator"
24179 [(match_operand:SWI 1 "<nonmemory_operand>")
24180 (match_dup 0)]))
24181 (clobber (reg:CC FLAGS_REG))])]
24182 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24183 [(set (match_dup 2) (match_dup 0))
24184 (parallel [(set (match_dup 2)
24185 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24186 (clobber (reg:CC FLAGS_REG))])
24187 (set (match_dup 0) (match_dup 2))])
24188
24189 ;; Attempt to use arith or logical operations with memory outputs with
24190 ;; setting of flags.
24191 (define_peephole2
24192 [(set (match_operand:SWI 0 "register_operand")
24193 (match_operand:SWI 1 "memory_operand"))
24194 (parallel [(set (match_dup 0)
24195 (match_operator:SWI 3 "plusminuslogic_operator"
24196 [(match_dup 0)
24197 (match_operand:SWI 2 "<nonmemory_operand>")]))
24198 (clobber (reg:CC FLAGS_REG))])
24199 (set (match_dup 1) (match_dup 0))
24200 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24201 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24202 && peep2_reg_dead_p (4, operands[0])
24203 && !reg_overlap_mentioned_p (operands[0], operands[1])
24204 && !reg_overlap_mentioned_p (operands[0], operands[2])
24205 && (<MODE>mode != QImode
24206 || immediate_operand (operands[2], QImode)
24207 || any_QIreg_operand (operands[2], QImode))
24208 && ix86_match_ccmode (peep2_next_insn (3),
24209 (GET_CODE (operands[3]) == PLUS
24210 || GET_CODE (operands[3]) == MINUS)
24211 ? CCGOCmode : CCNOmode)"
24212 [(parallel [(set (match_dup 4) (match_dup 6))
24213 (set (match_dup 1) (match_dup 5))])]
24214 {
24215 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
24216 operands[5]
24217 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24218 copy_rtx (operands[1]),
24219 operands[2]);
24220 operands[6]
24221 = gen_rtx_COMPARE (GET_MODE (operands[4]),
24222 copy_rtx (operands[5]),
24223 const0_rtx);
24224 })
24225
24226 ;; Likewise for cmpelim optimized pattern.
24227 (define_peephole2
24228 [(set (match_operand:SWI 0 "register_operand")
24229 (match_operand:SWI 1 "memory_operand"))
24230 (parallel [(set (reg FLAGS_REG)
24231 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24232 [(match_dup 0)
24233 (match_operand:SWI 2 "<nonmemory_operand>")])
24234 (const_int 0)))
24235 (set (match_dup 0) (match_dup 3))])
24236 (set (match_dup 1) (match_dup 0))]
24237 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24238 && peep2_reg_dead_p (3, operands[0])
24239 && !reg_overlap_mentioned_p (operands[0], operands[1])
24240 && !reg_overlap_mentioned_p (operands[0], operands[2])
24241 && ix86_match_ccmode (peep2_next_insn (1),
24242 (GET_CODE (operands[3]) == PLUS
24243 || GET_CODE (operands[3]) == MINUS)
24244 ? CCGOCmode : CCNOmode)"
24245 [(parallel [(set (match_dup 4) (match_dup 6))
24246 (set (match_dup 1) (match_dup 5))])]
24247 {
24248 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24249 operands[5]
24250 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24251 copy_rtx (operands[1]), operands[2]);
24252 operands[6]
24253 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
24254 const0_rtx);
24255 })
24256
24257 ;; Likewise for instances where we have a lea pattern.
24258 (define_peephole2
24259 [(set (match_operand:SWI 0 "register_operand")
24260 (match_operand:SWI 1 "memory_operand"))
24261 (set (match_operand:<LEAMODE> 3 "register_operand")
24262 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
24263 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
24264 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
24265 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24266 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24267 && REGNO (operands[4]) == REGNO (operands[0])
24268 && REGNO (operands[5]) == REGNO (operands[3])
24269 && peep2_reg_dead_p (4, operands[3])
24270 && ((REGNO (operands[0]) == REGNO (operands[3]))
24271 || peep2_reg_dead_p (2, operands[0]))
24272 && !reg_overlap_mentioned_p (operands[0], operands[1])
24273 && !reg_overlap_mentioned_p (operands[3], operands[1])
24274 && !reg_overlap_mentioned_p (operands[0], operands[2])
24275 && (<MODE>mode != QImode
24276 || immediate_operand (operands[2], QImode)
24277 || any_QIreg_operand (operands[2], QImode))
24278 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
24279 [(parallel [(set (match_dup 6) (match_dup 8))
24280 (set (match_dup 1) (match_dup 7))])]
24281 {
24282 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
24283 operands[7]
24284 = gen_rtx_PLUS (<MODE>mode,
24285 copy_rtx (operands[1]),
24286 gen_lowpart (<MODE>mode, operands[2]));
24287 operands[8]
24288 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24289 copy_rtx (operands[7]),
24290 const0_rtx);
24291 })
24292
24293 (define_peephole2
24294 [(parallel [(set (match_operand:SWI 0 "register_operand")
24295 (match_operator:SWI 2 "plusminuslogic_operator"
24296 [(match_dup 0)
24297 (match_operand:SWI 1 "memory_operand")]))
24298 (clobber (reg:CC FLAGS_REG))])
24299 (set (match_dup 1) (match_dup 0))
24300 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24301 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24302 && COMMUTATIVE_ARITH_P (operands[2])
24303 && peep2_reg_dead_p (3, operands[0])
24304 && !reg_overlap_mentioned_p (operands[0], operands[1])
24305 && ix86_match_ccmode (peep2_next_insn (2),
24306 GET_CODE (operands[2]) == PLUS
24307 ? CCGOCmode : CCNOmode)"
24308 [(parallel [(set (match_dup 3) (match_dup 5))
24309 (set (match_dup 1) (match_dup 4))])]
24310 {
24311 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
24312 operands[4]
24313 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24314 copy_rtx (operands[1]),
24315 operands[0]);
24316 operands[5]
24317 = gen_rtx_COMPARE (GET_MODE (operands[3]),
24318 copy_rtx (operands[4]),
24319 const0_rtx);
24320 })
24321
24322 ;; Likewise for cmpelim optimized pattern.
24323 (define_peephole2
24324 [(parallel [(set (reg FLAGS_REG)
24325 (compare (match_operator:SWI 2 "plusminuslogic_operator"
24326 [(match_operand:SWI 0 "register_operand")
24327 (match_operand:SWI 1 "memory_operand")])
24328 (const_int 0)))
24329 (set (match_dup 0) (match_dup 2))])
24330 (set (match_dup 1) (match_dup 0))]
24331 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24332 && COMMUTATIVE_ARITH_P (operands[2])
24333 && peep2_reg_dead_p (2, operands[0])
24334 && !reg_overlap_mentioned_p (operands[0], operands[1])
24335 && ix86_match_ccmode (peep2_next_insn (0),
24336 GET_CODE (operands[2]) == PLUS
24337 ? CCGOCmode : CCNOmode)"
24338 [(parallel [(set (match_dup 3) (match_dup 5))
24339 (set (match_dup 1) (match_dup 4))])]
24340 {
24341 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
24342 operands[4]
24343 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24344 copy_rtx (operands[1]), operands[0]);
24345 operands[5]
24346 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
24347 const0_rtx);
24348 })
24349
24350 (define_peephole2
24351 [(set (match_operand:SWI12 0 "register_operand")
24352 (match_operand:SWI12 1 "memory_operand"))
24353 (parallel [(set (match_operand:SI 4 "register_operand")
24354 (match_operator:SI 3 "plusminuslogic_operator"
24355 [(match_dup 4)
24356 (match_operand:SI 2 "nonmemory_operand")]))
24357 (clobber (reg:CC FLAGS_REG))])
24358 (set (match_dup 1) (match_dup 0))
24359 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24360 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24361 && REGNO (operands[0]) == REGNO (operands[4])
24362 && peep2_reg_dead_p (4, operands[0])
24363 && (<MODE>mode != QImode
24364 || immediate_operand (operands[2], SImode)
24365 || any_QIreg_operand (operands[2], SImode))
24366 && !reg_overlap_mentioned_p (operands[0], operands[1])
24367 && !reg_overlap_mentioned_p (operands[0], operands[2])
24368 && ix86_match_ccmode (peep2_next_insn (3),
24369 (GET_CODE (operands[3]) == PLUS
24370 || GET_CODE (operands[3]) == MINUS)
24371 ? CCGOCmode : CCNOmode)"
24372 [(parallel [(set (match_dup 5) (match_dup 7))
24373 (set (match_dup 1) (match_dup 6))])]
24374 {
24375 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
24376 operands[6]
24377 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24378 copy_rtx (operands[1]),
24379 gen_lowpart (<MODE>mode, operands[2]));
24380 operands[7]
24381 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24382 copy_rtx (operands[6]),
24383 const0_rtx);
24384 })
24385
24386 ;; peephole2 comes before regcprop, so deal also with a case that
24387 ;; would be cleaned up by regcprop.
24388 (define_peephole2
24389 [(set (match_operand:SWI 0 "register_operand")
24390 (match_operand:SWI 1 "memory_operand"))
24391 (parallel [(set (match_dup 0)
24392 (match_operator:SWI 3 "plusminuslogic_operator"
24393 [(match_dup 0)
24394 (match_operand:SWI 2 "<nonmemory_operand>")]))
24395 (clobber (reg:CC FLAGS_REG))])
24396 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24397 (set (match_dup 1) (match_dup 4))
24398 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
24399 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24400 && peep2_reg_dead_p (3, operands[0])
24401 && peep2_reg_dead_p (5, operands[4])
24402 && !reg_overlap_mentioned_p (operands[0], operands[1])
24403 && !reg_overlap_mentioned_p (operands[0], operands[2])
24404 && !reg_overlap_mentioned_p (operands[4], operands[1])
24405 && (<MODE>mode != QImode
24406 || immediate_operand (operands[2], QImode)
24407 || any_QIreg_operand (operands[2], QImode))
24408 && ix86_match_ccmode (peep2_next_insn (4),
24409 (GET_CODE (operands[3]) == PLUS
24410 || GET_CODE (operands[3]) == MINUS)
24411 ? CCGOCmode : CCNOmode)"
24412 [(parallel [(set (match_dup 5) (match_dup 7))
24413 (set (match_dup 1) (match_dup 6))])]
24414 {
24415 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
24416 operands[6]
24417 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24418 copy_rtx (operands[1]),
24419 operands[2]);
24420 operands[7]
24421 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24422 copy_rtx (operands[6]),
24423 const0_rtx);
24424 })
24425
24426 (define_peephole2
24427 [(set (match_operand:SWI12 0 "register_operand")
24428 (match_operand:SWI12 1 "memory_operand"))
24429 (parallel [(set (match_operand:SI 4 "register_operand")
24430 (match_operator:SI 3 "plusminuslogic_operator"
24431 [(match_dup 4)
24432 (match_operand:SI 2 "nonmemory_operand")]))
24433 (clobber (reg:CC FLAGS_REG))])
24434 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
24435 (set (match_dup 1) (match_dup 5))
24436 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24437 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24438 && REGNO (operands[0]) == REGNO (operands[4])
24439 && peep2_reg_dead_p (3, operands[0])
24440 && peep2_reg_dead_p (5, operands[5])
24441 && (<MODE>mode != QImode
24442 || immediate_operand (operands[2], SImode)
24443 || any_QIreg_operand (operands[2], SImode))
24444 && !reg_overlap_mentioned_p (operands[0], operands[1])
24445 && !reg_overlap_mentioned_p (operands[0], operands[2])
24446 && !reg_overlap_mentioned_p (operands[5], operands[1])
24447 && ix86_match_ccmode (peep2_next_insn (4),
24448 (GET_CODE (operands[3]) == PLUS
24449 || GET_CODE (operands[3]) == MINUS)
24450 ? CCGOCmode : CCNOmode)"
24451 [(parallel [(set (match_dup 6) (match_dup 8))
24452 (set (match_dup 1) (match_dup 7))])]
24453 {
24454 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
24455 operands[7]
24456 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24457 copy_rtx (operands[1]),
24458 gen_lowpart (<MODE>mode, operands[2]));
24459 operands[8]
24460 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24461 copy_rtx (operands[7]),
24462 const0_rtx);
24463 })
24464
24465 ;; Likewise for cmpelim optimized pattern.
24466 (define_peephole2
24467 [(set (match_operand:SWI 0 "register_operand")
24468 (match_operand:SWI 1 "memory_operand"))
24469 (parallel [(set (reg FLAGS_REG)
24470 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24471 [(match_dup 0)
24472 (match_operand:SWI 2 "<nonmemory_operand>")])
24473 (const_int 0)))
24474 (set (match_dup 0) (match_dup 3))])
24475 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24476 (set (match_dup 1) (match_dup 4))]
24477 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24478 && peep2_reg_dead_p (3, operands[0])
24479 && peep2_reg_dead_p (4, operands[4])
24480 && !reg_overlap_mentioned_p (operands[0], operands[1])
24481 && !reg_overlap_mentioned_p (operands[0], operands[2])
24482 && !reg_overlap_mentioned_p (operands[4], operands[1])
24483 && ix86_match_ccmode (peep2_next_insn (1),
24484 (GET_CODE (operands[3]) == PLUS
24485 || GET_CODE (operands[3]) == MINUS)
24486 ? CCGOCmode : CCNOmode)"
24487 [(parallel [(set (match_dup 5) (match_dup 7))
24488 (set (match_dup 1) (match_dup 6))])]
24489 {
24490 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24491 operands[6]
24492 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24493 copy_rtx (operands[1]), operands[2]);
24494 operands[7]
24495 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
24496 const0_rtx);
24497 })
24498
24499 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
24500 ;; into x = z; x ^= y; x != z
24501 (define_peephole2
24502 [(set (match_operand:SWI 0 "register_operand")
24503 (match_operand:SWI 1 "memory_operand"))
24504 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
24505 (parallel [(set (match_operand:SWI 4 "register_operand")
24506 (xor:SWI (match_dup 4)
24507 (match_operand:SWI 2 "<nonmemory_operand>")))
24508 (clobber (reg:CC FLAGS_REG))])
24509 (set (match_dup 1) (match_dup 4))
24510 (set (reg:CCZ FLAGS_REG)
24511 (compare:CCZ (match_operand:SWI 5 "register_operand")
24512 (match_operand:SWI 6 "<nonmemory_operand>")))]
24513 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24514 && (REGNO (operands[4]) == REGNO (operands[0])
24515 || REGNO (operands[4]) == REGNO (operands[3]))
24516 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
24517 ? 3 : 0], operands[5])
24518 ? rtx_equal_p (operands[2], operands[6])
24519 : rtx_equal_p (operands[2], operands[5])
24520 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
24521 ? 3 : 0], operands[6]))
24522 && peep2_reg_dead_p (4, operands[4])
24523 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
24524 ? 3 : 0])
24525 && !reg_overlap_mentioned_p (operands[0], operands[1])
24526 && !reg_overlap_mentioned_p (operands[0], operands[2])
24527 && !reg_overlap_mentioned_p (operands[3], operands[0])
24528 && !reg_overlap_mentioned_p (operands[3], operands[1])
24529 && !reg_overlap_mentioned_p (operands[3], operands[2])
24530 && (<MODE>mode != QImode
24531 || immediate_operand (operands[2], QImode)
24532 || any_QIreg_operand (operands[2], QImode))"
24533 [(parallel [(set (match_dup 7) (match_dup 9))
24534 (set (match_dup 1) (match_dup 8))])]
24535 {
24536 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
24537 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
24538 operands[2]);
24539 operands[9]
24540 = gen_rtx_COMPARE (GET_MODE (operands[7]),
24541 copy_rtx (operands[8]),
24542 const0_rtx);
24543 })
24544
24545 (define_peephole2
24546 [(set (match_operand:SWI12 0 "register_operand")
24547 (match_operand:SWI12 1 "memory_operand"))
24548 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
24549 (parallel [(set (match_operand:SI 4 "register_operand")
24550 (xor:SI (match_dup 4)
24551 (match_operand:SI 2 "<nonmemory_operand>")))
24552 (clobber (reg:CC FLAGS_REG))])
24553 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
24554 (set (reg:CCZ FLAGS_REG)
24555 (compare:CCZ (match_operand:SWI12 6 "register_operand")
24556 (match_operand:SWI12 7 "<nonmemory_operand>")))]
24557 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24558 && (REGNO (operands[5]) == REGNO (operands[0])
24559 || REGNO (operands[5]) == REGNO (operands[3]))
24560 && REGNO (operands[5]) == REGNO (operands[4])
24561 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
24562 ? 3 : 0], operands[6])
24563 ? (REG_P (operands[2])
24564 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
24565 : rtx_equal_p (operands[2], operands[7]))
24566 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
24567 ? 3 : 0], operands[7])
24568 && REG_P (operands[2])
24569 && REGNO (operands[2]) == REGNO (operands[6])))
24570 && peep2_reg_dead_p (4, operands[5])
24571 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
24572 ? 3 : 0])
24573 && !reg_overlap_mentioned_p (operands[0], operands[1])
24574 && !reg_overlap_mentioned_p (operands[0], operands[2])
24575 && !reg_overlap_mentioned_p (operands[3], operands[0])
24576 && !reg_overlap_mentioned_p (operands[3], operands[1])
24577 && !reg_overlap_mentioned_p (operands[3], operands[2])
24578 && (<MODE>mode != QImode
24579 || immediate_operand (operands[2], SImode)
24580 || any_QIreg_operand (operands[2], SImode))"
24581 [(parallel [(set (match_dup 8) (match_dup 10))
24582 (set (match_dup 1) (match_dup 9))])]
24583 {
24584 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
24585 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
24586 gen_lowpart (<MODE>mode, operands[2]));
24587 operands[10]
24588 = gen_rtx_COMPARE (GET_MODE (operands[8]),
24589 copy_rtx (operands[9]),
24590 const0_rtx);
24591 })
24592
24593 ;; Attempt to optimize away memory stores of values the memory already
24594 ;; has. See PR79593.
24595 (define_peephole2
24596 [(set (match_operand 0 "register_operand")
24597 (match_operand 1 "memory_operand"))
24598 (set (match_operand 2 "memory_operand") (match_dup 0))]
24599 "!MEM_VOLATILE_P (operands[1])
24600 && !MEM_VOLATILE_P (operands[2])
24601 && rtx_equal_p (operands[1], operands[2])
24602 && !reg_overlap_mentioned_p (operands[0], operands[2])"
24603 [(set (match_dup 0) (match_dup 1))])
24604
24605 ;; Attempt to always use XOR for zeroing registers (including FP modes).
24606 (define_peephole2
24607 [(set (match_operand 0 "general_reg_operand")
24608 (match_operand 1 "const0_operand"))]
24609 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
24610 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24611 && peep2_regno_dead_p (0, FLAGS_REG)"
24612 [(parallel [(set (match_dup 0) (const_int 0))
24613 (clobber (reg:CC FLAGS_REG))])]
24614 "operands[0] = gen_lowpart (word_mode, operands[0]);")
24615
24616 (define_peephole2
24617 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
24618 (const_int 0))]
24619 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24620 && peep2_regno_dead_p (0, FLAGS_REG)"
24621 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
24622 (clobber (reg:CC FLAGS_REG))])])
24623
24624 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
24625 (define_peephole2
24626 [(set (match_operand:SWI248 0 "general_reg_operand")
24627 (const_int -1))]
24628 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
24629 && peep2_regno_dead_p (0, FLAGS_REG)"
24630 [(parallel [(set (match_dup 0) (const_int -1))
24631 (clobber (reg:CC FLAGS_REG))])]
24632 {
24633 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
24634 operands[0] = gen_lowpart (SImode, operands[0]);
24635 })
24636
24637 ;; Attempt to convert simple lea to add/shift.
24638 ;; These can be created by move expanders.
24639 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
24640 ;; relevant lea instructions were already split.
24641
24642 (define_peephole2
24643 [(set (match_operand:SWI48 0 "register_operand")
24644 (plus:SWI48 (match_dup 0)
24645 (match_operand:SWI48 1 "<nonmemory_operand>")))]
24646 "!TARGET_OPT_AGU
24647 && peep2_regno_dead_p (0, FLAGS_REG)"
24648 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
24649 (clobber (reg:CC FLAGS_REG))])])
24650
24651 (define_peephole2
24652 [(set (match_operand:SWI48 0 "register_operand")
24653 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
24654 (match_dup 0)))]
24655 "!TARGET_OPT_AGU
24656 && peep2_regno_dead_p (0, FLAGS_REG)"
24657 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
24658 (clobber (reg:CC FLAGS_REG))])])
24659
24660 (define_peephole2
24661 [(set (match_operand:DI 0 "register_operand")
24662 (zero_extend:DI
24663 (plus:SI (match_operand:SI 1 "register_operand")
24664 (match_operand:SI 2 "nonmemory_operand"))))]
24665 "TARGET_64BIT && !TARGET_OPT_AGU
24666 && REGNO (operands[0]) == REGNO (operands[1])
24667 && peep2_regno_dead_p (0, FLAGS_REG)"
24668 [(parallel [(set (match_dup 0)
24669 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
24670 (clobber (reg:CC FLAGS_REG))])])
24671
24672 (define_peephole2
24673 [(set (match_operand:DI 0 "register_operand")
24674 (zero_extend:DI
24675 (plus:SI (match_operand:SI 1 "nonmemory_operand")
24676 (match_operand:SI 2 "register_operand"))))]
24677 "TARGET_64BIT && !TARGET_OPT_AGU
24678 && REGNO (operands[0]) == REGNO (operands[2])
24679 && peep2_regno_dead_p (0, FLAGS_REG)"
24680 [(parallel [(set (match_dup 0)
24681 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
24682 (clobber (reg:CC FLAGS_REG))])])
24683
24684 (define_peephole2
24685 [(set (match_operand:SWI48 0 "register_operand")
24686 (mult:SWI48 (match_dup 0)
24687 (match_operand:SWI48 1 "const_int_operand")))]
24688 "pow2p_hwi (INTVAL (operands[1]))
24689 && peep2_regno_dead_p (0, FLAGS_REG)"
24690 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
24691 (clobber (reg:CC FLAGS_REG))])]
24692 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
24693
24694 (define_peephole2
24695 [(set (match_operand:DI 0 "register_operand")
24696 (zero_extend:DI
24697 (mult:SI (match_operand:SI 1 "register_operand")
24698 (match_operand:SI 2 "const_int_operand"))))]
24699 "TARGET_64BIT
24700 && pow2p_hwi (INTVAL (operands[2]))
24701 && REGNO (operands[0]) == REGNO (operands[1])
24702 && peep2_regno_dead_p (0, FLAGS_REG)"
24703 [(parallel [(set (match_dup 0)
24704 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
24705 (clobber (reg:CC FLAGS_REG))])]
24706 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
24707
24708 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
24709 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
24710 ;; On many CPUs it is also faster, since special hardware to avoid esp
24711 ;; dependencies is present.
24712
24713 ;; While some of these conversions may be done using splitters, we use
24714 ;; peepholes in order to allow combine_stack_adjustments pass to see
24715 ;; nonobfuscated RTL.
24716
24717 ;; Convert prologue esp subtractions to push.
24718 ;; We need register to push. In order to keep verify_flow_info happy we have
24719 ;; two choices
24720 ;; - use scratch and clobber it in order to avoid dependencies
24721 ;; - use already live register
24722 ;; We can't use the second way right now, since there is no reliable way how to
24723 ;; verify that given register is live. First choice will also most likely in
24724 ;; fewer dependencies. On the place of esp adjustments it is very likely that
24725 ;; call clobbered registers are dead. We may want to use base pointer as an
24726 ;; alternative when no register is available later.
24727
24728 (define_peephole2
24729 [(match_scratch:W 1 "r")
24730 (parallel [(set (reg:P SP_REG)
24731 (plus:P (reg:P SP_REG)
24732 (match_operand:P 0 "const_int_operand")))
24733 (clobber (reg:CC FLAGS_REG))
24734 (clobber (mem:BLK (scratch)))])]
24735 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
24736 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
24737 && !ix86_red_zone_used"
24738 [(clobber (match_dup 1))
24739 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24740 (clobber (mem:BLK (scratch)))])])
24741
24742 (define_peephole2
24743 [(match_scratch:W 1 "r")
24744 (parallel [(set (reg:P SP_REG)
24745 (plus:P (reg:P SP_REG)
24746 (match_operand:P 0 "const_int_operand")))
24747 (clobber (reg:CC FLAGS_REG))
24748 (clobber (mem:BLK (scratch)))])]
24749 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
24750 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
24751 && !ix86_red_zone_used"
24752 [(clobber (match_dup 1))
24753 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24754 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24755 (clobber (mem:BLK (scratch)))])])
24756
24757 ;; Convert esp subtractions to push.
24758 (define_peephole2
24759 [(match_scratch:W 1 "r")
24760 (parallel [(set (reg:P SP_REG)
24761 (plus:P (reg:P SP_REG)
24762 (match_operand:P 0 "const_int_operand")))
24763 (clobber (reg:CC FLAGS_REG))])]
24764 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
24765 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
24766 && !ix86_red_zone_used"
24767 [(clobber (match_dup 1))
24768 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
24769
24770 (define_peephole2
24771 [(match_scratch:W 1 "r")
24772 (parallel [(set (reg:P SP_REG)
24773 (plus:P (reg:P SP_REG)
24774 (match_operand:P 0 "const_int_operand")))
24775 (clobber (reg:CC FLAGS_REG))])]
24776 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
24777 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
24778 && !ix86_red_zone_used"
24779 [(clobber (match_dup 1))
24780 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24781 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
24782
24783 ;; Convert epilogue deallocator to pop.
24784 (define_peephole2
24785 [(match_scratch:W 1 "r")
24786 (parallel [(set (reg:P SP_REG)
24787 (plus:P (reg:P SP_REG)
24788 (match_operand:P 0 "const_int_operand")))
24789 (clobber (reg:CC FLAGS_REG))
24790 (clobber (mem:BLK (scratch)))])]
24791 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
24792 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
24793 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24794 (clobber (mem:BLK (scratch)))])])
24795
24796 ;; Two pops case is tricky, since pop causes dependency
24797 ;; on destination register. We use two registers if available.
24798 (define_peephole2
24799 [(match_scratch:W 1 "r")
24800 (match_scratch:W 2 "r")
24801 (parallel [(set (reg:P SP_REG)
24802 (plus:P (reg:P SP_REG)
24803 (match_operand:P 0 "const_int_operand")))
24804 (clobber (reg:CC FLAGS_REG))
24805 (clobber (mem:BLK (scratch)))])]
24806 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
24807 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24808 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24809 (clobber (mem:BLK (scratch)))])
24810 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
24811
24812 (define_peephole2
24813 [(match_scratch:W 1 "r")
24814 (parallel [(set (reg:P SP_REG)
24815 (plus:P (reg:P SP_REG)
24816 (match_operand:P 0 "const_int_operand")))
24817 (clobber (reg:CC FLAGS_REG))
24818 (clobber (mem:BLK (scratch)))])]
24819 "optimize_insn_for_size_p ()
24820 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24821 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24822 (clobber (mem:BLK (scratch)))])
24823 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
24824
24825 ;; Convert esp additions to pop.
24826 (define_peephole2
24827 [(match_scratch:W 1 "r")
24828 (parallel [(set (reg:P SP_REG)
24829 (plus:P (reg:P SP_REG)
24830 (match_operand:P 0 "const_int_operand")))
24831 (clobber (reg:CC FLAGS_REG))])]
24832 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
24833 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
24834
24835 ;; Two pops case is tricky, since pop causes dependency
24836 ;; on destination register. We use two registers if available.
24837 (define_peephole2
24838 [(match_scratch:W 1 "r")
24839 (match_scratch:W 2 "r")
24840 (parallel [(set (reg:P SP_REG)
24841 (plus:P (reg:P SP_REG)
24842 (match_operand:P 0 "const_int_operand")))
24843 (clobber (reg:CC FLAGS_REG))])]
24844 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24845 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24846 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
24847
24848 (define_peephole2
24849 [(match_scratch:W 1 "r")
24850 (parallel [(set (reg:P SP_REG)
24851 (plus:P (reg:P SP_REG)
24852 (match_operand:P 0 "const_int_operand")))
24853 (clobber (reg:CC FLAGS_REG))])]
24854 "optimize_insn_for_size_p ()
24855 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24856 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24857 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
24858 \f
24859 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
24860 ;; required and register dies. Similarly for 128 to -128.
24861 (define_peephole2
24862 [(set (match_operand 0 "flags_reg_operand")
24863 (match_operator 1 "compare_operator"
24864 [(match_operand 2 "register_operand")
24865 (match_operand 3 "const_int_operand")]))]
24866 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
24867 && incdec_operand (operands[3], GET_MODE (operands[3])))
24868 || (!TARGET_FUSE_CMP_AND_BRANCH
24869 && INTVAL (operands[3]) == 128))
24870 && ix86_match_ccmode (insn, CCGCmode)
24871 && peep2_reg_dead_p (1, operands[2])"
24872 [(parallel [(set (match_dup 0)
24873 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
24874 (clobber (match_dup 2))])])
24875 \f
24876 ;; Convert imul by three, five and nine into lea
24877 (define_peephole2
24878 [(parallel
24879 [(set (match_operand:SWI48 0 "register_operand")
24880 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
24881 (match_operand:SWI48 2 "const359_operand")))
24882 (clobber (reg:CC FLAGS_REG))])]
24883 "!TARGET_PARTIAL_REG_STALL
24884 || <MODE>mode == SImode
24885 || optimize_function_for_size_p (cfun)"
24886 [(set (match_dup 0)
24887 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
24888 (match_dup 1)))]
24889 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
24890
24891 (define_peephole2
24892 [(parallel
24893 [(set (match_operand:SWI48 0 "register_operand")
24894 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
24895 (match_operand:SWI48 2 "const359_operand")))
24896 (clobber (reg:CC FLAGS_REG))])]
24897 "optimize_insn_for_speed_p ()
24898 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
24899 [(set (match_dup 0) (match_dup 1))
24900 (set (match_dup 0)
24901 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
24902 (match_dup 0)))]
24903 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
24904
24905 ;; imul $32bit_imm, mem, reg is vector decoded, while
24906 ;; imul $32bit_imm, reg, reg is direct decoded.
24907 (define_peephole2
24908 [(match_scratch:SWI48 3 "r")
24909 (parallel [(set (match_operand:SWI48 0 "register_operand")
24910 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
24911 (match_operand:SWI48 2 "immediate_operand")))
24912 (clobber (reg:CC FLAGS_REG))])]
24913 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
24914 && !satisfies_constraint_K (operands[2])"
24915 [(set (match_dup 3) (match_dup 1))
24916 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
24917 (clobber (reg:CC FLAGS_REG))])])
24918
24919 (define_peephole2
24920 [(match_scratch:SI 3 "r")
24921 (parallel [(set (match_operand:DI 0 "register_operand")
24922 (zero_extend:DI
24923 (mult:SI (match_operand:SI 1 "memory_operand")
24924 (match_operand:SI 2 "immediate_operand"))))
24925 (clobber (reg:CC FLAGS_REG))])]
24926 "TARGET_64BIT
24927 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
24928 && !satisfies_constraint_K (operands[2])"
24929 [(set (match_dup 3) (match_dup 1))
24930 (parallel [(set (match_dup 0)
24931 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
24932 (clobber (reg:CC FLAGS_REG))])])
24933
24934 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
24935 ;; Convert it into imul reg, reg
24936 ;; It would be better to force assembler to encode instruction using long
24937 ;; immediate, but there is apparently no way to do so.
24938 (define_peephole2
24939 [(parallel [(set (match_operand:SWI248 0 "register_operand")
24940 (mult:SWI248
24941 (match_operand:SWI248 1 "nonimmediate_operand")
24942 (match_operand:SWI248 2 "const_int_operand")))
24943 (clobber (reg:CC FLAGS_REG))])
24944 (match_scratch:SWI248 3 "r")]
24945 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
24946 && satisfies_constraint_K (operands[2])"
24947 [(set (match_dup 3) (match_dup 2))
24948 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
24949 (clobber (reg:CC FLAGS_REG))])]
24950 {
24951 if (!rtx_equal_p (operands[0], operands[1]))
24952 emit_move_insn (operands[0], operands[1]);
24953 })
24954
24955 ;; After splitting up read-modify operations, array accesses with memory
24956 ;; operands might end up in form:
24957 ;; sall $2, %eax
24958 ;; movl 4(%esp), %edx
24959 ;; addl %edx, %eax
24960 ;; instead of pre-splitting:
24961 ;; sall $2, %eax
24962 ;; addl 4(%esp), %eax
24963 ;; Turn it into:
24964 ;; movl 4(%esp), %edx
24965 ;; leal (%edx,%eax,4), %eax
24966
24967 (define_peephole2
24968 [(match_scratch:W 5 "r")
24969 (parallel [(set (match_operand 0 "register_operand")
24970 (ashift (match_operand 1 "register_operand")
24971 (match_operand 2 "const_int_operand")))
24972 (clobber (reg:CC FLAGS_REG))])
24973 (parallel [(set (match_operand 3 "register_operand")
24974 (plus (match_dup 0)
24975 (match_operand 4 "x86_64_general_operand")))
24976 (clobber (reg:CC FLAGS_REG))])]
24977 "IN_RANGE (INTVAL (operands[2]), 1, 3)
24978 /* Validate MODE for lea. */
24979 && ((!TARGET_PARTIAL_REG_STALL
24980 && (GET_MODE (operands[0]) == QImode
24981 || GET_MODE (operands[0]) == HImode))
24982 || GET_MODE (operands[0]) == SImode
24983 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
24984 && (rtx_equal_p (operands[0], operands[3])
24985 || peep2_reg_dead_p (2, operands[0]))
24986 /* We reorder load and the shift. */
24987 && !reg_overlap_mentioned_p (operands[0], operands[4])"
24988 [(set (match_dup 5) (match_dup 4))
24989 (set (match_dup 0) (match_dup 1))]
24990 {
24991 machine_mode op1mode = GET_MODE (operands[1]);
24992 machine_mode mode = op1mode == DImode ? DImode : SImode;
24993 int scale = 1 << INTVAL (operands[2]);
24994 rtx index = gen_lowpart (word_mode, operands[1]);
24995 rtx base = gen_lowpart (word_mode, operands[5]);
24996 rtx dest = gen_lowpart (mode, operands[3]);
24997
24998 operands[1] = gen_rtx_PLUS (word_mode, base,
24999 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25000 if (mode != word_mode)
25001 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25002
25003 operands[5] = base;
25004 if (op1mode != word_mode)
25005 operands[5] = gen_lowpart (op1mode, operands[5]);
25006
25007 operands[0] = dest;
25008 })
25009 \f
25010 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25011 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25012 ;; caught for use by garbage collectors and the like. Using an insn that
25013 ;; maps to SIGILL makes it more likely the program will rightfully die.
25014 ;; Keeping with tradition, "6" is in honor of #UD.
25015 (define_insn "trap"
25016 [(trap_if (const_int 1) (const_int 6))]
25017 ""
25018 {
25019 #ifdef HAVE_AS_IX86_UD2
25020 return "ud2";
25021 #else
25022 return ASM_SHORT "0x0b0f";
25023 #endif
25024 }
25025 [(set_attr "length" "2")])
25026
25027 (define_insn "ud2"
25028 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25029 ""
25030 {
25031 #ifdef HAVE_AS_IX86_UD2
25032 return "ud2";
25033 #else
25034 return ASM_SHORT "0x0b0f";
25035 #endif
25036 }
25037 [(set_attr "length" "2")])
25038
25039 (define_expand "prefetch"
25040 [(prefetch (match_operand 0 "address_operand")
25041 (match_operand:SI 1 "const_int_operand")
25042 (match_operand:SI 2 "const_int_operand"))]
25043 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25044 {
25045 bool write = operands[1] != const0_rtx;
25046 int locality = INTVAL (operands[2]);
25047
25048 gcc_assert (IN_RANGE (locality, 0, 3));
25049
25050 /* Use 3dNOW prefetch in case we are asking for write prefetch not
25051 supported by SSE counterpart (non-SSE2 athlon machines) or the
25052 SSE prefetch is not available (K6 machines). Otherwise use SSE
25053 prefetch as it allows specifying of locality. */
25054
25055 if (write)
25056 {
25057 if (TARGET_PREFETCHWT1)
25058 operands[2] = GEN_INT (MAX (locality, 2));
25059 else if (TARGET_PRFCHW)
25060 operands[2] = GEN_INT (3);
25061 else if (TARGET_3DNOW && !TARGET_SSE2)
25062 operands[2] = GEN_INT (3);
25063 else if (TARGET_PREFETCH_SSE)
25064 operands[1] = const0_rtx;
25065 else
25066 {
25067 gcc_assert (TARGET_3DNOW);
25068 operands[2] = GEN_INT (3);
25069 }
25070 }
25071 else
25072 {
25073 if (TARGET_PREFETCH_SSE)
25074 ;
25075 else
25076 {
25077 gcc_assert (TARGET_3DNOW);
25078 operands[2] = GEN_INT (3);
25079 }
25080 }
25081 })
25082
25083 (define_insn "*prefetch_sse"
25084 [(prefetch (match_operand 0 "address_operand" "p")
25085 (const_int 0)
25086 (match_operand:SI 1 "const_int_operand"))]
25087 "TARGET_PREFETCH_SSE"
25088 {
25089 static const char * const patterns[4] = {
25090 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25091 };
25092
25093 int locality = INTVAL (operands[1]);
25094 gcc_assert (IN_RANGE (locality, 0, 3));
25095
25096 return patterns[locality];
25097 }
25098 [(set_attr "type" "sse")
25099 (set_attr "atom_sse_attr" "prefetch")
25100 (set (attr "length_address")
25101 (symbol_ref "memory_address_length (operands[0], false)"))
25102 (set_attr "memory" "none")])
25103
25104 (define_insn "*prefetch_3dnow"
25105 [(prefetch (match_operand 0 "address_operand" "p")
25106 (match_operand:SI 1 "const_int_operand")
25107 (const_int 3))]
25108 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25109 {
25110 if (operands[1] == const0_rtx)
25111 return "prefetch\t%a0";
25112 else
25113 return "prefetchw\t%a0";
25114 }
25115 [(set_attr "type" "mmx")
25116 (set (attr "length_address")
25117 (symbol_ref "memory_address_length (operands[0], false)"))
25118 (set_attr "memory" "none")])
25119
25120 (define_insn "*prefetch_prefetchwt1"
25121 [(prefetch (match_operand 0 "address_operand" "p")
25122 (const_int 1)
25123 (const_int 2))]
25124 "TARGET_PREFETCHWT1"
25125 "prefetchwt1\t%a0";
25126 [(set_attr "type" "sse")
25127 (set (attr "length_address")
25128 (symbol_ref "memory_address_length (operands[0], false)"))
25129 (set_attr "memory" "none")])
25130
25131 (define_insn "prefetchi"
25132 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
25133 (match_operand:SI 1 "const_int_operand")]
25134 UNSPECV_PREFETCHI)]
25135 "TARGET_PREFETCHI && TARGET_64BIT"
25136 {
25137 static const char * const patterns[2] = {
25138 "prefetchit1\t%0", "prefetchit0\t%0"
25139 };
25140
25141 int locality = INTVAL (operands[1]);
25142 gcc_assert (IN_RANGE (locality, 2, 3));
25143
25144 return patterns[locality - 2];
25145 }
25146 [(set_attr "type" "sse")
25147 (set (attr "length_address")
25148 (symbol_ref "memory_address_length (operands[0], false)"))
25149 (set_attr "memory" "none")])
25150
25151 (define_expand "stack_protect_set"
25152 [(match_operand 0 "memory_operand")
25153 (match_operand 1 "memory_operand")]
25154 ""
25155 {
25156 emit_insn (gen_stack_protect_set_1
25157 (ptr_mode, operands[0], operands[1]));
25158 DONE;
25159 })
25160
25161 (define_insn "@stack_protect_set_1_<mode>"
25162 [(set (match_operand:PTR 0 "memory_operand" "=m")
25163 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
25164 UNSPEC_SP_SET))
25165 (set (match_scratch:PTR 2 "=&r") (const_int 0))
25166 (clobber (reg:CC FLAGS_REG))]
25167 ""
25168 {
25169 output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
25170 output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
25171 return "xor{l}\t%k2, %k2";
25172 }
25173 [(set_attr "type" "multi")])
25174
25175 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
25176 ;; immediately followed by *mov{s,d}i_internal to the same register,
25177 ;; where we can avoid the xor{l} above. We don't split this, so that
25178 ;; scheduling or anything else doesn't separate the *stack_protect_set*
25179 ;; pattern from the set of the register that overwrites the register
25180 ;; with a new value.
25181 (define_insn "*stack_protect_set_2_<mode>"
25182 [(set (match_operand:PTR 0 "memory_operand" "=m")
25183 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25184 UNSPEC_SP_SET))
25185 (set (match_operand:SI 1 "register_operand" "=&r")
25186 (match_operand:SI 2 "general_operand" "g"))
25187 (clobber (reg:CC FLAGS_REG))]
25188 "reload_completed
25189 && !reg_overlap_mentioned_p (operands[1], operands[2])"
25190 {
25191 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25192 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25193 if (pic_32bit_operand (operands[2], SImode)
25194 || ix86_use_lea_for_mov (insn, operands + 1))
25195 return "lea{l}\t{%E2, %1|%1, %E2}";
25196 else
25197 return "mov{l}\t{%2, %1|%1, %2}";
25198 }
25199 [(set_attr "type" "multi")
25200 (set_attr "length" "24")])
25201
25202 (define_peephole2
25203 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25204 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25205 UNSPEC_SP_SET))
25206 (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
25207 (clobber (reg:CC FLAGS_REG))])
25208 (set (match_operand:SI 3 "general_reg_operand")
25209 (match_operand:SI 4))]
25210 "REGNO (operands[2]) == REGNO (operands[3])
25211 && general_operand (operands[4], SImode)
25212 && (general_reg_operand (operands[4], SImode)
25213 || memory_operand (operands[4], SImode)
25214 || immediate_operand (operands[4], SImode))
25215 && !reg_overlap_mentioned_p (operands[3], operands[4])"
25216 [(parallel [(set (match_dup 0)
25217 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25218 (set (match_dup 3) (match_dup 4))
25219 (clobber (reg:CC FLAGS_REG))])])
25220
25221 (define_insn "*stack_protect_set_3"
25222 [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
25223 (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
25224 UNSPEC_SP_SET))
25225 (set (match_operand:DI 1 "register_operand" "=&r,r,r")
25226 (match_operand:DI 2 "general_operand" "Z,rem,i"))
25227 (clobber (reg:CC FLAGS_REG))]
25228 "TARGET_64BIT
25229 && reload_completed
25230 && !reg_overlap_mentioned_p (operands[1], operands[2])"
25231 {
25232 output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
25233 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
25234 if (pic_32bit_operand (operands[2], DImode))
25235 return "lea{q}\t{%E2, %1|%1, %E2}";
25236 else if (which_alternative == 0)
25237 return "mov{l}\t{%k2, %k1|%k1, %k2}";
25238 else if (which_alternative == 2)
25239 return "movabs{q}\t{%2, %1|%1, %2}";
25240 else if (ix86_use_lea_for_mov (insn, operands + 1))
25241 return "lea{q}\t{%E2, %1|%1, %E2}";
25242 else
25243 return "mov{q}\t{%2, %1|%1, %2}";
25244 }
25245 [(set_attr "type" "multi")
25246 (set_attr "length" "24")])
25247
25248 (define_peephole2
25249 [(parallel [(set (match_operand:DI 0 "memory_operand")
25250 (unspec:DI [(match_operand:DI 1 "memory_operand")]
25251 UNSPEC_SP_SET))
25252 (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
25253 (clobber (reg:CC FLAGS_REG))])
25254 (set (match_dup 2) (match_operand:DI 3))]
25255 "TARGET_64BIT
25256 && general_operand (operands[3], DImode)
25257 && (general_reg_operand (operands[3], DImode)
25258 || memory_operand (operands[3], DImode)
25259 || x86_64_zext_immediate_operand (operands[3], DImode)
25260 || x86_64_immediate_operand (operands[3], DImode)
25261 || (CONSTANT_P (operands[3])
25262 && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
25263 && !reg_overlap_mentioned_p (operands[2], operands[3])"
25264 [(parallel [(set (match_dup 0)
25265 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25266 (set (match_dup 2) (match_dup 3))
25267 (clobber (reg:CC FLAGS_REG))])])
25268
25269 (define_expand "stack_protect_test"
25270 [(match_operand 0 "memory_operand")
25271 (match_operand 1 "memory_operand")
25272 (match_operand 2)]
25273 ""
25274 {
25275 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
25276
25277 emit_insn (gen_stack_protect_test_1
25278 (ptr_mode, flags, operands[0], operands[1]));
25279
25280 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
25281 flags, const0_rtx, operands[2]));
25282 DONE;
25283 })
25284
25285 (define_insn "@stack_protect_test_1_<mode>"
25286 [(set (match_operand:CCZ 0 "flags_reg_operand")
25287 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
25288 (match_operand:PTR 2 "memory_operand" "m")]
25289 UNSPEC_SP_TEST))
25290 (clobber (match_scratch:PTR 3 "=&r"))]
25291 ""
25292 {
25293 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
25294 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
25295 }
25296 [(set_attr "type" "multi")])
25297
25298 (define_insn "sse4_2_crc32<mode>"
25299 [(set (match_operand:SI 0 "register_operand" "=r")
25300 (unspec:SI
25301 [(match_operand:SI 1 "register_operand" "0")
25302 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
25303 UNSPEC_CRC32))]
25304 "TARGET_CRC32"
25305 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
25306 [(set_attr "type" "sselog1")
25307 (set_attr "prefix_rep" "1")
25308 (set_attr "prefix_extra" "1")
25309 (set (attr "prefix_data16")
25310 (if_then_else (match_operand:HI 2)
25311 (const_string "1")
25312 (const_string "*")))
25313 (set (attr "prefix_rex")
25314 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
25315 (const_string "1")
25316 (const_string "*")))
25317 (set_attr "mode" "SI")])
25318
25319 (define_insn "sse4_2_crc32di"
25320 [(set (match_operand:DI 0 "register_operand" "=r")
25321 (zero_extend:DI
25322 (unspec:SI
25323 [(match_operand:SI 1 "register_operand" "0")
25324 (match_operand:DI 2 "nonimmediate_operand" "rm")]
25325 UNSPEC_CRC32)))]
25326 "TARGET_64BIT && TARGET_CRC32"
25327 "crc32{q}\t{%2, %0|%0, %2}"
25328 [(set_attr "type" "sselog1")
25329 (set_attr "prefix_rep" "1")
25330 (set_attr "prefix_extra" "1")
25331 (set_attr "mode" "DI")])
25332
25333 (define_insn "rdpmc"
25334 [(set (match_operand:DI 0 "register_operand" "=A")
25335 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25336 UNSPECV_RDPMC))]
25337 "!TARGET_64BIT"
25338 "rdpmc"
25339 [(set_attr "type" "other")
25340 (set_attr "length" "2")])
25341
25342 (define_insn "rdpmc_rex64"
25343 [(set (match_operand:DI 0 "register_operand" "=a")
25344 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25345 UNSPECV_RDPMC))
25346 (set (match_operand:DI 1 "register_operand" "=d")
25347 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
25348 "TARGET_64BIT"
25349 "rdpmc"
25350 [(set_attr "type" "other")
25351 (set_attr "length" "2")])
25352
25353 (define_insn "rdtsc"
25354 [(set (match_operand:DI 0 "register_operand" "=A")
25355 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25356 "!TARGET_64BIT"
25357 "rdtsc"
25358 [(set_attr "type" "other")
25359 (set_attr "length" "2")])
25360
25361 (define_insn "rdtsc_rex64"
25362 [(set (match_operand:DI 0 "register_operand" "=a")
25363 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
25364 (set (match_operand:DI 1 "register_operand" "=d")
25365 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25366 "TARGET_64BIT"
25367 "rdtsc"
25368 [(set_attr "type" "other")
25369 (set_attr "length" "2")])
25370
25371 (define_insn "rdtscp"
25372 [(set (match_operand:DI 0 "register_operand" "=A")
25373 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25374 (set (match_operand:SI 1 "register_operand" "=c")
25375 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25376 "!TARGET_64BIT"
25377 "rdtscp"
25378 [(set_attr "type" "other")
25379 (set_attr "length" "3")])
25380
25381 (define_insn "rdtscp_rex64"
25382 [(set (match_operand:DI 0 "register_operand" "=a")
25383 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25384 (set (match_operand:DI 1 "register_operand" "=d")
25385 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25386 (set (match_operand:SI 2 "register_operand" "=c")
25387 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25388 "TARGET_64BIT"
25389 "rdtscp"
25390 [(set_attr "type" "other")
25391 (set_attr "length" "3")])
25392
25393 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25394 ;;
25395 ;; FXSR, XSAVE and XSAVEOPT instructions
25396 ;;
25397 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25398
25399 (define_insn "fxsave"
25400 [(set (match_operand:BLK 0 "memory_operand" "=m")
25401 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
25402 "TARGET_FXSR"
25403 "fxsave\t%0"
25404 [(set_attr "type" "other")
25405 (set_attr "memory" "store")
25406 (set (attr "length")
25407 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25408
25409 (define_insn "fxsave64"
25410 [(set (match_operand:BLK 0 "memory_operand" "=m")
25411 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
25412 "TARGET_64BIT && TARGET_FXSR"
25413 "fxsave64\t%0"
25414 [(set_attr "type" "other")
25415 (set_attr "memory" "store")
25416 (set (attr "length")
25417 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25418
25419 (define_insn "fxrstor"
25420 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25421 UNSPECV_FXRSTOR)]
25422 "TARGET_FXSR"
25423 "fxrstor\t%0"
25424 [(set_attr "type" "other")
25425 (set_attr "memory" "load")
25426 (set (attr "length")
25427 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25428
25429 (define_insn "fxrstor64"
25430 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25431 UNSPECV_FXRSTOR64)]
25432 "TARGET_64BIT && TARGET_FXSR"
25433 "fxrstor64\t%0"
25434 [(set_attr "type" "other")
25435 (set_attr "memory" "load")
25436 (set (attr "length")
25437 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25438
25439 (define_int_iterator ANY_XSAVE
25440 [UNSPECV_XSAVE
25441 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
25442 (UNSPECV_XSAVEC "TARGET_XSAVEC")
25443 (UNSPECV_XSAVES "TARGET_XSAVES")])
25444
25445 (define_int_iterator ANY_XSAVE64
25446 [UNSPECV_XSAVE64
25447 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
25448 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
25449 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
25450
25451 (define_int_attr xsave
25452 [(UNSPECV_XSAVE "xsave")
25453 (UNSPECV_XSAVE64 "xsave64")
25454 (UNSPECV_XSAVEOPT "xsaveopt")
25455 (UNSPECV_XSAVEOPT64 "xsaveopt64")
25456 (UNSPECV_XSAVEC "xsavec")
25457 (UNSPECV_XSAVEC64 "xsavec64")
25458 (UNSPECV_XSAVES "xsaves")
25459 (UNSPECV_XSAVES64 "xsaves64")])
25460
25461 (define_int_iterator ANY_XRSTOR
25462 [UNSPECV_XRSTOR
25463 (UNSPECV_XRSTORS "TARGET_XSAVES")])
25464
25465 (define_int_iterator ANY_XRSTOR64
25466 [UNSPECV_XRSTOR64
25467 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
25468
25469 (define_int_attr xrstor
25470 [(UNSPECV_XRSTOR "xrstor")
25471 (UNSPECV_XRSTOR64 "xrstor")
25472 (UNSPECV_XRSTORS "xrstors")
25473 (UNSPECV_XRSTORS64 "xrstors")])
25474
25475 (define_insn "<xsave>"
25476 [(set (match_operand:BLK 0 "memory_operand" "=m")
25477 (unspec_volatile:BLK
25478 [(match_operand:DI 1 "register_operand" "A")]
25479 ANY_XSAVE))]
25480 "!TARGET_64BIT && TARGET_XSAVE"
25481 "<xsave>\t%0"
25482 [(set_attr "type" "other")
25483 (set_attr "memory" "store")
25484 (set (attr "length")
25485 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25486
25487 (define_insn "<xsave>_rex64"
25488 [(set (match_operand:BLK 0 "memory_operand" "=m")
25489 (unspec_volatile:BLK
25490 [(match_operand:SI 1 "register_operand" "a")
25491 (match_operand:SI 2 "register_operand" "d")]
25492 ANY_XSAVE))]
25493 "TARGET_64BIT && TARGET_XSAVE"
25494 "<xsave>\t%0"
25495 [(set_attr "type" "other")
25496 (set_attr "memory" "store")
25497 (set (attr "length")
25498 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25499
25500 (define_insn "<xsave>"
25501 [(set (match_operand:BLK 0 "memory_operand" "=m")
25502 (unspec_volatile:BLK
25503 [(match_operand:SI 1 "register_operand" "a")
25504 (match_operand:SI 2 "register_operand" "d")]
25505 ANY_XSAVE64))]
25506 "TARGET_64BIT && TARGET_XSAVE"
25507 "<xsave>\t%0"
25508 [(set_attr "type" "other")
25509 (set_attr "memory" "store")
25510 (set (attr "length")
25511 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25512
25513 (define_insn "<xrstor>"
25514 [(unspec_volatile:BLK
25515 [(match_operand:BLK 0 "memory_operand" "m")
25516 (match_operand:DI 1 "register_operand" "A")]
25517 ANY_XRSTOR)]
25518 "!TARGET_64BIT && TARGET_XSAVE"
25519 "<xrstor>\t%0"
25520 [(set_attr "type" "other")
25521 (set_attr "memory" "load")
25522 (set (attr "length")
25523 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25524
25525 (define_insn "<xrstor>_rex64"
25526 [(unspec_volatile:BLK
25527 [(match_operand:BLK 0 "memory_operand" "m")
25528 (match_operand:SI 1 "register_operand" "a")
25529 (match_operand:SI 2 "register_operand" "d")]
25530 ANY_XRSTOR)]
25531 "TARGET_64BIT && TARGET_XSAVE"
25532 "<xrstor>\t%0"
25533 [(set_attr "type" "other")
25534 (set_attr "memory" "load")
25535 (set (attr "length")
25536 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25537
25538 (define_insn "<xrstor>64"
25539 [(unspec_volatile:BLK
25540 [(match_operand:BLK 0 "memory_operand" "m")
25541 (match_operand:SI 1 "register_operand" "a")
25542 (match_operand:SI 2 "register_operand" "d")]
25543 ANY_XRSTOR64)]
25544 "TARGET_64BIT && TARGET_XSAVE"
25545 "<xrstor>64\t%0"
25546 [(set_attr "type" "other")
25547 (set_attr "memory" "load")
25548 (set (attr "length")
25549 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25550
25551 (define_insn "xsetbv"
25552 [(unspec_volatile:SI
25553 [(match_operand:SI 0 "register_operand" "c")
25554 (match_operand:DI 1 "register_operand" "A")]
25555 UNSPECV_XSETBV)]
25556 "!TARGET_64BIT && TARGET_XSAVE"
25557 "xsetbv"
25558 [(set_attr "type" "other")])
25559
25560 (define_insn "xsetbv_rex64"
25561 [(unspec_volatile:SI
25562 [(match_operand:SI 0 "register_operand" "c")
25563 (match_operand:SI 1 "register_operand" "a")
25564 (match_operand:SI 2 "register_operand" "d")]
25565 UNSPECV_XSETBV)]
25566 "TARGET_64BIT && TARGET_XSAVE"
25567 "xsetbv"
25568 [(set_attr "type" "other")])
25569
25570 (define_insn "xgetbv"
25571 [(set (match_operand:DI 0 "register_operand" "=A")
25572 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25573 UNSPECV_XGETBV))]
25574 "!TARGET_64BIT && TARGET_XSAVE"
25575 "xgetbv"
25576 [(set_attr "type" "other")])
25577
25578 (define_insn "xgetbv_rex64"
25579 [(set (match_operand:DI 0 "register_operand" "=a")
25580 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25581 UNSPECV_XGETBV))
25582 (set (match_operand:DI 1 "register_operand" "=d")
25583 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
25584 "TARGET_64BIT && TARGET_XSAVE"
25585 "xgetbv"
25586 [(set_attr "type" "other")])
25587
25588 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25589 ;;
25590 ;; Floating-point instructions for atomic compound assignments
25591 ;;
25592 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25593
25594 ; Clobber all floating-point registers on environment save and restore
25595 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
25596 (define_insn "fnstenv"
25597 [(set (match_operand:BLK 0 "memory_operand" "=m")
25598 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
25599 (clobber (reg:XF ST0_REG))
25600 (clobber (reg:XF ST1_REG))
25601 (clobber (reg:XF ST2_REG))
25602 (clobber (reg:XF ST3_REG))
25603 (clobber (reg:XF ST4_REG))
25604 (clobber (reg:XF ST5_REG))
25605 (clobber (reg:XF ST6_REG))
25606 (clobber (reg:XF ST7_REG))]
25607 "TARGET_80387"
25608 "fnstenv\t%0"
25609 [(set_attr "type" "other")
25610 (set_attr "memory" "store")
25611 (set (attr "length")
25612 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25613
25614 (define_insn "fldenv"
25615 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25616 UNSPECV_FLDENV)
25617 (clobber (reg:XF ST0_REG))
25618 (clobber (reg:XF ST1_REG))
25619 (clobber (reg:XF ST2_REG))
25620 (clobber (reg:XF ST3_REG))
25621 (clobber (reg:XF ST4_REG))
25622 (clobber (reg:XF ST5_REG))
25623 (clobber (reg:XF ST6_REG))
25624 (clobber (reg:XF ST7_REG))]
25625 "TARGET_80387"
25626 "fldenv\t%0"
25627 [(set_attr "type" "other")
25628 (set_attr "memory" "load")
25629 (set (attr "length")
25630 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25631
25632 (define_insn "fnstsw"
25633 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
25634 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
25635 "TARGET_80387"
25636 "fnstsw\t%0"
25637 [(set_attr "type" "other,other")
25638 (set_attr "memory" "none,store")
25639 (set (attr "length")
25640 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25641
25642 (define_insn "fnclex"
25643 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
25644 "TARGET_80387"
25645 "fnclex"
25646 [(set_attr "type" "other")
25647 (set_attr "memory" "none")
25648 (set_attr "length" "2")])
25649
25650 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25651 ;;
25652 ;; LWP instructions
25653 ;;
25654 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25655
25656 (define_insn "@lwp_llwpcb<mode>"
25657 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
25658 UNSPECV_LLWP_INTRINSIC)]
25659 "TARGET_LWP"
25660 "llwpcb\t%0"
25661 [(set_attr "type" "lwp")
25662 (set_attr "mode" "<MODE>")
25663 (set_attr "length" "5")])
25664
25665 (define_insn "@lwp_slwpcb<mode>"
25666 [(set (match_operand:P 0 "register_operand" "=r")
25667 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
25668 "TARGET_LWP"
25669 "slwpcb\t%0"
25670 [(set_attr "type" "lwp")
25671 (set_attr "mode" "<MODE>")
25672 (set_attr "length" "5")])
25673
25674 (define_insn "@lwp_lwpval<mode>"
25675 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25676 (match_operand:SI 1 "nonimmediate_operand" "rm")
25677 (match_operand:SI 2 "const_int_operand")]
25678 UNSPECV_LWPVAL_INTRINSIC)]
25679 "TARGET_LWP"
25680 "lwpval\t{%2, %1, %0|%0, %1, %2}"
25681 [(set_attr "type" "lwp")
25682 (set_attr "mode" "<MODE>")
25683 (set (attr "length")
25684 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
25685
25686 (define_insn "@lwp_lwpins<mode>"
25687 [(set (reg:CCC FLAGS_REG)
25688 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
25689 (match_operand:SI 1 "nonimmediate_operand" "rm")
25690 (match_operand:SI 2 "const_int_operand")]
25691 UNSPECV_LWPINS_INTRINSIC))]
25692 "TARGET_LWP"
25693 "lwpins\t{%2, %1, %0|%0, %1, %2}"
25694 [(set_attr "type" "lwp")
25695 (set_attr "mode" "<MODE>")
25696 (set (attr "length")
25697 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
25698
25699 (define_int_iterator RDFSGSBASE
25700 [UNSPECV_RDFSBASE
25701 UNSPECV_RDGSBASE])
25702
25703 (define_int_iterator WRFSGSBASE
25704 [UNSPECV_WRFSBASE
25705 UNSPECV_WRGSBASE])
25706
25707 (define_int_attr fsgs
25708 [(UNSPECV_RDFSBASE "fs")
25709 (UNSPECV_RDGSBASE "gs")
25710 (UNSPECV_WRFSBASE "fs")
25711 (UNSPECV_WRGSBASE "gs")])
25712
25713 (define_insn "rd<fsgs>base<mode>"
25714 [(set (match_operand:SWI48 0 "register_operand" "=r")
25715 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
25716 "TARGET_64BIT && TARGET_FSGSBASE"
25717 "rd<fsgs>base\t%0"
25718 [(set_attr "type" "other")
25719 (set_attr "prefix_extra" "2")])
25720
25721 (define_insn "wr<fsgs>base<mode>"
25722 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
25723 WRFSGSBASE)]
25724 "TARGET_64BIT && TARGET_FSGSBASE"
25725 "wr<fsgs>base\t%0"
25726 [(set_attr "type" "other")
25727 (set_attr "prefix_extra" "2")])
25728
25729 (define_insn "ptwrite<mode>"
25730 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
25731 UNSPECV_PTWRITE)]
25732 "TARGET_PTWRITE"
25733 "ptwrite\t%0"
25734 [(set_attr "type" "other")
25735 (set_attr "prefix_extra" "2")])
25736
25737 (define_insn "@rdrand<mode>"
25738 [(set (match_operand:SWI248 0 "register_operand" "=r")
25739 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
25740 (set (reg:CCC FLAGS_REG)
25741 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
25742 "TARGET_RDRND"
25743 "rdrand\t%0"
25744 [(set_attr "type" "other")
25745 (set_attr "prefix_extra" "1")])
25746
25747 (define_insn "@rdseed<mode>"
25748 [(set (match_operand:SWI248 0 "register_operand" "=r")
25749 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
25750 (set (reg:CCC FLAGS_REG)
25751 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
25752 "TARGET_RDSEED"
25753 "rdseed\t%0"
25754 [(set_attr "type" "other")
25755 (set_attr "prefix_extra" "1")])
25756
25757 (define_expand "pause"
25758 [(set (match_dup 0)
25759 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
25760 ""
25761 {
25762 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
25763 MEM_VOLATILE_P (operands[0]) = 1;
25764 })
25765
25766 ;; Use "rep; nop", instead of "pause", to support older assemblers.
25767 ;; They have the same encoding.
25768 (define_insn "*pause"
25769 [(set (match_operand:BLK 0)
25770 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
25771 ""
25772 "rep%; nop"
25773 [(set_attr "length" "2")
25774 (set_attr "memory" "unknown")])
25775
25776 ;; CET instructions
25777 (define_insn "@rdssp<mode>"
25778 [(set (match_operand:SWI48 0 "register_operand" "=r")
25779 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
25780 UNSPECV_NOP_RDSSP))]
25781 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
25782 "rdssp<mskmodesuffix>\t%0"
25783 [(set_attr "length" "6")
25784 (set_attr "type" "other")])
25785
25786 (define_insn "@incssp<mode>"
25787 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
25788 UNSPECV_INCSSP)]
25789 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
25790 "incssp<mskmodesuffix>\t%0"
25791 [(set_attr "length" "4")
25792 (set_attr "type" "other")])
25793
25794 (define_insn "saveprevssp"
25795 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
25796 "TARGET_SHSTK"
25797 "saveprevssp"
25798 [(set_attr "length" "5")
25799 (set_attr "type" "other")])
25800
25801 (define_insn "rstorssp"
25802 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
25803 UNSPECV_RSTORSSP)]
25804 "TARGET_SHSTK"
25805 "rstorssp\t%0"
25806 [(set_attr "length" "5")
25807 (set_attr "type" "other")])
25808
25809 (define_insn "@wrss<mode>"
25810 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25811 (match_operand:SWI48 1 "memory_operand" "m")]
25812 UNSPECV_WRSS)]
25813 "TARGET_SHSTK"
25814 "wrss<mskmodesuffix>\t%0, %1"
25815 [(set_attr "length" "3")
25816 (set_attr "type" "other")])
25817
25818 (define_insn "@wruss<mode>"
25819 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25820 (match_operand:SWI48 1 "memory_operand" "m")]
25821 UNSPECV_WRUSS)]
25822 "TARGET_SHSTK"
25823 "wruss<mskmodesuffix>\t%0, %1"
25824 [(set_attr "length" "4")
25825 (set_attr "type" "other")])
25826
25827 (define_insn "setssbsy"
25828 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
25829 "TARGET_SHSTK"
25830 "setssbsy"
25831 [(set_attr "length" "4")
25832 (set_attr "type" "other")])
25833
25834 (define_insn "clrssbsy"
25835 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
25836 UNSPECV_CLRSSBSY)]
25837 "TARGET_SHSTK"
25838 "clrssbsy\t%0"
25839 [(set_attr "length" "4")
25840 (set_attr "type" "other")])
25841
25842 (define_insn "nop_endbr"
25843 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
25844 "(flag_cf_protection & CF_BRANCH)"
25845 {
25846 return TARGET_64BIT ? "endbr64" : "endbr32";
25847 }
25848 [(set_attr "length" "4")
25849 (set_attr "length_immediate" "0")
25850 (set_attr "modrm" "0")])
25851
25852 ;; For RTM support
25853 (define_expand "xbegin"
25854 [(set (match_operand:SI 0 "register_operand")
25855 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
25856 "TARGET_RTM"
25857 {
25858 rtx_code_label *label = gen_label_rtx ();
25859
25860 /* xbegin is emitted as jump_insn, so reload won't be able
25861 to reload its operand. Force the value into AX hard register. */
25862 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
25863 emit_move_insn (ax_reg, constm1_rtx);
25864
25865 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
25866
25867 emit_label (label);
25868 LABEL_NUSES (label) = 1;
25869
25870 emit_move_insn (operands[0], ax_reg);
25871
25872 DONE;
25873 })
25874
25875 (define_insn "xbegin_1"
25876 [(set (pc)
25877 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
25878 (const_int 0))
25879 (label_ref (match_operand 1))
25880 (pc)))
25881 (set (match_operand:SI 0 "register_operand" "+a")
25882 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
25883 "TARGET_RTM"
25884 "xbegin\t%l1"
25885 [(set_attr "type" "other")
25886 (set_attr "length" "6")])
25887
25888 (define_insn "xend"
25889 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
25890 "TARGET_RTM"
25891 "xend"
25892 [(set_attr "type" "other")
25893 (set_attr "length" "3")])
25894
25895 (define_insn "xabort"
25896 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
25897 UNSPECV_XABORT)]
25898 "TARGET_RTM"
25899 "xabort\t%0"
25900 [(set_attr "type" "other")
25901 (set_attr "length" "3")])
25902
25903 (define_expand "xtest"
25904 [(set (match_operand:QI 0 "register_operand")
25905 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
25906 "TARGET_RTM"
25907 {
25908 emit_insn (gen_xtest_1 ());
25909
25910 ix86_expand_setcc (operands[0], NE,
25911 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
25912 DONE;
25913 })
25914
25915 (define_insn "xtest_1"
25916 [(set (reg:CCZ FLAGS_REG)
25917 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
25918 "TARGET_RTM"
25919 "xtest"
25920 [(set_attr "type" "other")
25921 (set_attr "length" "3")])
25922
25923 (define_insn "clwb"
25924 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
25925 UNSPECV_CLWB)]
25926 "TARGET_CLWB"
25927 "clwb\t%a0"
25928 [(set_attr "type" "sse")
25929 (set_attr "atom_sse_attr" "fence")
25930 (set_attr "memory" "unknown")])
25931
25932 (define_insn "clflushopt"
25933 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
25934 UNSPECV_CLFLUSHOPT)]
25935 "TARGET_CLFLUSHOPT"
25936 "clflushopt\t%a0"
25937 [(set_attr "type" "sse")
25938 (set_attr "atom_sse_attr" "fence")
25939 (set_attr "memory" "unknown")])
25940
25941 ;; MONITORX and MWAITX
25942 (define_insn "mwaitx"
25943 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
25944 (match_operand:SI 1 "register_operand" "a")
25945 (match_operand:SI 2 "register_operand" "b")]
25946 UNSPECV_MWAITX)]
25947 "TARGET_MWAITX"
25948 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
25949 ;; Since 32bit register operands are implicitly zero extended to 64bit,
25950 ;; we only need to set up 32bit registers.
25951 "mwaitx"
25952 [(set_attr "length" "3")])
25953
25954 (define_insn "@monitorx_<mode>"
25955 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
25956 (match_operand:SI 1 "register_operand" "c")
25957 (match_operand:SI 2 "register_operand" "d")]
25958 UNSPECV_MONITORX)]
25959 "TARGET_MWAITX"
25960 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
25961 ;; RCX and RDX are used. Since 32bit register operands are implicitly
25962 ;; zero extended to 64bit, we only need to set up 32bit registers.
25963 "%^monitorx"
25964 [(set (attr "length")
25965 (symbol_ref ("(Pmode != word_mode) + 3")))])
25966
25967 ;; CLZERO
25968 (define_insn "@clzero_<mode>"
25969 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
25970 UNSPECV_CLZERO)]
25971 "TARGET_CLZERO"
25972 "clzero"
25973 [(set_attr "length" "3")
25974 (set_attr "memory" "unknown")])
25975
25976 ;; RDPKRU and WRPKRU
25977
25978 (define_expand "rdpkru"
25979 [(parallel
25980 [(set (match_operand:SI 0 "register_operand")
25981 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
25982 (set (match_dup 2) (const_int 0))])]
25983 "TARGET_PKU"
25984 {
25985 operands[1] = force_reg (SImode, const0_rtx);
25986 operands[2] = gen_reg_rtx (SImode);
25987 })
25988
25989 (define_insn "*rdpkru"
25990 [(set (match_operand:SI 0 "register_operand" "=a")
25991 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
25992 UNSPECV_PKU))
25993 (set (match_operand:SI 1 "register_operand" "=d")
25994 (const_int 0))]
25995 "TARGET_PKU"
25996 "rdpkru"
25997 [(set_attr "type" "other")])
25998
25999 (define_expand "wrpkru"
26000 [(unspec_volatile:SI
26001 [(match_operand:SI 0 "register_operand")
26002 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26003 "TARGET_PKU"
26004 {
26005 operands[1] = force_reg (SImode, const0_rtx);
26006 operands[2] = force_reg (SImode, const0_rtx);
26007 })
26008
26009 (define_insn "*wrpkru"
26010 [(unspec_volatile:SI
26011 [(match_operand:SI 0 "register_operand" "a")
26012 (match_operand:SI 1 "register_operand" "d")
26013 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26014 "TARGET_PKU"
26015 "wrpkru"
26016 [(set_attr "type" "other")])
26017
26018 (define_insn "rdpid"
26019 [(set (match_operand:SI 0 "register_operand" "=r")
26020 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26021 "!TARGET_64BIT && TARGET_RDPID"
26022 "rdpid\t%0"
26023 [(set_attr "type" "other")])
26024
26025 (define_insn "rdpid_rex64"
26026 [(set (match_operand:DI 0 "register_operand" "=r")
26027 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26028 "TARGET_64BIT && TARGET_RDPID"
26029 "rdpid\t%0"
26030 [(set_attr "type" "other")])
26031
26032 ;; Intirinsics for > i486
26033
26034 (define_insn "wbinvd"
26035 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26036 ""
26037 "wbinvd"
26038 [(set_attr "type" "other")])
26039
26040 (define_insn "wbnoinvd"
26041 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26042 "TARGET_WBNOINVD"
26043 "wbnoinvd"
26044 [(set_attr "type" "other")])
26045
26046 ;; MOVDIRI and MOVDIR64B
26047
26048 (define_insn "movdiri<mode>"
26049 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26050 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26051 UNSPEC_MOVDIRI))]
26052 "TARGET_MOVDIRI"
26053 "movdiri\t{%1, %0|%0, %1}"
26054 [(set_attr "type" "other")])
26055
26056 (define_insn "@movdir64b_<mode>"
26057 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26058 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26059 UNSPEC_MOVDIR64B))]
26060 "TARGET_MOVDIR64B"
26061 "movdir64b\t{%1, %0|%0, %1}"
26062 [(set_attr "type" "other")])
26063
26064 ;; TSXLDTRK
26065 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26066 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26067 (UNSPECV_XRESLDTRK "xresldtrk")])
26068 (define_insn "<tsxldtrk>"
26069 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26070 "TARGET_TSXLDTRK"
26071 "<tsxldtrk>"
26072 [(set_attr "type" "other")
26073 (set_attr "length" "4")])
26074
26075 ;; ENQCMD and ENQCMDS
26076
26077 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26078 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26079
26080 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26081 [(set (reg:CCZ FLAGS_REG)
26082 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26083 (match_operand:XI 1 "memory_operand" "m")]
26084 ENQCMD))]
26085 "TARGET_ENQCMD"
26086 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26087 [(set_attr "type" "other")])
26088
26089 ;; UINTR
26090 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26091 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26092
26093 (define_insn "<uintr>"
26094 [(unspec_volatile [(const_int 0)] UINTR)]
26095 "TARGET_UINTR && TARGET_64BIT"
26096 "<uintr>"
26097 [(set_attr "type" "other")
26098 (set_attr "length" "4")])
26099
26100 (define_insn "testui"
26101 [(set (reg:CCC FLAGS_REG)
26102 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26103 "TARGET_UINTR && TARGET_64BIT"
26104 "testui"
26105 [(set_attr "type" "other")
26106 (set_attr "length" "4")])
26107
26108 (define_insn "senduipi"
26109 [(unspec_volatile
26110 [(match_operand:DI 0 "register_operand" "r")]
26111 UNSPECV_SENDUIPI)]
26112 "TARGET_UINTR && TARGET_64BIT"
26113 "senduipi\t%0"
26114 [(set_attr "type" "other")
26115 (set_attr "length" "4")])
26116
26117 ;; WAITPKG
26118
26119 (define_insn "umwait"
26120 [(set (reg:CCC FLAGS_REG)
26121 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26122 (match_operand:DI 1 "register_operand" "A")]
26123 UNSPECV_UMWAIT))]
26124 "!TARGET_64BIT && TARGET_WAITPKG"
26125 "umwait\t%0"
26126 [(set_attr "length" "3")])
26127
26128 (define_insn "umwait_rex64"
26129 [(set (reg:CCC FLAGS_REG)
26130 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26131 (match_operand:SI 1 "register_operand" "a")
26132 (match_operand:SI 2 "register_operand" "d")]
26133 UNSPECV_UMWAIT))]
26134 "TARGET_64BIT && TARGET_WAITPKG"
26135 "umwait\t%0"
26136 [(set_attr "length" "3")])
26137
26138 (define_insn "@umonitor_<mode>"
26139 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26140 UNSPECV_UMONITOR)]
26141 "TARGET_WAITPKG"
26142 "umonitor\t%0"
26143 [(set (attr "length")
26144 (symbol_ref ("(Pmode != word_mode) + 3")))])
26145
26146 (define_insn "tpause"
26147 [(set (reg:CCC FLAGS_REG)
26148 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26149 (match_operand:DI 1 "register_operand" "A")]
26150 UNSPECV_TPAUSE))]
26151 "!TARGET_64BIT && TARGET_WAITPKG"
26152 "tpause\t%0"
26153 [(set_attr "length" "3")])
26154
26155 (define_insn "tpause_rex64"
26156 [(set (reg:CCC FLAGS_REG)
26157 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26158 (match_operand:SI 1 "register_operand" "a")
26159 (match_operand:SI 2 "register_operand" "d")]
26160 UNSPECV_TPAUSE))]
26161 "TARGET_64BIT && TARGET_WAITPKG"
26162 "tpause\t%0"
26163 [(set_attr "length" "3")])
26164
26165 (define_insn "cldemote"
26166 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26167 UNSPECV_CLDEMOTE)]
26168 "TARGET_CLDEMOTE"
26169 "cldemote\t%a0"
26170 [(set_attr "type" "other")
26171 (set_attr "memory" "unknown")])
26172
26173 (define_insn "speculation_barrier"
26174 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26175 ""
26176 "lfence"
26177 [(set_attr "type" "other")
26178 (set_attr "length" "3")])
26179
26180 (define_insn "serialize"
26181 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26182 "TARGET_SERIALIZE"
26183 "serialize"
26184 [(set_attr "type" "other")
26185 (set_attr "length" "3")])
26186
26187 (define_insn "patchable_area"
26188 [(unspec_volatile [(match_operand 0 "const_int_operand")
26189 (match_operand 1 "const_int_operand")]
26190 UNSPECV_PATCHABLE_AREA)]
26191 ""
26192 {
26193 ix86_output_patchable_area (INTVAL (operands[0]),
26194 INTVAL (operands[1]) != 0);
26195 return "";
26196 }
26197 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26198 (set_attr "length_immediate" "0")
26199 (set_attr "modrm" "0")])
26200
26201 (define_insn "hreset"
26202 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26203 UNSPECV_HRESET)]
26204 "TARGET_HRESET"
26205 "hreset\t{$0|0}"
26206 [(set_attr "type" "other")
26207 (set_attr "length" "4")])
26208
26209 ;; Spaceship optimization
26210 (define_expand "spaceship<mode>3"
26211 [(match_operand:SI 0 "register_operand")
26212 (match_operand:MODEF 1 "cmp_fp_expander_operand")
26213 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26214 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26215 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26216 {
26217 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26218 DONE;
26219 })
26220
26221 (define_expand "spaceshipxf3"
26222 [(match_operand:SI 0 "register_operand")
26223 (match_operand:XF 1 "nonmemory_operand")
26224 (match_operand:XF 2 "nonmemory_operand")]
26225 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26226 {
26227 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26228 DONE;
26229 })
26230
26231 ;; Defined because the generic expand_builtin_issignaling for XFmode
26232 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26233 ;; signaling.
26234 (define_expand "issignalingxf2"
26235 [(match_operand:SI 0 "register_operand")
26236 (match_operand:XF 1 "general_operand")]
26237 ""
26238 {
26239 rtx temp = operands[1];
26240 if (!MEM_P (temp))
26241 {
26242 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26243 emit_move_insn (mem, temp);
26244 temp = mem;
26245 }
26246 rtx ex = adjust_address (temp, HImode, 8);
26247 rtx hi = adjust_address (temp, SImode, 4);
26248 rtx lo = adjust_address (temp, SImode, 0);
26249 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26250 rtx mask = GEN_INT (0x7fff);
26251 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26252 /* Expand to:
26253 ((ex & mask) && (int) hi >= 0)
26254 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
26255 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26256 lo = expand_binop (SImode, ior_optab, lo, nlo,
26257 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26258 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26259 temp = expand_binop (SImode, xor_optab, hi, bit,
26260 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26261 temp = expand_binop (SImode, ior_optab, temp, lo,
26262 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26263 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
26264 SImode, 1, 1);
26265 ex = expand_binop (HImode, and_optab, ex, mask,
26266 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26267 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
26268 ex, const0_rtx, SImode, 1, 1);
26269 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
26270 ex, mask, HImode, 1, 1);
26271 temp = expand_binop (SImode, and_optab, temp, ex,
26272 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26273 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
26274 hi, const0_rtx, SImode, 0, 1);
26275 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
26276 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26277 temp = expand_binop (SImode, ior_optab, temp, temp2,
26278 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26279 emit_move_insn (operands[0], temp);
26280 DONE;
26281 })
26282
26283 (include "mmx.md")
26284 (include "sse.md")
26285 (include "sync.md")