]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
4db210cc7959f89917f9a12e7dc583e5116e2695
[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 xchg with a REG_UNUSED note to a mov (variant #1).
3247 (define_peephole2
3248 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3249 (match_operand:SWI 1 "general_reg_operand"))
3250 (set (match_dup 1) (match_dup 0))])]
3251 "((REGNO (operands[0]) != AX_REG
3252 && REGNO (operands[1]) != AX_REG)
3253 || optimize_size < 2
3254 || !optimize_insn_for_size_p ())
3255 && peep2_reg_dead_p (1, operands[0])"
3256 [(set (match_dup 1) (match_dup 0))])
3257
3258 ;; Convert xchg with a REG_UNUSED note to a mov (variant #2).
3259 (define_peephole2
3260 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
3261 (match_operand:SWI 1 "general_reg_operand"))
3262 (set (match_dup 1) (match_dup 0))])]
3263 "((REGNO (operands[0]) != AX_REG
3264 && REGNO (operands[1]) != AX_REG)
3265 || optimize_size < 2
3266 || !optimize_insn_for_size_p ())
3267 && peep2_reg_dead_p (1, operands[1])"
3268 [(set (match_dup 0) (match_dup 1))])
3269
3270 ;; Convert moves to/from AX_REG into xchg with -Oz.
3271 (define_peephole2
3272 [(set (match_operand:SWI48 0 "general_reg_operand")
3273 (match_operand:SWI48 1 "general_reg_operand"))]
3274 "optimize_size > 1
3275 && ((REGNO (operands[0]) == AX_REG)
3276 != (REGNO (operands[1]) == AX_REG))
3277 && optimize_insn_for_size_p ()
3278 && peep2_reg_dead_p (1, operands[1])"
3279 [(parallel [(set (match_dup 0) (match_dup 1))
3280 (set (match_dup 1) (match_dup 0))])])
3281
3282 (define_expand "movstrict<mode>"
3283 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3284 (match_operand:SWI12 1 "general_operand"))]
3285 ""
3286 {
3287 gcc_assert (SUBREG_P (operands[0]));
3288 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3289 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3290 FAIL;
3291 })
3292
3293 (define_insn "*movstrict<mode>_1"
3294 [(set (strict_low_part
3295 (match_operand:SWI12 0 "register_operand" "+<r>"))
3296 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3297 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3298 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3299 [(set_attr "type" "imov")
3300 (set_attr "mode" "<MODE>")])
3301
3302 (define_insn "*movstrict<mode>_xor"
3303 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3304 (match_operand:SWI12 1 "const0_operand"))
3305 (clobber (reg:CC FLAGS_REG))]
3306 "reload_completed"
3307 "xor{<imodesuffix>}\t%0, %0"
3308 [(set_attr "type" "alu1")
3309 (set_attr "mode" "<MODE>")
3310 (set_attr "length_immediate" "0")])
3311
3312 (define_expand "extv<mode>"
3313 [(set (match_operand:SWI24 0 "register_operand")
3314 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3315 (match_operand:SI 2 "const_int_operand")
3316 (match_operand:SI 3 "const_int_operand")))]
3317 ""
3318 {
3319 /* Handle extractions from %ah et al. */
3320 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3321 FAIL;
3322
3323 unsigned int regno = reg_or_subregno (operands[1]);
3324
3325 /* Be careful to expand only with registers having upper parts. */
3326 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3327 operands[1] = copy_to_reg (operands[1]);
3328 })
3329
3330 (define_insn "*extv<mode>"
3331 [(set (match_operand:SWI24 0 "register_operand" "=R")
3332 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3333 (const_int 8)
3334 (const_int 8)))]
3335 ""
3336 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3337 [(set_attr "type" "imovx")
3338 (set_attr "mode" "SI")])
3339
3340 (define_expand "extzv<mode>"
3341 [(set (match_operand:SWI248 0 "register_operand")
3342 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3343 (match_operand:SI 2 "const_int_operand")
3344 (match_operand:SI 3 "const_int_operand")))]
3345 ""
3346 {
3347 if (ix86_expand_pextr (operands))
3348 DONE;
3349
3350 /* Handle extractions from %ah et al. */
3351 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3352 FAIL;
3353
3354 unsigned int regno = reg_or_subregno (operands[1]);
3355
3356 /* Be careful to expand only with registers having upper parts. */
3357 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3358 operands[1] = copy_to_reg (operands[1]);
3359 })
3360
3361 (define_insn "*extzv<mode>"
3362 [(set (match_operand:SWI248 0 "register_operand" "=R")
3363 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3364 (const_int 8)
3365 (const_int 8)))]
3366 ""
3367 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3368 [(set_attr "type" "imovx")
3369 (set_attr "mode" "SI")])
3370
3371 (define_insn "*extzvqi_mem_rex64"
3372 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
3373 (subreg:QI
3374 (match_operator:SWI248 2 "extract_operator"
3375 [(match_operand 1 "int248_register_operand" "Q")
3376 (const_int 8)
3377 (const_int 8)]) 0))]
3378 "TARGET_64BIT && reload_completed"
3379 "mov{b}\t{%h1, %0|%0, %h1}"
3380 [(set_attr "type" "imov")
3381 (set_attr "mode" "QI")])
3382
3383 (define_insn "*extzvqi"
3384 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
3385 (subreg:QI
3386 (match_operator:SWI248 2 "extract_operator"
3387 [(match_operand 1 "int248_register_operand" "Q,Q,Q")
3388 (const_int 8)
3389 (const_int 8)]) 0))]
3390 ""
3391 {
3392 switch (get_attr_type (insn))
3393 {
3394 case TYPE_IMOVX:
3395 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3396 default:
3397 return "mov{b}\t{%h1, %0|%0, %h1}";
3398 }
3399 }
3400 [(set_attr "isa" "*,*,nox64")
3401 (set (attr "type")
3402 (if_then_else (and (match_operand:QI 0 "register_operand")
3403 (ior (not (match_operand:QI 0 "QIreg_operand"))
3404 (match_test "TARGET_MOVX")))
3405 (const_string "imovx")
3406 (const_string "imov")))
3407 (set (attr "mode")
3408 (if_then_else (eq_attr "type" "imovx")
3409 (const_string "SI")
3410 (const_string "QI")))])
3411
3412 (define_peephole2
3413 [(set (match_operand:QI 0 "register_operand")
3414 (subreg:QI
3415 (match_operator:SWI248 3 "extract_operator"
3416 [(match_operand 1 "int248_register_operand")
3417 (const_int 8)
3418 (const_int 8)]) 0))
3419 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
3420 "TARGET_64BIT
3421 && peep2_reg_dead_p (2, operands[0])"
3422 [(set (match_dup 2)
3423 (subreg:QI
3424 (match_op_dup 3
3425 [(match_dup 1)
3426 (const_int 8)
3427 (const_int 8)]) 0))])
3428
3429 (define_expand "insv<mode>"
3430 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3431 (match_operand:SI 1 "const_int_operand")
3432 (match_operand:SI 2 "const_int_operand"))
3433 (match_operand:SWI248 3 "register_operand"))]
3434 ""
3435 {
3436 rtx dst;
3437
3438 if (ix86_expand_pinsr (operands))
3439 DONE;
3440
3441 /* Handle insertions to %ah et al. */
3442 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3443 FAIL;
3444
3445 unsigned int regno = reg_or_subregno (operands[0]);
3446
3447 /* Be careful to expand only with registers having upper parts. */
3448 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3449 dst = copy_to_reg (operands[0]);
3450 else
3451 dst = operands[0];
3452
3453 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3454
3455 /* Fix up the destination if needed. */
3456 if (dst != operands[0])
3457 emit_move_insn (operands[0], dst);
3458
3459 DONE;
3460 })
3461
3462 (define_insn "*insvqi_1_mem_rex64"
3463 [(set (zero_extract:SWI248
3464 (match_operand 0 "int248_register_operand" "+Q")
3465 (const_int 8)
3466 (const_int 8))
3467 (subreg:SWI248
3468 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3469 "TARGET_64BIT && reload_completed"
3470 "mov{b}\t{%1, %h0|%h0, %1}"
3471 [(set_attr "type" "imov")
3472 (set_attr "mode" "QI")])
3473
3474 (define_insn "@insv<mode>_1"
3475 [(set (zero_extract:SWI248
3476 (match_operand 0 "int248_register_operand" "+Q,Q")
3477 (const_int 8)
3478 (const_int 8))
3479 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3480 ""
3481 {
3482 if (CONST_INT_P (operands[1]))
3483 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3484 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3485 }
3486 [(set_attr "isa" "*,nox64")
3487 (set_attr "type" "imov")
3488 (set_attr "mode" "QI")])
3489
3490 (define_insn "*insvqi_1"
3491 [(set (zero_extract:SWI248
3492 (match_operand 0 "int248_register_operand" "+Q,Q")
3493 (const_int 8)
3494 (const_int 8))
3495 (subreg:SWI248
3496 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3497 ""
3498 "mov{b}\t{%1, %h0|%h0, %1}"
3499 [(set_attr "isa" "*,nox64")
3500 (set_attr "type" "imov")
3501 (set_attr "mode" "QI")])
3502
3503 (define_peephole2
3504 [(set (match_operand:QI 0 "register_operand")
3505 (match_operand:QI 1 "norex_memory_operand"))
3506 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3507 (const_int 8)
3508 (const_int 8))
3509 (subreg:SWI248 (match_dup 0) 0))]
3510 "TARGET_64BIT
3511 && peep2_reg_dead_p (2, operands[0])"
3512 [(set (zero_extract:SWI248 (match_dup 2)
3513 (const_int 8)
3514 (const_int 8))
3515 (subreg:SWI248 (match_dup 1) 0))])
3516
3517 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3518 (define_peephole2
3519 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3520 (const_int 0))
3521 (clobber (reg:CC FLAGS_REG))])
3522 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3523 (const_int 8)
3524 (const_int 8))
3525 (const_int 0))]
3526 "REGNO (operands[0]) == REGNO (operands[1])"
3527 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3528 (const_int 0))
3529 (clobber (reg:CC FLAGS_REG))])])
3530
3531 ;; Combine movl followed by movb.
3532 (define_peephole2
3533 [(set (match_operand:SWI48 0 "general_reg_operand")
3534 (match_operand:SWI48 1 "const_int_operand"))
3535 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3536 (const_int 8)
3537 (const_int 8))
3538 (match_operand:SWI248 3 "const_int_operand"))]
3539 "REGNO (operands[0]) == REGNO (operands[2])"
3540 [(set (match_operand:SWI48 0 "general_reg_operand")
3541 (match_dup 4))]
3542 {
3543 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3544 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3545 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3546 })
3547
3548 (define_insn "*insvqi_2"
3549 [(set (zero_extract:SWI248
3550 (match_operand 0 "int248_register_operand" "+Q")
3551 (const_int 8)
3552 (const_int 8))
3553 (match_operator:SWI248 2 "extract_operator"
3554 [(match_operand 1 "int248_register_operand" "Q")
3555 (const_int 8)
3556 (const_int 8)]))]
3557 ""
3558 "mov{b}\t{%h1, %h0|%h0, %h1}"
3559 [(set_attr "type" "imov")
3560 (set_attr "mode" "QI")])
3561
3562 (define_insn "*insvqi_3"
3563 [(set (zero_extract:SWI248
3564 (match_operand 0 "int248_register_operand" "+Q")
3565 (const_int 8)
3566 (const_int 8))
3567 (any_shiftrt:SWI248
3568 (match_operand:SWI248 1 "register_operand" "Q")
3569 (const_int 8)))]
3570 ""
3571 "mov{b}\t{%h1, %h0|%h0, %h1}"
3572 [(set_attr "type" "imov")
3573 (set_attr "mode" "QI")])
3574
3575 (define_code_iterator any_or_plus [plus ior xor])
3576
3577 (define_insn_and_split "*insvti_highpart_1"
3578 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3579 (any_or_plus:TI
3580 (and:TI
3581 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3582 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3583 (ashift:TI
3584 (zero_extend:TI
3585 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3586 (const_int 64))))]
3587 "TARGET_64BIT
3588 && CONST_WIDE_INT_P (operands[3])
3589 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3590 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3591 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3592 "#"
3593 "&& reload_completed"
3594 [(const_int 0)]
3595 {
3596 operands[4] = gen_lowpart (DImode, operands[1]);
3597 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3598 DONE;
3599 })
3600
3601 (define_insn_and_split "*insvti_lowpart_1"
3602 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3603 (any_or_plus:TI
3604 (and:TI
3605 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3606 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3607 (zero_extend:TI
3608 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))))]
3609 "TARGET_64BIT
3610 && CONST_WIDE_INT_P (operands[3])
3611 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3612 && CONST_WIDE_INT_ELT (operands[3], 0) == 0
3613 && CONST_WIDE_INT_ELT (operands[3], 1) == -1"
3614 "#"
3615 "&& reload_completed"
3616 [(const_int 0)]
3617 {
3618 operands[4] = gen_highpart (DImode, operands[1]);
3619 split_double_concat (TImode, operands[0], operands[2], operands[4]);
3620 DONE;
3621 })
3622
3623 (define_insn_and_split "*insvdi_lowpart_1"
3624 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
3625 (any_or_plus:DI
3626 (and:DI
3627 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m")
3628 (match_operand:DI 3 "const_int_operand" "n,n,n,n"))
3629 (zero_extend:DI
3630 (match_operand:SI 2 "nonimmediate_operand" "r,r,m,m"))))]
3631 "!TARGET_64BIT
3632 && CONST_INT_P (operands[3])
3633 && UINTVAL (operands[3]) == 0xffffffff00000000ll"
3634 "#"
3635 "&& reload_completed"
3636 [(const_int 0)]
3637 {
3638 operands[4] = gen_highpart (SImode, operands[1]);
3639 split_double_concat (DImode, operands[0], operands[2], operands[4]);
3640 DONE;
3641 })
3642 \f
3643 ;; Floating point push instructions.
3644
3645 (define_insn "*pushtf"
3646 [(set (match_operand:TF 0 "push_operand" "=<,<")
3647 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3648 "TARGET_64BIT || TARGET_SSE"
3649 {
3650 /* This insn should be already split before reg-stack. */
3651 return "#";
3652 }
3653 [(set_attr "isa" "*,x64")
3654 (set_attr "type" "multi")
3655 (set_attr "unit" "sse,*")
3656 (set_attr "mode" "TF,DI")])
3657
3658 ;; %%% Kill this when call knows how to work this out.
3659 (define_split
3660 [(set (match_operand:TF 0 "push_operand")
3661 (match_operand:TF 1 "sse_reg_operand"))]
3662 "TARGET_SSE && reload_completed"
3663 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3664 (set (match_dup 0) (match_dup 1))]
3665 {
3666 /* Preserve memory attributes. */
3667 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3668 })
3669
3670 (define_insn "*pushxf"
3671 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3672 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3673 ""
3674 {
3675 /* This insn should be already split before reg-stack. */
3676 return "#";
3677 }
3678 [(set_attr "isa" "*,*,*,nox64,x64")
3679 (set_attr "type" "multi")
3680 (set_attr "unit" "i387,*,*,*,*")
3681 (set (attr "mode")
3682 (cond [(eq_attr "alternative" "1,2,3,4")
3683 (if_then_else (match_test "TARGET_64BIT")
3684 (const_string "DI")
3685 (const_string "SI"))
3686 ]
3687 (const_string "XF")))
3688 (set (attr "preferred_for_size")
3689 (cond [(eq_attr "alternative" "1")
3690 (symbol_ref "false")]
3691 (symbol_ref "true")))])
3692
3693 ;; %%% Kill this when call knows how to work this out.
3694 (define_split
3695 [(set (match_operand:XF 0 "push_operand")
3696 (match_operand:XF 1 "fp_register_operand"))]
3697 "reload_completed"
3698 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3699 (set (match_dup 0) (match_dup 1))]
3700 {
3701 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3702 /* Preserve memory attributes. */
3703 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3704 })
3705
3706 (define_insn "*pushdf"
3707 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3708 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3709 ""
3710 {
3711 /* This insn should be already split before reg-stack. */
3712 return "#";
3713 }
3714 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3715 (set_attr "type" "multi")
3716 (set_attr "unit" "i387,*,*,*,*,sse")
3717 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3718 (set (attr "preferred_for_size")
3719 (cond [(eq_attr "alternative" "1")
3720 (symbol_ref "false")]
3721 (symbol_ref "true")))
3722 (set (attr "preferred_for_speed")
3723 (cond [(eq_attr "alternative" "1")
3724 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3725 (symbol_ref "true")))])
3726
3727 ;; %%% Kill this when call knows how to work this out.
3728 (define_split
3729 [(set (match_operand:DF 0 "push_operand")
3730 (match_operand:DF 1 "any_fp_register_operand"))]
3731 "reload_completed"
3732 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3733 (set (match_dup 0) (match_dup 1))]
3734 {
3735 /* Preserve memory attributes. */
3736 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3737 })
3738
3739 (define_mode_iterator HFBF [HF BF])
3740
3741 (define_insn "*push<mode>_rex64"
3742 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3743 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3744 "TARGET_64BIT"
3745 {
3746 /* Anything else should be already split before reg-stack. */
3747 gcc_assert (which_alternative == 0);
3748 return "push{q}\t%q1";
3749 }
3750 [(set_attr "isa" "*,sse4")
3751 (set_attr "type" "push,multi")
3752 (set_attr "mode" "DI,TI")])
3753
3754 (define_insn "*push<mode>"
3755 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3756 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3757 "!TARGET_64BIT"
3758 {
3759 /* Anything else should be already split before reg-stack. */
3760 gcc_assert (which_alternative == 0);
3761 return "push{l}\t%k1";
3762 }
3763 [(set_attr "isa" "*,sse4")
3764 (set_attr "type" "push,multi")
3765 (set_attr "mode" "SI,TI")])
3766
3767 (define_insn "*pushsf_rex64"
3768 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3769 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3770 "TARGET_64BIT"
3771 {
3772 /* Anything else should be already split before reg-stack. */
3773 if (which_alternative != 1)
3774 return "#";
3775 return "push{q}\t%q1";
3776 }
3777 [(set_attr "type" "multi,push,multi")
3778 (set_attr "unit" "i387,*,*")
3779 (set_attr "mode" "SF,DI,SF")])
3780
3781 (define_insn "*pushsf"
3782 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3783 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3784 "!TARGET_64BIT"
3785 {
3786 /* Anything else should be already split before reg-stack. */
3787 if (which_alternative != 1)
3788 return "#";
3789 return "push{l}\t%1";
3790 }
3791 [(set_attr "type" "multi,push,multi")
3792 (set_attr "unit" "i387,*,*")
3793 (set_attr "mode" "SF,SI,SF")])
3794
3795 (define_mode_iterator MODESH [SF HF BF])
3796 ;; %%% Kill this when call knows how to work this out.
3797 (define_split
3798 [(set (match_operand:MODESH 0 "push_operand")
3799 (match_operand:MODESH 1 "any_fp_register_operand"))]
3800 "reload_completed"
3801 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3802 (set (match_dup 0) (match_dup 1))]
3803 {
3804 rtx op = XEXP (operands[0], 0);
3805 if (GET_CODE (op) == PRE_DEC)
3806 {
3807 gcc_assert (!TARGET_64BIT);
3808 op = GEN_INT (-4);
3809 }
3810 else
3811 {
3812 op = XEXP (XEXP (op, 1), 1);
3813 gcc_assert (CONST_INT_P (op));
3814 }
3815 operands[2] = op;
3816 /* Preserve memory attributes. */
3817 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3818 })
3819
3820 (define_split
3821 [(set (match_operand:SF 0 "push_operand")
3822 (match_operand:SF 1 "memory_operand"))]
3823 "reload_completed
3824 && find_constant_src (insn)"
3825 [(set (match_dup 0) (match_dup 2))]
3826 "operands[2] = find_constant_src (curr_insn);")
3827
3828 (define_split
3829 [(set (match_operand 0 "push_operand")
3830 (match_operand 1 "general_gr_operand"))]
3831 "reload_completed
3832 && (GET_MODE (operands[0]) == TFmode
3833 || GET_MODE (operands[0]) == XFmode
3834 || GET_MODE (operands[0]) == DFmode)"
3835 [(const_int 0)]
3836 "ix86_split_long_move (operands); DONE;")
3837 \f
3838 ;; Floating point move instructions.
3839
3840 (define_expand "movtf"
3841 [(set (match_operand:TF 0 "nonimmediate_operand")
3842 (match_operand:TF 1 "nonimmediate_operand"))]
3843 "TARGET_64BIT || TARGET_SSE"
3844 "ix86_expand_move (TFmode, operands); DONE;")
3845
3846 (define_expand "mov<mode>"
3847 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3848 (match_operand:X87MODEFH 1 "general_operand"))]
3849 ""
3850 "ix86_expand_move (<MODE>mode, operands); DONE;")
3851
3852 (define_insn "*movtf_internal"
3853 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3854 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3855 "(TARGET_64BIT || TARGET_SSE)
3856 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3857 && (lra_in_progress || reload_completed
3858 || !CONST_DOUBLE_P (operands[1])
3859 || (standard_sse_constant_p (operands[1], TFmode) == 1
3860 && !memory_operand (operands[0], TFmode))
3861 || (!TARGET_MEMORY_MISMATCH_STALL
3862 && memory_operand (operands[0], TFmode)))"
3863 {
3864 switch (get_attr_type (insn))
3865 {
3866 case TYPE_SSELOG1:
3867 return standard_sse_constant_opcode (insn, operands);
3868
3869 case TYPE_SSEMOV:
3870 return ix86_output_ssemov (insn, operands);
3871
3872 case TYPE_MULTI:
3873 return "#";
3874
3875 default:
3876 gcc_unreachable ();
3877 }
3878 }
3879 [(set_attr "isa" "*,*,*,x64,x64")
3880 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3881 (set (attr "prefix")
3882 (if_then_else (eq_attr "type" "sselog1,ssemov")
3883 (const_string "maybe_vex")
3884 (const_string "orig")))
3885 (set (attr "mode")
3886 (cond [(eq_attr "alternative" "3,4")
3887 (const_string "DI")
3888 (match_test "TARGET_AVX")
3889 (const_string "TI")
3890 (ior (not (match_test "TARGET_SSE2"))
3891 (match_test "optimize_function_for_size_p (cfun)"))
3892 (const_string "V4SF")
3893 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3894 (const_string "V4SF")
3895 (and (eq_attr "alternative" "2")
3896 (match_test "TARGET_SSE_TYPELESS_STORES"))
3897 (const_string "V4SF")
3898 ]
3899 (const_string "TI")))])
3900
3901 (define_split
3902 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3903 (match_operand:TF 1 "general_gr_operand"))]
3904 "reload_completed"
3905 [(const_int 0)]
3906 "ix86_split_long_move (operands); DONE;")
3907
3908 ;; Possible store forwarding (partial memory) stall
3909 ;; in alternatives 4, 6, 7 and 8.
3910 (define_insn "*movxf_internal"
3911 [(set (match_operand:XF 0 "nonimmediate_operand"
3912 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3913 (match_operand:XF 1 "general_operand"
3914 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3915 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3916 && (lra_in_progress || reload_completed
3917 || !CONST_DOUBLE_P (operands[1])
3918 || ((optimize_function_for_size_p (cfun)
3919 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3920 && standard_80387_constant_p (operands[1]) > 0
3921 && !memory_operand (operands[0], XFmode))
3922 || (!TARGET_MEMORY_MISMATCH_STALL
3923 && memory_operand (operands[0], XFmode))
3924 || !TARGET_HARD_XF_REGS)"
3925 {
3926 switch (get_attr_type (insn))
3927 {
3928 case TYPE_FMOV:
3929 if (which_alternative == 2)
3930 return standard_80387_constant_opcode (operands[1]);
3931 return output_387_reg_move (insn, operands);
3932
3933 case TYPE_MULTI:
3934 return "#";
3935
3936 default:
3937 gcc_unreachable ();
3938 }
3939 }
3940 [(set (attr "isa")
3941 (cond [(eq_attr "alternative" "7,10")
3942 (const_string "nox64")
3943 (eq_attr "alternative" "8,11")
3944 (const_string "x64")
3945 ]
3946 (const_string "*")))
3947 (set (attr "type")
3948 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3949 (const_string "multi")
3950 ]
3951 (const_string "fmov")))
3952 (set (attr "mode")
3953 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3954 (if_then_else (match_test "TARGET_64BIT")
3955 (const_string "DI")
3956 (const_string "SI"))
3957 ]
3958 (const_string "XF")))
3959 (set (attr "preferred_for_size")
3960 (cond [(eq_attr "alternative" "3,4")
3961 (symbol_ref "false")]
3962 (symbol_ref "true")))
3963 (set (attr "enabled")
3964 (cond [(eq_attr "alternative" "9,10,11")
3965 (if_then_else
3966 (match_test "TARGET_HARD_XF_REGS")
3967 (symbol_ref "false")
3968 (const_string "*"))
3969 (not (match_test "TARGET_HARD_XF_REGS"))
3970 (symbol_ref "false")
3971 ]
3972 (const_string "*")))])
3973
3974 (define_split
3975 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3976 (match_operand:XF 1 "general_gr_operand"))]
3977 "reload_completed"
3978 [(const_int 0)]
3979 "ix86_split_long_move (operands); DONE;")
3980
3981 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3982 (define_insn "*movdf_internal"
3983 [(set (match_operand:DF 0 "nonimmediate_operand"
3984 "=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")
3985 (match_operand:DF 1 "general_operand"
3986 "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"))]
3987 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3988 && (lra_in_progress || reload_completed
3989 || !CONST_DOUBLE_P (operands[1])
3990 || ((optimize_function_for_size_p (cfun)
3991 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3992 && IS_STACK_MODE (DFmode)
3993 && standard_80387_constant_p (operands[1]) > 0
3994 && !memory_operand (operands[0], DFmode))
3995 || (TARGET_SSE2 && TARGET_SSE_MATH
3996 && standard_sse_constant_p (operands[1], DFmode) == 1
3997 && !memory_operand (operands[0], DFmode))
3998 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3999 && memory_operand (operands[0], DFmode))
4000 || !TARGET_HARD_DF_REGS)"
4001 {
4002 switch (get_attr_type (insn))
4003 {
4004 case TYPE_FMOV:
4005 if (which_alternative == 2)
4006 return standard_80387_constant_opcode (operands[1]);
4007 return output_387_reg_move (insn, operands);
4008
4009 case TYPE_MULTI:
4010 return "#";
4011
4012 case TYPE_IMOV:
4013 if (get_attr_mode (insn) == MODE_SI)
4014 return "mov{l}\t{%1, %k0|%k0, %1}";
4015 else if (which_alternative == 11)
4016 return "movabs{q}\t{%1, %0|%0, %1}";
4017 else
4018 return "mov{q}\t{%1, %0|%0, %1}";
4019
4020 case TYPE_SSELOG1:
4021 return standard_sse_constant_opcode (insn, operands);
4022
4023 case TYPE_SSEMOV:
4024 return ix86_output_ssemov (insn, operands);
4025
4026 default:
4027 gcc_unreachable ();
4028 }
4029 }
4030 [(set (attr "isa")
4031 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
4032 (const_string "nox64")
4033 (eq_attr "alternative" "8,9,10,11,24,25")
4034 (const_string "x64")
4035 (eq_attr "alternative" "12,13,14,15")
4036 (const_string "sse2")
4037 (eq_attr "alternative" "20,21")
4038 (const_string "x64_sse2")
4039 ]
4040 (const_string "*")))
4041 (set (attr "type")
4042 (cond [(eq_attr "alternative" "0,1,2")
4043 (const_string "fmov")
4044 (eq_attr "alternative" "3,4,5,6,7,22,23")
4045 (const_string "multi")
4046 (eq_attr "alternative" "8,9,10,11,24,25")
4047 (const_string "imov")
4048 (eq_attr "alternative" "12,16")
4049 (const_string "sselog1")
4050 ]
4051 (const_string "ssemov")))
4052 (set (attr "modrm")
4053 (if_then_else (eq_attr "alternative" "11")
4054 (const_string "0")
4055 (const_string "*")))
4056 (set (attr "length_immediate")
4057 (if_then_else (eq_attr "alternative" "11")
4058 (const_string "8")
4059 (const_string "*")))
4060 (set (attr "prefix")
4061 (if_then_else (eq_attr "type" "sselog1,ssemov")
4062 (const_string "maybe_vex")
4063 (const_string "orig")))
4064 (set (attr "prefix_data16")
4065 (if_then_else
4066 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4067 (eq_attr "mode" "V1DF"))
4068 (const_string "1")
4069 (const_string "*")))
4070 (set (attr "mode")
4071 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4072 (const_string "SI")
4073 (eq_attr "alternative" "8,9,11,20,21,24,25")
4074 (const_string "DI")
4075
4076 /* xorps is one byte shorter for non-AVX targets. */
4077 (eq_attr "alternative" "12,16")
4078 (cond [(match_test "TARGET_AVX")
4079 (const_string "V2DF")
4080 (ior (not (match_test "TARGET_SSE2"))
4081 (match_test "optimize_function_for_size_p (cfun)"))
4082 (const_string "V4SF")
4083 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4084 (const_string "TI")
4085 ]
4086 (const_string "V2DF"))
4087
4088 /* For architectures resolving dependencies on
4089 whole SSE registers use movapd to break dependency
4090 chains, otherwise use short move to avoid extra work. */
4091
4092 /* movaps is one byte shorter for non-AVX targets. */
4093 (eq_attr "alternative" "13,17")
4094 (cond [(match_test "TARGET_AVX")
4095 (const_string "DF")
4096 (ior (not (match_test "TARGET_SSE2"))
4097 (match_test "optimize_function_for_size_p (cfun)"))
4098 (const_string "V4SF")
4099 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4100 (const_string "V4SF")
4101 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4102 (const_string "V2DF")
4103 ]
4104 (const_string "DF"))
4105
4106 /* For architectures resolving dependencies on register
4107 parts we may avoid extra work to zero out upper part
4108 of register. */
4109 (eq_attr "alternative" "14,18")
4110 (cond [(not (match_test "TARGET_SSE2"))
4111 (const_string "V2SF")
4112 (match_test "TARGET_AVX")
4113 (const_string "DF")
4114 (match_test "TARGET_SSE_SPLIT_REGS")
4115 (const_string "V1DF")
4116 ]
4117 (const_string "DF"))
4118
4119 (and (eq_attr "alternative" "15,19")
4120 (not (match_test "TARGET_SSE2")))
4121 (const_string "V2SF")
4122 ]
4123 (const_string "DF")))
4124 (set (attr "preferred_for_size")
4125 (cond [(eq_attr "alternative" "3,4")
4126 (symbol_ref "false")]
4127 (symbol_ref "true")))
4128 (set (attr "preferred_for_speed")
4129 (cond [(eq_attr "alternative" "3,4")
4130 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4131 (eq_attr "alternative" "20")
4132 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4133 (eq_attr "alternative" "21")
4134 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4135 ]
4136 (symbol_ref "true")))
4137 (set (attr "enabled")
4138 (cond [(eq_attr "alternative" "22,23,24,25")
4139 (if_then_else
4140 (match_test "TARGET_HARD_DF_REGS")
4141 (symbol_ref "false")
4142 (const_string "*"))
4143 (not (match_test "TARGET_HARD_DF_REGS"))
4144 (symbol_ref "false")
4145 ]
4146 (const_string "*")))])
4147
4148 (define_split
4149 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4150 (match_operand:DF 1 "general_gr_operand"))]
4151 "!TARGET_64BIT && reload_completed"
4152 [(const_int 0)]
4153 "ix86_split_long_move (operands); DONE;")
4154
4155 (define_insn "*movsf_internal"
4156 [(set (match_operand:SF 0 "nonimmediate_operand"
4157 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4158 (match_operand:SF 1 "general_operand"
4159 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4160 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4161 && (lra_in_progress || reload_completed
4162 || !CONST_DOUBLE_P (operands[1])
4163 || ((optimize_function_for_size_p (cfun)
4164 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4165 && IS_STACK_MODE (SFmode)
4166 && standard_80387_constant_p (operands[1]) > 0)
4167 || (TARGET_SSE && TARGET_SSE_MATH
4168 && standard_sse_constant_p (operands[1], SFmode) == 1)
4169 || memory_operand (operands[0], SFmode)
4170 || !TARGET_HARD_SF_REGS)"
4171 {
4172 switch (get_attr_type (insn))
4173 {
4174 case TYPE_FMOV:
4175 if (which_alternative == 2)
4176 return standard_80387_constant_opcode (operands[1]);
4177 return output_387_reg_move (insn, operands);
4178
4179 case TYPE_IMOV:
4180 return "mov{l}\t{%1, %0|%0, %1}";
4181
4182 case TYPE_SSELOG1:
4183 return standard_sse_constant_opcode (insn, operands);
4184
4185 case TYPE_SSEMOV:
4186 return ix86_output_ssemov (insn, operands);
4187
4188 case TYPE_MMXMOV:
4189 switch (get_attr_mode (insn))
4190 {
4191 case MODE_DI:
4192 return "movq\t{%1, %0|%0, %1}";
4193 case MODE_SI:
4194 return "movd\t{%1, %0|%0, %1}";
4195
4196 default:
4197 gcc_unreachable ();
4198 }
4199
4200 default:
4201 gcc_unreachable ();
4202 }
4203 }
4204 [(set (attr "isa")
4205 (cond [(eq_attr "alternative" "9,10")
4206 (const_string "sse2")
4207 ]
4208 (const_string "*")))
4209 (set (attr "type")
4210 (cond [(eq_attr "alternative" "0,1,2")
4211 (const_string "fmov")
4212 (eq_attr "alternative" "3,4,16,17")
4213 (const_string "imov")
4214 (eq_attr "alternative" "5")
4215 (const_string "sselog1")
4216 (eq_attr "alternative" "11,12,13,14,15")
4217 (const_string "mmxmov")
4218 ]
4219 (const_string "ssemov")))
4220 (set (attr "prefix")
4221 (if_then_else (eq_attr "type" "sselog1,ssemov")
4222 (const_string "maybe_vex")
4223 (const_string "orig")))
4224 (set (attr "prefix_data16")
4225 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4226 (const_string "1")
4227 (const_string "*")))
4228 (set (attr "mode")
4229 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4230 (const_string "SI")
4231 (eq_attr "alternative" "11")
4232 (const_string "DI")
4233 (eq_attr "alternative" "5")
4234 (cond [(and (match_test "TARGET_AVX512F")
4235 (not (match_test "TARGET_PREFER_AVX256")))
4236 (const_string "V16SF")
4237 (match_test "TARGET_AVX")
4238 (const_string "V4SF")
4239 (ior (not (match_test "TARGET_SSE2"))
4240 (match_test "optimize_function_for_size_p (cfun)"))
4241 (const_string "V4SF")
4242 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4243 (const_string "TI")
4244 ]
4245 (const_string "V4SF"))
4246
4247 /* For architectures resolving dependencies on
4248 whole SSE registers use APS move to break dependency
4249 chains, otherwise use short move to avoid extra work.
4250
4251 Do the same for architectures resolving dependencies on
4252 the parts. While in DF mode it is better to always handle
4253 just register parts, the SF mode is different due to lack
4254 of instructions to load just part of the register. It is
4255 better to maintain the whole registers in single format
4256 to avoid problems on using packed logical operations. */
4257 (eq_attr "alternative" "6")
4258 (cond [(ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4259 (match_test "TARGET_SSE_SPLIT_REGS"))
4260 (const_string "V4SF")
4261 ]
4262 (const_string "SF"))
4263 ]
4264 (const_string "SF")))
4265 (set (attr "preferred_for_speed")
4266 (cond [(eq_attr "alternative" "9,14")
4267 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4268 (eq_attr "alternative" "10,15")
4269 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4270 ]
4271 (symbol_ref "true")))
4272 (set (attr "enabled")
4273 (cond [(eq_attr "alternative" "16,17")
4274 (if_then_else
4275 (match_test "TARGET_HARD_SF_REGS")
4276 (symbol_ref "false")
4277 (const_string "*"))
4278 (not (match_test "TARGET_HARD_SF_REGS"))
4279 (symbol_ref "false")
4280 ]
4281 (const_string "*")))])
4282
4283 (define_mode_attr hfbfconstf
4284 [(HF "F") (BF "")])
4285
4286 (define_insn "*mov<mode>_internal"
4287 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4288 "=?r,?r,?r,?m,v,v,?r,m,?v,v")
4289 (match_operand:HFBF 1 "general_operand"
4290 "r ,F ,m ,r<hfbfconstf>,C,v, v,v,r ,m"))]
4291 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4292 && (lra_in_progress
4293 || reload_completed
4294 || !CONST_DOUBLE_P (operands[1])
4295 || (TARGET_SSE2
4296 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4297 || memory_operand (operands[0], <MODE>mode))"
4298 {
4299 switch (get_attr_type (insn))
4300 {
4301 case TYPE_IMOVX:
4302 /* movzwl is faster than movw on p2 due to partial word stalls,
4303 though not as fast as an aligned movl. */
4304 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4305
4306 case TYPE_SSEMOV:
4307 return ix86_output_ssemov (insn, operands);
4308
4309 case TYPE_SSELOG1:
4310 if (satisfies_constraint_C (operands[1]))
4311 return standard_sse_constant_opcode (insn, operands);
4312
4313 if (SSE_REG_P (operands[0]))
4314 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4315 else
4316 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4317
4318 default:
4319 if (get_attr_mode (insn) == MODE_SI)
4320 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4321 else
4322 return "mov{w}\t{%1, %0|%0, %1}";
4323 }
4324 }
4325 [(set (attr "isa")
4326 (cond [(eq_attr "alternative" "4,5,6,8,9")
4327 (const_string "sse2")
4328 (eq_attr "alternative" "7")
4329 (const_string "sse4")
4330 ]
4331 (const_string "*")))
4332 (set (attr "type")
4333 (cond [(eq_attr "alternative" "4")
4334 (const_string "sselog1")
4335 (eq_attr "alternative" "5,6,8")
4336 (const_string "ssemov")
4337 (eq_attr "alternative" "7,9")
4338 (if_then_else
4339 (match_test ("TARGET_AVX512FP16"))
4340 (const_string "ssemov")
4341 (const_string "sselog1"))
4342 (match_test "optimize_function_for_size_p (cfun)")
4343 (const_string "imov")
4344 (and (eq_attr "alternative" "0")
4345 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4346 (not (match_test "TARGET_HIMODE_MATH"))))
4347 (const_string "imov")
4348 (and (eq_attr "alternative" "1,2")
4349 (match_operand:HI 1 "aligned_operand"))
4350 (const_string "imov")
4351 (and (match_test "TARGET_MOVX")
4352 (eq_attr "alternative" "0,2"))
4353 (const_string "imovx")
4354 ]
4355 (const_string "imov")))
4356 (set (attr "prefix")
4357 (cond [(eq_attr "alternative" "4,5,6,7,8,9")
4358 (const_string "maybe_vex")
4359 ]
4360 (const_string "orig")))
4361 (set (attr "mode")
4362 (cond [(eq_attr "alternative" "4")
4363 (const_string "V4SF")
4364 (eq_attr "alternative" "6,8")
4365 (if_then_else
4366 (match_test "TARGET_AVX512FP16")
4367 (const_string "HI")
4368 (const_string "SI"))
4369 (eq_attr "alternative" "7,9")
4370 (if_then_else
4371 (match_test "TARGET_AVX512FP16")
4372 (const_string "HI")
4373 (const_string "TI"))
4374 (eq_attr "alternative" "5")
4375 (cond [(match_test "TARGET_AVX512FP16")
4376 (const_string "HF")
4377 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4378 (match_test "TARGET_SSE_SPLIT_REGS"))
4379 (const_string "V4SF")
4380 ]
4381 (const_string "SF"))
4382 (eq_attr "type" "imovx")
4383 (const_string "SI")
4384 (and (eq_attr "alternative" "1,2")
4385 (match_operand:HI 1 "aligned_operand"))
4386 (const_string "SI")
4387 (and (eq_attr "alternative" "0")
4388 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4389 (not (match_test "TARGET_HIMODE_MATH"))))
4390 (const_string "SI")
4391 ]
4392 (const_string "HI")))
4393 (set (attr "enabled")
4394 (cond [(and (match_test "<MODE>mode == BFmode")
4395 (eq_attr "alternative" "1"))
4396 (symbol_ref "false")
4397 ]
4398 (const_string "*")))])
4399
4400 (define_split
4401 [(set (match_operand 0 "any_fp_register_operand")
4402 (match_operand 1 "memory_operand"))]
4403 "reload_completed
4404 && (GET_MODE (operands[0]) == TFmode
4405 || GET_MODE (operands[0]) == XFmode
4406 || GET_MODE (operands[0]) == DFmode
4407 || GET_MODE (operands[0]) == SFmode)
4408 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4409 [(set (match_dup 0) (match_dup 2))]
4410 "operands[2] = find_constant_src (curr_insn);")
4411
4412 (define_split
4413 [(set (match_operand 0 "any_fp_register_operand")
4414 (float_extend (match_operand 1 "memory_operand")))]
4415 "reload_completed
4416 && (GET_MODE (operands[0]) == TFmode
4417 || GET_MODE (operands[0]) == XFmode
4418 || GET_MODE (operands[0]) == DFmode)
4419 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4420 [(set (match_dup 0) (match_dup 2))]
4421 "operands[2] = find_constant_src (curr_insn);")
4422
4423 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4424 (define_split
4425 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4426 (match_operand:X87MODEF 1 "immediate_operand"))]
4427 "reload_completed
4428 && (standard_80387_constant_p (operands[1]) == 8
4429 || standard_80387_constant_p (operands[1]) == 9)"
4430 [(set (match_dup 0)(match_dup 1))
4431 (set (match_dup 0)
4432 (neg:X87MODEF (match_dup 0)))]
4433 {
4434 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4435 operands[1] = CONST0_RTX (<MODE>mode);
4436 else
4437 operands[1] = CONST1_RTX (<MODE>mode);
4438 })
4439
4440 (define_insn "*swapxf"
4441 [(set (match_operand:XF 0 "register_operand" "+f")
4442 (match_operand:XF 1 "register_operand" "+f"))
4443 (set (match_dup 1)
4444 (match_dup 0))]
4445 "TARGET_80387"
4446 {
4447 if (STACK_TOP_P (operands[0]))
4448 return "fxch\t%1";
4449 else
4450 return "fxch\t%0";
4451 }
4452 [(set_attr "type" "fxch")
4453 (set_attr "mode" "XF")])
4454 \f
4455
4456 ;; Zero extension instructions
4457
4458 (define_insn_and_split "zero_extendditi2"
4459 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4460 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4461 "TARGET_64BIT"
4462 "#"
4463 "&& reload_completed"
4464 [(set (match_dup 3) (match_dup 1))
4465 (set (match_dup 4) (const_int 0))]
4466 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4467
4468 (define_expand "zero_extendsidi2"
4469 [(set (match_operand:DI 0 "nonimmediate_operand")
4470 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4471
4472 (define_insn "*zero_extendsidi2"
4473 [(set (match_operand:DI 0 "nonimmediate_operand"
4474 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4475 (zero_extend:DI
4476 (match_operand:SI 1 "x86_64_zext_operand"
4477 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
4478 ""
4479 {
4480 switch (get_attr_type (insn))
4481 {
4482 case TYPE_IMOVX:
4483 if (ix86_use_lea_for_mov (insn, operands))
4484 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4485 else
4486 return "mov{l}\t{%1, %k0|%k0, %1}";
4487
4488 case TYPE_MULTI:
4489 return "#";
4490
4491 case TYPE_MMXMOV:
4492 return "movd\t{%1, %0|%0, %1}";
4493
4494 case TYPE_SSEMOV:
4495 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4496 {
4497 if (EXT_REX_SSE_REG_P (operands[0])
4498 || EXT_REX_SSE_REG_P (operands[1]))
4499 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4500 else
4501 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4502 }
4503
4504 if (GENERAL_REG_P (operands[0]))
4505 return "%vmovd\t{%1, %k0|%k0, %1}";
4506
4507 return "%vmovd\t{%1, %0|%0, %1}";
4508
4509 case TYPE_MSKMOV:
4510 return "kmovd\t{%1, %k0|%k0, %1}";
4511
4512 default:
4513 gcc_unreachable ();
4514 }
4515 }
4516 [(set (attr "isa")
4517 (cond [(eq_attr "alternative" "0,1,2")
4518 (const_string "nox64")
4519 (eq_attr "alternative" "3")
4520 (const_string "x64")
4521 (eq_attr "alternative" "7,8,9")
4522 (const_string "sse2")
4523 (eq_attr "alternative" "10")
4524 (const_string "sse4")
4525 (eq_attr "alternative" "11")
4526 (const_string "avx512f")
4527 (eq_attr "alternative" "12")
4528 (const_string "x64_avx512bw")
4529 (eq_attr "alternative" "13")
4530 (const_string "avx512bw")
4531 ]
4532 (const_string "*")))
4533 (set (attr "mmx_isa")
4534 (if_then_else (eq_attr "alternative" "5,6")
4535 (const_string "native")
4536 (const_string "*")))
4537 (set (attr "type")
4538 (cond [(eq_attr "alternative" "0,1,2,4")
4539 (const_string "multi")
4540 (eq_attr "alternative" "5,6")
4541 (const_string "mmxmov")
4542 (eq_attr "alternative" "7")
4543 (if_then_else (match_test "TARGET_64BIT")
4544 (const_string "ssemov")
4545 (const_string "multi"))
4546 (eq_attr "alternative" "8,9,10,11")
4547 (const_string "ssemov")
4548 (eq_attr "alternative" "12,13")
4549 (const_string "mskmov")
4550 ]
4551 (const_string "imovx")))
4552 (set (attr "prefix_extra")
4553 (if_then_else (eq_attr "alternative" "10,11")
4554 (const_string "1")
4555 (const_string "*")))
4556 (set (attr "prefix")
4557 (if_then_else (eq_attr "type" "ssemov")
4558 (const_string "maybe_vex")
4559 (const_string "orig")))
4560 (set (attr "prefix_0f")
4561 (if_then_else (eq_attr "type" "imovx")
4562 (const_string "0")
4563 (const_string "*")))
4564 (set (attr "mode")
4565 (cond [(eq_attr "alternative" "5,6")
4566 (const_string "DI")
4567 (and (eq_attr "alternative" "7")
4568 (match_test "TARGET_64BIT"))
4569 (const_string "TI")
4570 (eq_attr "alternative" "8,10,11")
4571 (const_string "TI")
4572 ]
4573 (const_string "SI")))
4574 (set (attr "preferred_for_speed")
4575 (cond [(eq_attr "alternative" "7")
4576 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4577 (eq_attr "alternative" "5,8")
4578 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4579 ]
4580 (symbol_ref "true")))])
4581
4582 (define_split
4583 [(set (match_operand:DI 0 "memory_operand")
4584 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4585 "reload_completed"
4586 [(set (match_dup 4) (const_int 0))]
4587 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4588
4589 (define_split
4590 [(set (match_operand:DI 0 "general_reg_operand")
4591 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4592 "!TARGET_64BIT && reload_completed
4593 && REGNO (operands[0]) == REGNO (operands[1])"
4594 [(set (match_dup 4) (const_int 0))]
4595 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4596
4597 (define_split
4598 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4599 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4600 "!TARGET_64BIT && reload_completed
4601 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4602 [(set (match_dup 3) (match_dup 1))
4603 (set (match_dup 4) (const_int 0))]
4604 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4605
4606 (define_mode_attr kmov_isa
4607 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4608
4609 (define_insn "zero_extend<mode>di2"
4610 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4611 (zero_extend:DI
4612 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4613 "TARGET_64BIT"
4614 "@
4615 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4616 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4617 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4618 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4619 (set_attr "type" "imovx,mskmov,mskmov")
4620 (set_attr "mode" "SI,<MODE>,<MODE>")])
4621
4622 (define_expand "zero_extend<mode>si2"
4623 [(set (match_operand:SI 0 "register_operand")
4624 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4625 ""
4626 {
4627 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4628 {
4629 operands[1] = force_reg (<MODE>mode, operands[1]);
4630 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4631 DONE;
4632 }
4633 })
4634
4635 (define_insn_and_split "zero_extend<mode>si2_and"
4636 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4637 (zero_extend:SI
4638 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4639 (clobber (reg:CC FLAGS_REG))]
4640 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4641 "#"
4642 "&& reload_completed"
4643 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4644 (clobber (reg:CC FLAGS_REG))])]
4645 {
4646 if (!REG_P (operands[1])
4647 || REGNO (operands[0]) != REGNO (operands[1]))
4648 {
4649 ix86_expand_clear (operands[0]);
4650
4651 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4652 emit_insn (gen_rtx_SET
4653 (gen_rtx_STRICT_LOW_PART
4654 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4655 operands[1]));
4656 DONE;
4657 }
4658
4659 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4660 }
4661 [(set_attr "type" "alu1")
4662 (set_attr "mode" "SI")])
4663
4664 (define_insn "*zero_extend<mode>si2"
4665 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4666 (zero_extend:SI
4667 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4668 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4669 "@
4670 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4671 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4672 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4673 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4674 (set_attr "type" "imovx,mskmov,mskmov")
4675 (set_attr "mode" "SI,<MODE>,<MODE>")])
4676
4677 (define_expand "zero_extendqihi2"
4678 [(set (match_operand:HI 0 "register_operand")
4679 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4680 ""
4681 {
4682 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4683 {
4684 operands[1] = force_reg (QImode, operands[1]);
4685 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4686 DONE;
4687 }
4688 })
4689
4690 (define_insn_and_split "zero_extendqihi2_and"
4691 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4692 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4693 (clobber (reg:CC FLAGS_REG))]
4694 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4695 "#"
4696 "&& reload_completed"
4697 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4698 (clobber (reg:CC FLAGS_REG))])]
4699 {
4700 if (!REG_P (operands[1])
4701 || REGNO (operands[0]) != REGNO (operands[1]))
4702 {
4703 ix86_expand_clear (operands[0]);
4704
4705 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4706 emit_insn (gen_rtx_SET
4707 (gen_rtx_STRICT_LOW_PART
4708 (VOIDmode, gen_lowpart (QImode, operands[0])),
4709 operands[1]));
4710 DONE;
4711 }
4712
4713 operands[0] = gen_lowpart (SImode, operands[0]);
4714 }
4715 [(set_attr "type" "alu1")
4716 (set_attr "mode" "SI")])
4717
4718 ; zero extend to SImode to avoid partial register stalls
4719 (define_insn "*zero_extendqihi2"
4720 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4721 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4722 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4723 "@
4724 movz{bl|x}\t{%1, %k0|%k0, %1}
4725 kmovb\t{%1, %k0|%k0, %1}
4726 kmovb\t{%1, %0|%0, %1}"
4727 [(set_attr "isa" "*,avx512dq,avx512dq")
4728 (set_attr "type" "imovx,mskmov,mskmov")
4729 (set_attr "mode" "SI,QI,QI")])
4730
4731 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4732 (define_peephole2
4733 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4734 (const_int 0))
4735 (clobber (reg:CC FLAGS_REG))])
4736 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4737 (match_operand:SWI12 2 "nonimmediate_operand"))]
4738 "REGNO (operands[0]) == REGNO (operands[1])
4739 && (<SWI48:MODE>mode != SImode
4740 || !TARGET_ZERO_EXTEND_WITH_AND
4741 || !optimize_function_for_speed_p (cfun))"
4742 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4743
4744 ;; Likewise, but preserving FLAGS_REG.
4745 (define_peephole2
4746 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4747 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4748 (match_operand:SWI12 2 "nonimmediate_operand"))]
4749 "REGNO (operands[0]) == REGNO (operands[1])
4750 && (<SWI48:MODE>mode != SImode
4751 || !TARGET_ZERO_EXTEND_WITH_AND
4752 || !optimize_function_for_speed_p (cfun))"
4753 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4754 \f
4755 ;; Sign extension instructions
4756
4757 (define_expand "extendsidi2"
4758 [(set (match_operand:DI 0 "register_operand")
4759 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4760 ""
4761 {
4762 if (!TARGET_64BIT)
4763 {
4764 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4765 DONE;
4766 }
4767 })
4768
4769 (define_insn "*extendsidi2_rex64"
4770 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4771 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4772 "TARGET_64BIT"
4773 "@
4774 {cltq|cdqe}
4775 movs{lq|x}\t{%1, %0|%0, %1}"
4776 [(set_attr "type" "imovx")
4777 (set_attr "mode" "DI")
4778 (set_attr "prefix_0f" "0")
4779 (set_attr "modrm" "0,1")])
4780
4781 (define_insn "extendsidi2_1"
4782 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4783 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4784 (clobber (reg:CC FLAGS_REG))
4785 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4786 "!TARGET_64BIT"
4787 "#")
4788
4789 (define_insn "extendditi2"
4790 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4791 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4792 (clobber (reg:CC FLAGS_REG))
4793 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4794 "TARGET_64BIT"
4795 "#")
4796
4797 ;; Split the memory case. If the source register doesn't die, it will stay
4798 ;; this way, if it does die, following peephole2s take care of it.
4799 (define_split
4800 [(set (match_operand:<DWI> 0 "memory_operand")
4801 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4802 (clobber (reg:CC FLAGS_REG))
4803 (clobber (match_operand:DWIH 2 "register_operand"))]
4804 "reload_completed"
4805 [(const_int 0)]
4806 {
4807 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4808
4809 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4810
4811 emit_move_insn (operands[3], operands[1]);
4812
4813 /* Generate a cltd if possible and doing so it profitable. */
4814 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4815 && REGNO (operands[1]) == AX_REG
4816 && REGNO (operands[2]) == DX_REG)
4817 {
4818 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4819 }
4820 else
4821 {
4822 emit_move_insn (operands[2], operands[1]);
4823 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4824 }
4825 emit_move_insn (operands[4], operands[2]);
4826 DONE;
4827 })
4828
4829 ;; Peepholes for the case where the source register does die, after
4830 ;; being split with the above splitter.
4831 (define_peephole2
4832 [(set (match_operand:DWIH 0 "memory_operand")
4833 (match_operand:DWIH 1 "general_reg_operand"))
4834 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4835 (parallel [(set (match_dup 2)
4836 (ashiftrt:DWIH (match_dup 2)
4837 (match_operand 4 "const_int_operand")))
4838 (clobber (reg:CC FLAGS_REG))])
4839 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4840 "REGNO (operands[1]) != REGNO (operands[2])
4841 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4842 && peep2_reg_dead_p (2, operands[1])
4843 && peep2_reg_dead_p (4, operands[2])
4844 && !reg_mentioned_p (operands[2], operands[3])"
4845 [(set (match_dup 0) (match_dup 1))
4846 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4847 (clobber (reg:CC FLAGS_REG))])
4848 (set (match_dup 3) (match_dup 1))])
4849
4850 (define_peephole2
4851 [(set (match_operand:DWIH 0 "memory_operand")
4852 (match_operand:DWIH 1 "general_reg_operand"))
4853 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4854 (ashiftrt:DWIH (match_dup 1)
4855 (match_operand 4 "const_int_operand")))
4856 (clobber (reg:CC FLAGS_REG))])
4857 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4858 "/* cltd is shorter than sarl $31, %eax */
4859 !optimize_function_for_size_p (cfun)
4860 && REGNO (operands[1]) == AX_REG
4861 && REGNO (operands[2]) == DX_REG
4862 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4863 && peep2_reg_dead_p (2, operands[1])
4864 && peep2_reg_dead_p (3, operands[2])
4865 && !reg_mentioned_p (operands[2], operands[3])"
4866 [(set (match_dup 0) (match_dup 1))
4867 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4868 (clobber (reg:CC FLAGS_REG))])
4869 (set (match_dup 3) (match_dup 1))])
4870
4871 ;; Extend to register case. Optimize case where source and destination
4872 ;; registers match and cases where we can use cltd.
4873 (define_split
4874 [(set (match_operand:<DWI> 0 "register_operand")
4875 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4876 (clobber (reg:CC FLAGS_REG))
4877 (clobber (match_scratch:DWIH 2))]
4878 "reload_completed"
4879 [(const_int 0)]
4880 {
4881 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4882
4883 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4884
4885 if (REGNO (operands[3]) != REGNO (operands[1]))
4886 emit_move_insn (operands[3], operands[1]);
4887
4888 rtx src = operands[1];
4889 if (REGNO (operands[3]) == AX_REG)
4890 src = operands[3];
4891
4892 /* Generate a cltd if possible and doing so it profitable. */
4893 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4894 && REGNO (src) == AX_REG
4895 && REGNO (operands[4]) == DX_REG)
4896 {
4897 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4898 DONE;
4899 }
4900
4901 if (REGNO (operands[4]) != REGNO (operands[1]))
4902 emit_move_insn (operands[4], operands[1]);
4903
4904 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
4905 DONE;
4906 })
4907
4908 (define_insn "extend<mode>di2"
4909 [(set (match_operand:DI 0 "register_operand" "=r")
4910 (sign_extend:DI
4911 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4912 "TARGET_64BIT"
4913 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4914 [(set_attr "type" "imovx")
4915 (set_attr "mode" "DI")])
4916
4917 (define_insn "extendhisi2"
4918 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4919 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4920 ""
4921 {
4922 switch (get_attr_prefix_0f (insn))
4923 {
4924 case 0:
4925 return "{cwtl|cwde}";
4926 default:
4927 return "movs{wl|x}\t{%1, %0|%0, %1}";
4928 }
4929 }
4930 [(set_attr "type" "imovx")
4931 (set_attr "mode" "SI")
4932 (set (attr "prefix_0f")
4933 ;; movsx is short decodable while cwtl is vector decoded.
4934 (if_then_else (and (eq_attr "cpu" "!k6")
4935 (eq_attr "alternative" "0"))
4936 (const_string "0")
4937 (const_string "1")))
4938 (set (attr "znver1_decode")
4939 (if_then_else (eq_attr "prefix_0f" "0")
4940 (const_string "double")
4941 (const_string "direct")))
4942 (set (attr "modrm")
4943 (if_then_else (eq_attr "prefix_0f" "0")
4944 (const_string "0")
4945 (const_string "1")))])
4946
4947 (define_insn "*extendhisi2_zext"
4948 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4949 (zero_extend:DI
4950 (sign_extend:SI
4951 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4952 "TARGET_64BIT"
4953 {
4954 switch (get_attr_prefix_0f (insn))
4955 {
4956 case 0:
4957 return "{cwtl|cwde}";
4958 default:
4959 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4960 }
4961 }
4962 [(set_attr "type" "imovx")
4963 (set_attr "mode" "SI")
4964 (set (attr "prefix_0f")
4965 ;; movsx is short decodable while cwtl is vector decoded.
4966 (if_then_else (and (eq_attr "cpu" "!k6")
4967 (eq_attr "alternative" "0"))
4968 (const_string "0")
4969 (const_string "1")))
4970 (set (attr "modrm")
4971 (if_then_else (eq_attr "prefix_0f" "0")
4972 (const_string "0")
4973 (const_string "1")))])
4974
4975 (define_insn "extendqisi2"
4976 [(set (match_operand:SI 0 "register_operand" "=r")
4977 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4978 ""
4979 "movs{bl|x}\t{%1, %0|%0, %1}"
4980 [(set_attr "type" "imovx")
4981 (set_attr "mode" "SI")])
4982
4983 (define_insn "*extendqisi2_zext"
4984 [(set (match_operand:DI 0 "register_operand" "=r")
4985 (zero_extend:DI
4986 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4987 "TARGET_64BIT"
4988 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4989 [(set_attr "type" "imovx")
4990 (set_attr "mode" "SI")])
4991
4992 (define_insn "extendqihi2"
4993 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4994 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4995 ""
4996 {
4997 switch (get_attr_prefix_0f (insn))
4998 {
4999 case 0:
5000 return "{cbtw|cbw}";
5001 default:
5002 return "movs{bw|x}\t{%1, %0|%0, %1}";
5003 }
5004 }
5005 [(set_attr "type" "imovx")
5006 (set_attr "mode" "HI")
5007 (set (attr "prefix_0f")
5008 ;; movsx is short decodable while cwtl is vector decoded.
5009 (if_then_else (and (eq_attr "cpu" "!k6")
5010 (eq_attr "alternative" "0"))
5011 (const_string "0")
5012 (const_string "1")))
5013 (set (attr "modrm")
5014 (if_then_else (eq_attr "prefix_0f" "0")
5015 (const_string "0")
5016 (const_string "1")))])
5017
5018 (define_insn "*extendqi<SWI24:mode>_ext_1"
5019 [(set (match_operand:SWI24 0 "register_operand" "=R")
5020 (sign_extend:SWI24
5021 (subreg:QI
5022 (match_operator:SWI248 2 "extract_operator"
5023 [(match_operand 1 "int248_register_operand" "Q")
5024 (const_int 8)
5025 (const_int 8)]) 0)))]
5026 ""
5027 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
5028 [(set_attr "type" "imovx")
5029 (set_attr "mode" "<SWI24:MODE>")])
5030 \f
5031 ;; Conversions between float and double.
5032
5033 ;; These are all no-ops in the model used for the 80387.
5034 ;; So just emit moves.
5035
5036 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
5037 (define_split
5038 [(set (match_operand:DF 0 "push_operand")
5039 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
5040 "reload_completed"
5041 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
5042 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
5043
5044 (define_split
5045 [(set (match_operand:XF 0 "push_operand")
5046 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
5047 "reload_completed"
5048 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
5049 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
5050 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
5051
5052 (define_expand "extendsfdf2"
5053 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
5054 (float_extend:DF (match_operand:SF 1 "general_operand")))]
5055 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5056 {
5057 /* ??? Needed for compress_float_constant since all fp constants
5058 are TARGET_LEGITIMATE_CONSTANT_P. */
5059 if (CONST_DOUBLE_P (operands[1]))
5060 {
5061 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
5062 && standard_80387_constant_p (operands[1]) > 0)
5063 {
5064 operands[1] = simplify_const_unary_operation
5065 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5066 emit_move_insn_1 (operands[0], operands[1]);
5067 DONE;
5068 }
5069 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5070 }
5071 })
5072
5073 (define_insn "*extendsfdf2"
5074 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5075 (float_extend:DF
5076 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5077 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5078 {
5079 switch (which_alternative)
5080 {
5081 case 0:
5082 case 1:
5083 return output_387_reg_move (insn, operands);
5084
5085 case 2:
5086 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5087 case 3:
5088 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5089
5090 default:
5091 gcc_unreachable ();
5092 }
5093 }
5094 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5095 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5096 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5097 (set_attr "mode" "SF,XF,DF,DF")
5098 (set (attr "enabled")
5099 (if_then_else
5100 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5101 (if_then_else
5102 (eq_attr "alternative" "0,1")
5103 (symbol_ref "TARGET_MIX_SSE_I387")
5104 (symbol_ref "true"))
5105 (if_then_else
5106 (eq_attr "alternative" "0,1")
5107 (symbol_ref "true")
5108 (symbol_ref "false"))))])
5109
5110 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5111 cvtss2sd:
5112 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5113 cvtps2pd xmm2,xmm1
5114 We do the conversion post reload to avoid producing of 128bit spills
5115 that might lead to ICE on 32bit target. The sequence unlikely combine
5116 anyway. */
5117 (define_split
5118 [(set (match_operand:DF 0 "sse_reg_operand")
5119 (float_extend:DF
5120 (match_operand:SF 1 "nonimmediate_operand")))]
5121 "TARGET_USE_VECTOR_FP_CONVERTS
5122 && optimize_insn_for_speed_p ()
5123 && reload_completed
5124 && (!EXT_REX_SSE_REG_P (operands[0])
5125 || TARGET_AVX512VL)"
5126 [(set (match_dup 2)
5127 (float_extend:V2DF
5128 (vec_select:V2SF
5129 (match_dup 3)
5130 (parallel [(const_int 0) (const_int 1)]))))]
5131 {
5132 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5133 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5134 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5135 Try to avoid move when unpacking can be done in source. */
5136 if (REG_P (operands[1]))
5137 {
5138 /* If it is unsafe to overwrite upper half of source, we need
5139 to move to destination and unpack there. */
5140 if (REGNO (operands[0]) != REGNO (operands[1])
5141 || (EXT_REX_SSE_REG_P (operands[1])
5142 && !TARGET_AVX512VL))
5143 {
5144 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5145 emit_move_insn (tmp, operands[1]);
5146 }
5147 else
5148 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5149 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5150 =v, v, then vbroadcastss will be only needed for AVX512F without
5151 AVX512VL. */
5152 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5153 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5154 operands[3]));
5155 else
5156 {
5157 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5158 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5159 }
5160 }
5161 else
5162 emit_insn (gen_vec_setv4sf_0 (operands[3],
5163 CONST0_RTX (V4SFmode), operands[1]));
5164 })
5165
5166 ;; It's more profitable to split and then extend in the same register.
5167 (define_peephole2
5168 [(set (match_operand:DF 0 "sse_reg_operand")
5169 (float_extend:DF
5170 (match_operand:SF 1 "memory_operand")))]
5171 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5172 && optimize_insn_for_speed_p ()"
5173 [(set (match_dup 2) (match_dup 1))
5174 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5175 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5176
5177 ;; Break partial SSE register dependency stall. This splitter should split
5178 ;; late in the pass sequence (after register rename pass), so allocated
5179 ;; registers won't change anymore
5180
5181 (define_split
5182 [(set (match_operand:DF 0 "sse_reg_operand")
5183 (float_extend:DF
5184 (match_operand:SF 1 "nonimmediate_operand")))]
5185 "!TARGET_AVX
5186 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5187 && epilogue_completed
5188 && optimize_function_for_speed_p (cfun)
5189 && (!REG_P (operands[1])
5190 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5191 && (!EXT_REX_SSE_REG_P (operands[0])
5192 || TARGET_AVX512VL)"
5193 [(set (match_dup 0)
5194 (vec_merge:V2DF
5195 (vec_duplicate:V2DF
5196 (float_extend:DF
5197 (match_dup 1)))
5198 (match_dup 0)
5199 (const_int 1)))]
5200 {
5201 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5202 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5203 })
5204
5205 (define_expand "extendhfsf2"
5206 [(set (match_operand:SF 0 "register_operand")
5207 (float_extend:SF
5208 (match_operand:HF 1 "nonimmediate_operand")))]
5209 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5210 {
5211 if (!TARGET_AVX512FP16)
5212 {
5213 rtx res = gen_reg_rtx (V4SFmode);
5214 rtx tmp = gen_reg_rtx (V8HFmode);
5215 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5216
5217 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5218 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5219 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5220 DONE;
5221 }
5222 })
5223
5224 (define_expand "extendhfdf2"
5225 [(set (match_operand:DF 0 "register_operand")
5226 (float_extend:DF
5227 (match_operand:HF 1 "nonimmediate_operand")))]
5228 "TARGET_AVX512FP16")
5229
5230 (define_insn "*extendhf<mode>2"
5231 [(set (match_operand:MODEF 0 "register_operand" "=v")
5232 (float_extend:MODEF
5233 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5234 "TARGET_AVX512FP16"
5235 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5236 [(set_attr "type" "ssecvt")
5237 (set_attr "prefix" "evex")
5238 (set_attr "mode" "<MODE>")])
5239
5240 (define_expand "extendbfsf2"
5241 [(set (match_operand:SF 0 "register_operand")
5242 (unspec:SF
5243 [(match_operand:BF 1 "register_operand")]
5244 UNSPEC_CVTBFSF))]
5245 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5246
5247 ;; Don't use float_extend since psrlld doesn't raise
5248 ;; exceptions and turn a sNaN into a qNaN.
5249 (define_insn "extendbfsf2_1"
5250 [(set (match_operand:SF 0 "register_operand" "=x,Yv,v")
5251 (unspec:SF
5252 [(match_operand:BF 1 "register_operand" " 0,Yv,v")]
5253 UNSPEC_CVTBFSF))]
5254 "TARGET_SSE2"
5255 "@
5256 pslld\t{$16, %0|%0, 16}
5257 vpslld\t{$16, %1, %0|%0, %1, 16}
5258 vpslld\t{$16, %g1, %g0|%g0, %g1, 16}"
5259 [(set_attr "isa" "noavx,avx,*")
5260 (set_attr "type" "sseishft1")
5261 (set_attr "length_immediate" "1")
5262 (set_attr "prefix_data16" "1,*,*")
5263 (set_attr "prefix" "orig,maybe_evex,evex")
5264 (set_attr "mode" "TI,TI,XI")
5265 (set_attr "memory" "none")
5266 (set (attr "enabled")
5267 (if_then_else (eq_attr "alternative" "2")
5268 (symbol_ref "TARGET_AVX512F && !TARGET_AVX512VL
5269 && !TARGET_PREFER_AVX256")
5270 (const_string "*")))])
5271
5272 (define_expand "extend<mode>xf2"
5273 [(set (match_operand:XF 0 "nonimmediate_operand")
5274 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5275 "TARGET_80387"
5276 {
5277 /* ??? Needed for compress_float_constant since all fp constants
5278 are TARGET_LEGITIMATE_CONSTANT_P. */
5279 if (CONST_DOUBLE_P (operands[1]))
5280 {
5281 if (standard_80387_constant_p (operands[1]) > 0)
5282 {
5283 operands[1] = simplify_const_unary_operation
5284 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5285 emit_move_insn_1 (operands[0], operands[1]);
5286 DONE;
5287 }
5288 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5289 }
5290 })
5291
5292 (define_insn "*extend<mode>xf2_i387"
5293 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5294 (float_extend:XF
5295 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5296 "TARGET_80387"
5297 "* return output_387_reg_move (insn, operands);"
5298 [(set_attr "type" "fmov")
5299 (set_attr "mode" "<MODE>,XF")])
5300
5301 ;; %%% This seems like bad news.
5302 ;; This cannot output into an f-reg because there is no way to be sure
5303 ;; of truncating in that case. Otherwise this is just like a simple move
5304 ;; insn. So we pretend we can output to a reg in order to get better
5305 ;; register preferencing, but we really use a stack slot.
5306
5307 ;; Conversion from DFmode to SFmode.
5308
5309 (define_insn "truncdfsf2"
5310 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5311 (float_truncate:SF
5312 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5313 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5314 {
5315 switch (which_alternative)
5316 {
5317 case 0:
5318 case 1:
5319 return output_387_reg_move (insn, operands);
5320
5321 case 2:
5322 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5323 case 3:
5324 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5325
5326 default:
5327 gcc_unreachable ();
5328 }
5329 }
5330 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5331 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5332 (set_attr "mode" "SF")
5333 (set (attr "enabled")
5334 (if_then_else
5335 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5336 (cond [(eq_attr "alternative" "0")
5337 (symbol_ref "TARGET_MIX_SSE_I387")
5338 (eq_attr "alternative" "1")
5339 (symbol_ref "TARGET_MIX_SSE_I387
5340 && flag_unsafe_math_optimizations")
5341 ]
5342 (symbol_ref "true"))
5343 (cond [(eq_attr "alternative" "0")
5344 (symbol_ref "true")
5345 (eq_attr "alternative" "1")
5346 (symbol_ref "flag_unsafe_math_optimizations")
5347 ]
5348 (symbol_ref "false"))))])
5349
5350 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5351 cvtsd2ss:
5352 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5353 cvtpd2ps xmm2,xmm1
5354 We do the conversion post reload to avoid producing of 128bit spills
5355 that might lead to ICE on 32bit target. The sequence unlikely combine
5356 anyway. */
5357 (define_split
5358 [(set (match_operand:SF 0 "sse_reg_operand")
5359 (float_truncate:SF
5360 (match_operand:DF 1 "nonimmediate_operand")))]
5361 "TARGET_USE_VECTOR_FP_CONVERTS
5362 && optimize_insn_for_speed_p ()
5363 && reload_completed
5364 && (!EXT_REX_SSE_REG_P (operands[0])
5365 || TARGET_AVX512VL)"
5366 [(set (match_dup 2)
5367 (vec_concat:V4SF
5368 (float_truncate:V2SF
5369 (match_dup 4))
5370 (match_dup 3)))]
5371 {
5372 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5373 operands[3] = CONST0_RTX (V2SFmode);
5374 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5375 /* Use movsd for loading from memory, unpcklpd for registers.
5376 Try to avoid move when unpacking can be done in source, or SSE3
5377 movddup is available. */
5378 if (REG_P (operands[1]))
5379 {
5380 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5381 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5382 {
5383 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5384 emit_move_insn (tmp, operands[1]);
5385 operands[1] = tmp;
5386 }
5387 else if (!TARGET_SSE3)
5388 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5389 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5390 }
5391 else
5392 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5393 CONST0_RTX (DFmode)));
5394 })
5395
5396 ;; It's more profitable to split and then truncate in the same register.
5397 (define_peephole2
5398 [(set (match_operand:SF 0 "sse_reg_operand")
5399 (float_truncate:SF
5400 (match_operand:DF 1 "memory_operand")))]
5401 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5402 && optimize_insn_for_speed_p ()"
5403 [(set (match_dup 2) (match_dup 1))
5404 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5405 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5406
5407 ;; Break partial SSE register dependency stall. This splitter should split
5408 ;; late in the pass sequence (after register rename pass), so allocated
5409 ;; registers won't change anymore
5410
5411 (define_split
5412 [(set (match_operand:SF 0 "sse_reg_operand")
5413 (float_truncate:SF
5414 (match_operand:DF 1 "nonimmediate_operand")))]
5415 "!TARGET_AVX
5416 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5417 && epilogue_completed
5418 && optimize_function_for_speed_p (cfun)
5419 && (!REG_P (operands[1])
5420 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5421 && (!EXT_REX_SSE_REG_P (operands[0])
5422 || TARGET_AVX512VL)"
5423 [(set (match_dup 0)
5424 (vec_merge:V4SF
5425 (vec_duplicate:V4SF
5426 (float_truncate:SF
5427 (match_dup 1)))
5428 (match_dup 0)
5429 (const_int 1)))]
5430 {
5431 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5432 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5433 })
5434
5435 ;; Conversion from XFmode to {SF,DF}mode
5436
5437 (define_insn "truncxf<mode>2"
5438 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5439 (float_truncate:MODEF
5440 (match_operand:XF 1 "register_operand" "f,f")))]
5441 "TARGET_80387"
5442 "* return output_387_reg_move (insn, operands);"
5443 [(set_attr "type" "fmov")
5444 (set_attr "mode" "<MODE>")
5445 (set (attr "enabled")
5446 (cond [(eq_attr "alternative" "1")
5447 (symbol_ref "flag_unsafe_math_optimizations")
5448 ]
5449 (symbol_ref "true")))])
5450
5451 ;; Conversion from {SF,DF}mode to HFmode.
5452
5453 (define_expand "truncsfhf2"
5454 [(set (match_operand:HF 0 "register_operand")
5455 (float_truncate:HF
5456 (match_operand:SF 1 "nonimmediate_operand")))]
5457 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5458 {
5459 if (!TARGET_AVX512FP16)
5460 {
5461 rtx res = gen_reg_rtx (V8HFmode);
5462 rtx tmp = gen_reg_rtx (V4SFmode);
5463 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5464
5465 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5466 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5467 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5468 DONE;
5469 }
5470 })
5471
5472 (define_expand "truncdfhf2"
5473 [(set (match_operand:HF 0 "register_operand")
5474 (float_truncate:HF
5475 (match_operand:DF 1 "nonimmediate_operand")))]
5476 "TARGET_AVX512FP16")
5477
5478 (define_insn "*trunc<mode>hf2"
5479 [(set (match_operand:HF 0 "register_operand" "=v")
5480 (float_truncate:HF
5481 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5482 "TARGET_AVX512FP16"
5483 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5484 [(set_attr "type" "ssecvt")
5485 (set_attr "prefix" "evex")
5486 (set_attr "mode" "HF")])
5487
5488 (define_insn "truncsfbf2"
5489 [(set (match_operand:BF 0 "register_operand" "=x, v")
5490 (float_truncate:BF
5491 (match_operand:SF 1 "register_operand" "x,v")))]
5492 "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5493 && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5494 "@
5495 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5496 vcvtneps2bf16\t{%1, %0|%0, %1}"
5497 [(set_attr "isa" "avxneconvert,avx512bf16vl")
5498 (set_attr "prefix" "vex,evex")])
5499
5500 ;; Signed conversion to DImode.
5501
5502 (define_expand "fix_truncxfdi2"
5503 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5504 (fix:DI (match_operand:XF 1 "register_operand")))
5505 (clobber (reg:CC FLAGS_REG))])]
5506 "TARGET_80387"
5507 {
5508 if (TARGET_FISTTP)
5509 {
5510 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5511 DONE;
5512 }
5513 })
5514
5515 (define_expand "fix_trunc<mode>di2"
5516 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5517 (fix:DI (match_operand:MODEF 1 "register_operand")))
5518 (clobber (reg:CC FLAGS_REG))])]
5519 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5520 {
5521 if (TARGET_FISTTP
5522 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5523 {
5524 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5525 DONE;
5526 }
5527 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5528 {
5529 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5530 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5531 if (out != operands[0])
5532 emit_move_insn (operands[0], out);
5533 DONE;
5534 }
5535 })
5536
5537 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5538 [(set (match_operand:SWI48 0 "register_operand" "=r")
5539 (any_fix:SWI48
5540 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5541 "TARGET_AVX512FP16"
5542 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5543 [(set_attr "type" "sseicvt")
5544 (set_attr "prefix" "evex")
5545 (set_attr "mode" "<MODE>")])
5546
5547 ;; Signed conversion to SImode.
5548
5549 (define_expand "fix_truncxfsi2"
5550 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5551 (fix:SI (match_operand:XF 1 "register_operand")))
5552 (clobber (reg:CC FLAGS_REG))])]
5553 "TARGET_80387"
5554 {
5555 if (TARGET_FISTTP)
5556 {
5557 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5558 DONE;
5559 }
5560 })
5561
5562 (define_expand "fix_trunc<mode>si2"
5563 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5564 (fix:SI (match_operand:MODEF 1 "register_operand")))
5565 (clobber (reg:CC FLAGS_REG))])]
5566 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5567 {
5568 if (TARGET_FISTTP
5569 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5570 {
5571 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5572 DONE;
5573 }
5574 if (SSE_FLOAT_MODE_P (<MODE>mode))
5575 {
5576 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5577 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5578 if (out != operands[0])
5579 emit_move_insn (operands[0], out);
5580 DONE;
5581 }
5582 })
5583
5584 ;; Signed conversion to HImode.
5585
5586 (define_expand "fix_trunc<mode>hi2"
5587 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5588 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5589 (clobber (reg:CC FLAGS_REG))])]
5590 "TARGET_80387
5591 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5592 {
5593 if (TARGET_FISTTP)
5594 {
5595 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5596 DONE;
5597 }
5598 })
5599
5600 ;; Unsigned conversion to DImode
5601
5602 (define_insn "fixuns_trunc<mode>di2"
5603 [(set (match_operand:DI 0 "register_operand" "=r")
5604 (unsigned_fix:DI
5605 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5606 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5607 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5608 [(set_attr "type" "sseicvt")
5609 (set_attr "prefix" "evex")
5610 (set_attr "mode" "DI")])
5611
5612 ;; Unsigned conversion to SImode.
5613
5614 (define_expand "fixuns_trunc<mode>si2"
5615 [(parallel
5616 [(set (match_operand:SI 0 "register_operand")
5617 (unsigned_fix:SI
5618 (match_operand:MODEF 1 "nonimmediate_operand")))
5619 (use (match_dup 2))
5620 (clobber (scratch:<ssevecmode>))
5621 (clobber (scratch:<ssevecmode>))])]
5622 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5623 {
5624 machine_mode mode = <MODE>mode;
5625 machine_mode vecmode = <ssevecmode>mode;
5626 REAL_VALUE_TYPE TWO31r;
5627 rtx two31;
5628
5629 if (TARGET_AVX512F)
5630 {
5631 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5632 DONE;
5633 }
5634
5635 if (optimize_insn_for_size_p ())
5636 FAIL;
5637
5638 real_ldexp (&TWO31r, &dconst1, 31);
5639 two31 = const_double_from_real_value (TWO31r, mode);
5640 two31 = ix86_build_const_vector (vecmode, true, two31);
5641 operands[2] = force_reg (vecmode, two31);
5642 })
5643
5644 (define_insn "fixuns_trunc<mode>si2_avx512f"
5645 [(set (match_operand:SI 0 "register_operand" "=r")
5646 (unsigned_fix:SI
5647 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5648 "TARGET_AVX512F && TARGET_SSE_MATH"
5649 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5650 [(set_attr "type" "sseicvt")
5651 (set_attr "prefix" "evex")
5652 (set_attr "mode" "SI")])
5653
5654 (define_insn "*fixuns_trunchfsi2zext"
5655 [(set (match_operand:DI 0 "register_operand" "=r")
5656 (zero_extend:DI
5657 (unsigned_fix:SI
5658 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5659 "TARGET_64BIT && TARGET_AVX512FP16"
5660 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5661 [(set_attr "type" "sseicvt")
5662 (set_attr "prefix" "evex")
5663 (set_attr "mode" "SI")])
5664
5665 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5666 [(set (match_operand:DI 0 "register_operand" "=r")
5667 (zero_extend:DI
5668 (unsigned_fix:SI
5669 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5670 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5671 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5672 [(set_attr "type" "sseicvt")
5673 (set_attr "prefix" "evex")
5674 (set_attr "mode" "SI")])
5675
5676 (define_insn_and_split "*fixuns_trunc<mode>_1"
5677 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5678 (unsigned_fix:SI
5679 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5680 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5681 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5682 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5683 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5684 && optimize_function_for_speed_p (cfun)"
5685 "#"
5686 "&& reload_completed"
5687 [(const_int 0)]
5688 {
5689 ix86_split_convert_uns_si_sse (operands);
5690 DONE;
5691 })
5692
5693 ;; Unsigned conversion to HImode.
5694 ;; Without these patterns, we'll try the unsigned SI conversion which
5695 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5696
5697 (define_expand "fixuns_trunchfhi2"
5698 [(set (match_dup 2)
5699 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5700 (set (match_operand:HI 0 "nonimmediate_operand")
5701 (subreg:HI (match_dup 2) 0))]
5702 "TARGET_AVX512FP16"
5703 "operands[2] = gen_reg_rtx (SImode);")
5704
5705 (define_expand "fixuns_trunc<mode>hi2"
5706 [(set (match_dup 2)
5707 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5708 (set (match_operand:HI 0 "nonimmediate_operand")
5709 (subreg:HI (match_dup 2) 0))]
5710 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5711 "operands[2] = gen_reg_rtx (SImode);")
5712
5713 ;; When SSE is available, it is always faster to use it!
5714 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5715 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5716 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5717 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5718 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5719 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5720 [(set_attr "type" "sseicvt")
5721 (set_attr "prefix" "maybe_vex")
5722 (set (attr "prefix_rex")
5723 (if_then_else
5724 (match_test "<SWI48:MODE>mode == DImode")
5725 (const_string "1")
5726 (const_string "*")))
5727 (set_attr "mode" "<MODEF:MODE>")
5728 (set_attr "athlon_decode" "double,vector")
5729 (set_attr "amdfam10_decode" "double,double")
5730 (set_attr "bdver1_decode" "double,double")])
5731
5732 ;; Avoid vector decoded forms of the instruction.
5733 (define_peephole2
5734 [(match_scratch:MODEF 2 "x")
5735 (set (match_operand:SWI48 0 "register_operand")
5736 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5737 "TARGET_AVOID_VECTOR_DECODE
5738 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5739 && optimize_insn_for_speed_p ()"
5740 [(set (match_dup 2) (match_dup 1))
5741 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5742
5743 (define_insn "fix_trunc<mode>_i387_fisttp"
5744 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5745 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5746 (clobber (match_scratch:XF 2 "=&f"))]
5747 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5748 && TARGET_FISTTP
5749 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5750 && (TARGET_64BIT || <MODE>mode != DImode))
5751 && TARGET_SSE_MATH)"
5752 "* return output_fix_trunc (insn, operands, true);"
5753 [(set_attr "type" "fisttp")
5754 (set_attr "mode" "<MODE>")])
5755
5756 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5757 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5758 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5759 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5760 ;; function in i386.cc.
5761 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5762 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5763 (fix:SWI248x (match_operand 1 "register_operand")))
5764 (clobber (reg:CC FLAGS_REG))]
5765 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5766 && !TARGET_FISTTP
5767 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5768 && (TARGET_64BIT || <MODE>mode != DImode))
5769 && ix86_pre_reload_split ()"
5770 "#"
5771 "&& 1"
5772 [(const_int 0)]
5773 {
5774 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5775
5776 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5777 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5778
5779 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5780 operands[2], operands[3]));
5781 DONE;
5782 }
5783 [(set_attr "type" "fistp")
5784 (set_attr "i387_cw" "trunc")
5785 (set_attr "mode" "<MODE>")])
5786
5787 (define_insn "fix_truncdi_i387"
5788 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5789 (fix:DI (match_operand 1 "register_operand" "f")))
5790 (use (match_operand:HI 2 "memory_operand" "m"))
5791 (use (match_operand:HI 3 "memory_operand" "m"))
5792 (clobber (match_scratch:XF 4 "=&f"))]
5793 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5794 && !TARGET_FISTTP
5795 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5796 "* return output_fix_trunc (insn, operands, false);"
5797 [(set_attr "type" "fistp")
5798 (set_attr "i387_cw" "trunc")
5799 (set_attr "mode" "DI")])
5800
5801 (define_insn "fix_trunc<mode>_i387"
5802 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5803 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5804 (use (match_operand:HI 2 "memory_operand" "m"))
5805 (use (match_operand:HI 3 "memory_operand" "m"))]
5806 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5807 && !TARGET_FISTTP
5808 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5809 "* return output_fix_trunc (insn, operands, false);"
5810 [(set_attr "type" "fistp")
5811 (set_attr "i387_cw" "trunc")
5812 (set_attr "mode" "<MODE>")])
5813
5814 (define_insn "x86_fnstcw_1"
5815 [(set (match_operand:HI 0 "memory_operand" "=m")
5816 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5817 "TARGET_80387"
5818 "fnstcw\t%0"
5819 [(set (attr "length")
5820 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5821 (set_attr "mode" "HI")
5822 (set_attr "unit" "i387")
5823 (set_attr "bdver1_decode" "vector")])
5824 \f
5825 ;; Conversion between fixed point and floating point.
5826
5827 ;; Even though we only accept memory inputs, the backend _really_
5828 ;; wants to be able to do this between registers. Thankfully, LRA
5829 ;; will fix this up for us during register allocation.
5830
5831 (define_insn "floathi<mode>2"
5832 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5833 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5834 "TARGET_80387
5835 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5836 || TARGET_MIX_SSE_I387)"
5837 "fild%Z1\t%1"
5838 [(set_attr "type" "fmov")
5839 (set_attr "mode" "<MODE>")
5840 (set_attr "znver1_decode" "double")
5841 (set_attr "fp_int_src" "true")])
5842
5843 (define_insn "float<SWI48x:mode>xf2"
5844 [(set (match_operand:XF 0 "register_operand" "=f")
5845 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5846 "TARGET_80387"
5847 "fild%Z1\t%1"
5848 [(set_attr "type" "fmov")
5849 (set_attr "mode" "XF")
5850 (set_attr "znver1_decode" "double")
5851 (set_attr "fp_int_src" "true")])
5852
5853 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5854 [(set (match_operand:MODEF 0 "register_operand")
5855 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5856 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5857 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5858 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5859
5860 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5861 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5862 (float:MODEF
5863 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5864 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5865 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5866 "@
5867 fild%Z1\t%1
5868 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5869 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5870 [(set_attr "type" "fmov,sseicvt,sseicvt")
5871 (set_attr "avx_partial_xmm_update" "false,true,true")
5872 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5873 (set_attr "mode" "<MODEF:MODE>")
5874 (set (attr "prefix_rex")
5875 (if_then_else
5876 (and (eq_attr "prefix" "maybe_vex")
5877 (match_test "<SWI48:MODE>mode == DImode"))
5878 (const_string "1")
5879 (const_string "*")))
5880 (set_attr "unit" "i387,*,*")
5881 (set_attr "athlon_decode" "*,double,direct")
5882 (set_attr "amdfam10_decode" "*,vector,double")
5883 (set_attr "bdver1_decode" "*,double,direct")
5884 (set_attr "znver1_decode" "double,*,*")
5885 (set_attr "fp_int_src" "true")
5886 (set (attr "enabled")
5887 (if_then_else
5888 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5889 (if_then_else
5890 (eq_attr "alternative" "0")
5891 (symbol_ref "TARGET_MIX_SSE_I387
5892 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5893 <SWI48:MODE>mode)")
5894 (symbol_ref "true"))
5895 (if_then_else
5896 (eq_attr "alternative" "0")
5897 (symbol_ref "true")
5898 (symbol_ref "false"))))
5899 (set (attr "preferred_for_speed")
5900 (cond [(eq_attr "alternative" "1")
5901 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5902 (symbol_ref "true")))])
5903
5904 (define_insn "float<floatunssuffix><mode>hf2"
5905 [(set (match_operand:HF 0 "register_operand" "=v")
5906 (any_float:HF
5907 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5908 "TARGET_AVX512FP16"
5909 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
5910 [(set_attr "type" "sseicvt")
5911 (set_attr "prefix" "evex")
5912 (set_attr "mode" "HF")])
5913
5914 (define_insn "*floatdi<MODEF:mode>2_i387"
5915 [(set (match_operand:MODEF 0 "register_operand" "=f")
5916 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5917 "!TARGET_64BIT
5918 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5919 "fild%Z1\t%1"
5920 [(set_attr "type" "fmov")
5921 (set_attr "mode" "<MODEF:MODE>")
5922 (set_attr "znver1_decode" "double")
5923 (set_attr "fp_int_src" "true")])
5924
5925 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5926 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5927 ;; alternative in sse2_loadld.
5928 (define_split
5929 [(set (match_operand:MODEF 0 "sse_reg_operand")
5930 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5931 "TARGET_SSE2
5932 && TARGET_USE_VECTOR_CONVERTS
5933 && optimize_function_for_speed_p (cfun)
5934 && reload_completed
5935 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5936 && (!EXT_REX_SSE_REG_P (operands[0])
5937 || TARGET_AVX512VL)"
5938 [(const_int 0)]
5939 {
5940 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5941 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5942
5943 emit_insn (gen_sse2_loadld (operands[4],
5944 CONST0_RTX (V4SImode), operands[1]));
5945
5946 if (<ssevecmode>mode == V4SFmode)
5947 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5948 else
5949 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5950 DONE;
5951 })
5952
5953 ;; Avoid store forwarding (partial memory) stall penalty
5954 ;; by passing DImode value through XMM registers. */
5955
5956 (define_split
5957 [(set (match_operand:X87MODEF 0 "register_operand")
5958 (float:X87MODEF
5959 (match_operand:DI 1 "register_operand")))]
5960 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5961 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5962 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5963 && can_create_pseudo_p ()"
5964 [(const_int 0)]
5965 {
5966 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
5967 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
5968 DONE;
5969 })
5970
5971 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5972 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5973 (float:X87MODEF
5974 (match_operand:DI 1 "register_operand" "r,r")))
5975 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5976 (clobber (match_scratch:V4SI 3 "=x,x"))
5977 (clobber (match_scratch:V4SI 4 "=X,x"))]
5978 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5979 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5980 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5981 "#"
5982 "&& reload_completed"
5983 [(set (match_dup 2) (match_dup 3))
5984 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5985 {
5986 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5987 Assemble the 64-bit DImode value in an xmm register. */
5988 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5989 gen_lowpart (SImode, operands[1])));
5990 if (TARGET_SSE4_1)
5991 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5992 gen_highpart (SImode, operands[1]),
5993 GEN_INT (2)));
5994 else
5995 {
5996 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5997 gen_highpart (SImode, operands[1])));
5998 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5999 operands[4]));
6000 }
6001 operands[3] = gen_lowpart (DImode, operands[3]);
6002 }
6003 [(set_attr "isa" "sse4,*")
6004 (set_attr "type" "multi")
6005 (set_attr "mode" "<X87MODEF:MODE>")
6006 (set_attr "unit" "i387")
6007 (set_attr "fp_int_src" "true")])
6008
6009 ;; Break partial SSE register dependency stall. This splitter should split
6010 ;; late in the pass sequence (after register rename pass), so allocated
6011 ;; registers won't change anymore
6012
6013 (define_split
6014 [(set (match_operand:MODEF 0 "sse_reg_operand")
6015 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
6016 "!TARGET_AVX
6017 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
6018 && epilogue_completed
6019 && optimize_function_for_speed_p (cfun)
6020 && (!EXT_REX_SSE_REG_P (operands[0])
6021 || TARGET_AVX512VL)"
6022 [(set (match_dup 0)
6023 (vec_merge:<MODEF:ssevecmode>
6024 (vec_duplicate:<MODEF:ssevecmode>
6025 (float:MODEF
6026 (match_dup 1)))
6027 (match_dup 0)
6028 (const_int 1)))]
6029 {
6030 const machine_mode vmode = <MODEF:ssevecmode>mode;
6031
6032 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
6033 emit_move_insn (operands[0], CONST0_RTX (vmode));
6034 })
6035
6036 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
6037 [(set (match_operand:MODEF 0 "register_operand")
6038 (unsigned_float:MODEF
6039 (match_operand:SWI12 1 "nonimmediate_operand")))]
6040 "!TARGET_64BIT
6041 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
6042 {
6043 operands[1] = convert_to_mode (SImode, operands[1], 1);
6044 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
6045 DONE;
6046 })
6047
6048 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
6049 [(set (match_operand:MODEF 0 "register_operand" "=v")
6050 (unsigned_float:MODEF
6051 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
6052 "TARGET_AVX512F && TARGET_SSE_MATH"
6053 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
6054 [(set_attr "type" "sseicvt")
6055 (set_attr "avx_partial_xmm_update" "true")
6056 (set_attr "prefix" "evex")
6057 (set_attr "mode" "<MODEF:MODE>")])
6058
6059 ;; Avoid store forwarding (partial memory) stall penalty by extending
6060 ;; SImode value to DImode through XMM register instead of pushing two
6061 ;; SImode values to stack. Also note that fild loads from memory only.
6062
6063 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
6064 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
6065 (unsigned_float:X87MODEF
6066 (match_operand:SI 1 "nonimmediate_operand" "rm")))
6067 (clobber (match_operand:DI 2 "memory_operand" "=m"))
6068 (clobber (match_scratch:DI 3 "=x"))]
6069 "!TARGET_64BIT
6070 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6071 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6072 "#"
6073 "&& reload_completed"
6074 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6075 (set (match_dup 2) (match_dup 3))
6076 (set (match_dup 0)
6077 (float:X87MODEF (match_dup 2)))]
6078 ""
6079 [(set_attr "type" "multi")
6080 (set_attr "mode" "<MODE>")])
6081
6082 (define_expand "floatunssi<mode>2"
6083 [(set (match_operand:X87MODEF 0 "register_operand")
6084 (unsigned_float:X87MODEF
6085 (match_operand:SI 1 "nonimmediate_operand")))]
6086 "(!TARGET_64BIT
6087 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6088 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6089 || ((!TARGET_64BIT || TARGET_AVX512F)
6090 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6091 {
6092 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6093 {
6094 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6095 (operands[0], operands[1],
6096 assign_386_stack_local (DImode, SLOT_TEMP)));
6097 DONE;
6098 }
6099 if (!TARGET_AVX512F)
6100 {
6101 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6102 DONE;
6103 }
6104 })
6105
6106 (define_expand "floatunsdisf2"
6107 [(set (match_operand:SF 0 "register_operand")
6108 (unsigned_float:SF
6109 (match_operand:DI 1 "nonimmediate_operand")))]
6110 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6111 {
6112 if (!TARGET_AVX512F)
6113 {
6114 x86_emit_floatuns (operands);
6115 DONE;
6116 }
6117 })
6118
6119 (define_expand "floatunsdidf2"
6120 [(set (match_operand:DF 0 "register_operand")
6121 (unsigned_float:DF
6122 (match_operand:DI 1 "nonimmediate_operand")))]
6123 "((TARGET_64BIT && TARGET_AVX512F)
6124 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6125 && TARGET_SSE2 && TARGET_SSE_MATH"
6126 {
6127 if (!TARGET_64BIT)
6128 {
6129 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6130 DONE;
6131 }
6132 if (!TARGET_AVX512F)
6133 {
6134 x86_emit_floatuns (operands);
6135 DONE;
6136 }
6137 })
6138 \f
6139 ;; Load effective address instructions
6140
6141 (define_insn "*lea<mode>"
6142 [(set (match_operand:SWI48 0 "register_operand" "=r")
6143 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6144 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6145 {
6146 if (SImode_address_operand (operands[1], VOIDmode))
6147 {
6148 gcc_assert (TARGET_64BIT);
6149 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6150 }
6151 else
6152 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6153 }
6154 [(set_attr "type" "lea")
6155 (set (attr "mode")
6156 (if_then_else
6157 (match_operand 1 "SImode_address_operand")
6158 (const_string "SI")
6159 (const_string "<MODE>")))])
6160
6161 (define_peephole2
6162 [(set (match_operand:SWI48 0 "register_operand")
6163 (match_operand:SWI48 1 "address_no_seg_operand"))]
6164 "ix86_hardreg_mov_ok (operands[0], operands[1])
6165 && peep2_regno_dead_p (0, FLAGS_REG)
6166 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6167 [(const_int 0)]
6168 {
6169 machine_mode mode = <MODE>mode;
6170
6171 /* Emit all operations in SImode for zero-extended addresses. */
6172 if (SImode_address_operand (operands[1], VOIDmode))
6173 mode = SImode;
6174
6175 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6176
6177 /* Zero-extend return register to DImode for zero-extended addresses. */
6178 if (mode != <MODE>mode)
6179 emit_insn (gen_zero_extendsidi2 (operands[0],
6180 gen_lowpart (mode, operands[0])));
6181
6182 DONE;
6183 })
6184
6185 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6186 ;; peephole2 optimized back into a lea. Split that into the shift during
6187 ;; the following split pass.
6188 (define_split
6189 [(set (match_operand:SWI48 0 "general_reg_operand")
6190 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6191 (clobber (reg:CC FLAGS_REG))]
6192 "reload_completed"
6193 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6194 (clobber (reg:CC FLAGS_REG))])]
6195 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6196 \f
6197 ;; Add instructions
6198
6199 (define_expand "add<mode>3"
6200 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6201 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6202 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6203 ""
6204 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6205
6206 (define_insn_and_split "*add<dwi>3_doubleword"
6207 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6208 (plus:<DWI>
6209 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6210 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6211 (clobber (reg:CC FLAGS_REG))]
6212 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6213 "#"
6214 "&& reload_completed"
6215 [(parallel [(set (reg:CCC FLAGS_REG)
6216 (compare:CCC
6217 (plus:DWIH (match_dup 1) (match_dup 2))
6218 (match_dup 1)))
6219 (set (match_dup 0)
6220 (plus:DWIH (match_dup 1) (match_dup 2)))])
6221 (parallel [(set (match_dup 3)
6222 (plus:DWIH
6223 (plus:DWIH
6224 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6225 (match_dup 4))
6226 (match_dup 5)))
6227 (clobber (reg:CC FLAGS_REG))])]
6228 {
6229 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6230 if (operands[2] == const0_rtx)
6231 {
6232 if (operands[5] != const0_rtx)
6233 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6234 else if (!rtx_equal_p (operands[3], operands[4]))
6235 emit_move_insn (operands[3], operands[4]);
6236 else
6237 emit_note (NOTE_INSN_DELETED);
6238 DONE;
6239 }
6240 })
6241
6242 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6243 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6244 (plus:<DWI>
6245 (zero_extend:<DWI>
6246 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))
6247 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6248 (clobber (reg:CC FLAGS_REG))]
6249 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6250 "#"
6251 "&& reload_completed"
6252 [(parallel [(set (reg:CCC FLAGS_REG)
6253 (compare:CCC
6254 (plus:DWIH (match_dup 1) (match_dup 2))
6255 (match_dup 1)))
6256 (set (match_dup 0)
6257 (plus:DWIH (match_dup 1) (match_dup 2)))])
6258 (parallel [(set (match_dup 3)
6259 (plus:DWIH
6260 (plus:DWIH
6261 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6262 (match_dup 4))
6263 (const_int 0)))
6264 (clobber (reg:CC FLAGS_REG))])]
6265 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6266
6267 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6268 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6269 (plus:<DWI>
6270 (any_or_plus:<DWI>
6271 (ashift:<DWI>
6272 (zero_extend:<DWI>
6273 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6274 (match_operand:QI 3 "const_int_operand"))
6275 (zero_extend:<DWI>
6276 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6277 (match_operand:<DWI> 1 "register_operand" "0")))
6278 (clobber (reg:CC FLAGS_REG))]
6279 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6280 "#"
6281 "&& reload_completed"
6282 [(parallel [(set (reg:CCC FLAGS_REG)
6283 (compare:CCC
6284 (plus:DWIH (match_dup 1) (match_dup 4))
6285 (match_dup 1)))
6286 (set (match_dup 0)
6287 (plus:DWIH (match_dup 1) (match_dup 4)))])
6288 (parallel [(set (match_dup 5)
6289 (plus:DWIH
6290 (plus:DWIH
6291 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6292 (match_dup 6))
6293 (match_dup 2)))
6294 (clobber (reg:CC FLAGS_REG))])]
6295 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6296
6297 (define_insn_and_split "*add<dwi>3_doubleword_concat_zext"
6298 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6299 (plus:<DWI>
6300 (any_or_plus:<DWI>
6301 (ashift:<DWI>
6302 (zero_extend:<DWI>
6303 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6304 (match_operand:QI 3 "const_int_operand"))
6305 (zero_extend:<DWI>
6306 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6307 (zero_extend:<DWI>
6308 (match_operand:DWIH 1 "nonimmediate_operand" "rm"))))
6309 (clobber (reg:CC FLAGS_REG))]
6310 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6311 "#"
6312 "&& reload_completed"
6313 [(set (match_dup 0) (match_dup 4))
6314 (set (match_dup 5) (match_dup 2))
6315 (parallel [(set (reg:CCC FLAGS_REG)
6316 (compare:CCC
6317 (plus:DWIH (match_dup 0) (match_dup 1))
6318 (match_dup 0)))
6319 (set (match_dup 0)
6320 (plus:DWIH (match_dup 0) (match_dup 1)))])
6321 (parallel [(set (match_dup 5)
6322 (plus:DWIH
6323 (plus:DWIH
6324 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6325 (match_dup 5))
6326 (const_int 0)))
6327 (clobber (reg:CC FLAGS_REG))])]
6328 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[5]);")
6329
6330 (define_insn "*add<mode>_1"
6331 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6332 (plus:SWI48
6333 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6334 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6335 (clobber (reg:CC FLAGS_REG))]
6336 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6337 {
6338 switch (get_attr_type (insn))
6339 {
6340 case TYPE_LEA:
6341 return "#";
6342
6343 case TYPE_INCDEC:
6344 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6345 if (operands[2] == const1_rtx)
6346 return "inc{<imodesuffix>}\t%0";
6347 else
6348 {
6349 gcc_assert (operands[2] == constm1_rtx);
6350 return "dec{<imodesuffix>}\t%0";
6351 }
6352
6353 default:
6354 /* For most processors, ADD is faster than LEA. This alternative
6355 was added to use ADD as much as possible. */
6356 if (which_alternative == 2)
6357 std::swap (operands[1], operands[2]);
6358
6359 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6360 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6361 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6362
6363 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6364 }
6365 }
6366 [(set (attr "type")
6367 (cond [(eq_attr "alternative" "3")
6368 (const_string "lea")
6369 (match_operand:SWI48 2 "incdec_operand")
6370 (const_string "incdec")
6371 ]
6372 (const_string "alu")))
6373 (set (attr "length_immediate")
6374 (if_then_else
6375 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6376 (const_string "1")
6377 (const_string "*")))
6378 (set_attr "mode" "<MODE>")])
6379
6380 ;; It may seem that nonimmediate operand is proper one for operand 1.
6381 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6382 ;; we take care in ix86_binary_operator_ok to not allow two memory
6383 ;; operands so proper swapping will be done in reload. This allow
6384 ;; patterns constructed from addsi_1 to match.
6385
6386 (define_insn "addsi_1_zext"
6387 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6388 (zero_extend:DI
6389 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6390 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6391 (clobber (reg:CC FLAGS_REG))]
6392 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6393 {
6394 switch (get_attr_type (insn))
6395 {
6396 case TYPE_LEA:
6397 return "#";
6398
6399 case TYPE_INCDEC:
6400 if (operands[2] == const1_rtx)
6401 return "inc{l}\t%k0";
6402 else
6403 {
6404 gcc_assert (operands[2] == constm1_rtx);
6405 return "dec{l}\t%k0";
6406 }
6407
6408 default:
6409 /* For most processors, ADD is faster than LEA. This alternative
6410 was added to use ADD as much as possible. */
6411 if (which_alternative == 1)
6412 std::swap (operands[1], operands[2]);
6413
6414 if (x86_maybe_negate_const_int (&operands[2], SImode))
6415 return "sub{l}\t{%2, %k0|%k0, %2}";
6416
6417 return "add{l}\t{%2, %k0|%k0, %2}";
6418 }
6419 }
6420 [(set (attr "type")
6421 (cond [(eq_attr "alternative" "2")
6422 (const_string "lea")
6423 (match_operand:SI 2 "incdec_operand")
6424 (const_string "incdec")
6425 ]
6426 (const_string "alu")))
6427 (set (attr "length_immediate")
6428 (if_then_else
6429 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6430 (const_string "1")
6431 (const_string "*")))
6432 (set_attr "mode" "SI")])
6433
6434 (define_insn "*addhi_1"
6435 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6436 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6437 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6438 (clobber (reg:CC FLAGS_REG))]
6439 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6440 {
6441 switch (get_attr_type (insn))
6442 {
6443 case TYPE_LEA:
6444 return "#";
6445
6446 case TYPE_INCDEC:
6447 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6448 if (operands[2] == const1_rtx)
6449 return "inc{w}\t%0";
6450 else
6451 {
6452 gcc_assert (operands[2] == constm1_rtx);
6453 return "dec{w}\t%0";
6454 }
6455
6456 default:
6457 /* For most processors, ADD is faster than LEA. This alternative
6458 was added to use ADD as much as possible. */
6459 if (which_alternative == 2)
6460 std::swap (operands[1], operands[2]);
6461
6462 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6463 if (x86_maybe_negate_const_int (&operands[2], HImode))
6464 return "sub{w}\t{%2, %0|%0, %2}";
6465
6466 return "add{w}\t{%2, %0|%0, %2}";
6467 }
6468 }
6469 [(set (attr "type")
6470 (cond [(eq_attr "alternative" "3")
6471 (const_string "lea")
6472 (match_operand:HI 2 "incdec_operand")
6473 (const_string "incdec")
6474 ]
6475 (const_string "alu")))
6476 (set (attr "length_immediate")
6477 (if_then_else
6478 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6479 (const_string "1")
6480 (const_string "*")))
6481 (set_attr "mode" "HI,HI,HI,SI")])
6482
6483 (define_insn "*addqi_1"
6484 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6485 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6486 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6487 (clobber (reg:CC FLAGS_REG))]
6488 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6489 {
6490 bool widen = (get_attr_mode (insn) != MODE_QI);
6491
6492 switch (get_attr_type (insn))
6493 {
6494 case TYPE_LEA:
6495 return "#";
6496
6497 case TYPE_INCDEC:
6498 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6499 if (operands[2] == const1_rtx)
6500 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6501 else
6502 {
6503 gcc_assert (operands[2] == constm1_rtx);
6504 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6505 }
6506
6507 default:
6508 /* For most processors, ADD is faster than LEA. These alternatives
6509 were added to use ADD as much as possible. */
6510 if (which_alternative == 2 || which_alternative == 4)
6511 std::swap (operands[1], operands[2]);
6512
6513 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6514 if (x86_maybe_negate_const_int (&operands[2], QImode))
6515 {
6516 if (widen)
6517 return "sub{l}\t{%2, %k0|%k0, %2}";
6518 else
6519 return "sub{b}\t{%2, %0|%0, %2}";
6520 }
6521 if (widen)
6522 return "add{l}\t{%k2, %k0|%k0, %k2}";
6523 else
6524 return "add{b}\t{%2, %0|%0, %2}";
6525 }
6526 }
6527 [(set (attr "type")
6528 (cond [(eq_attr "alternative" "5")
6529 (const_string "lea")
6530 (match_operand:QI 2 "incdec_operand")
6531 (const_string "incdec")
6532 ]
6533 (const_string "alu")))
6534 (set (attr "length_immediate")
6535 (if_then_else
6536 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6537 (const_string "1")
6538 (const_string "*")))
6539 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6540 ;; Potential partial reg stall on alternatives 3 and 4.
6541 (set (attr "preferred_for_speed")
6542 (cond [(eq_attr "alternative" "3,4")
6543 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6544 (symbol_ref "true")))])
6545
6546 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6547 (define_insn_and_split "*add<mode>_1_slp"
6548 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6549 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6550 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6551 (clobber (reg:CC FLAGS_REG))]
6552 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6553 {
6554 if (which_alternative)
6555 return "#";
6556
6557 switch (get_attr_type (insn))
6558 {
6559 case TYPE_INCDEC:
6560 if (operands[2] == const1_rtx)
6561 return "inc{<imodesuffix>}\t%0";
6562 else
6563 {
6564 gcc_assert (operands[2] == constm1_rtx);
6565 return "dec{<imodesuffix>}\t%0";
6566 }
6567
6568 default:
6569 if (x86_maybe_negate_const_int (&operands[2], QImode))
6570 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6571
6572 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6573 }
6574 }
6575 "&& reload_completed"
6576 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6577 (parallel
6578 [(set (strict_low_part (match_dup 0))
6579 (plus:SWI12 (match_dup 0) (match_dup 2)))
6580 (clobber (reg:CC FLAGS_REG))])]
6581 ""
6582 [(set (attr "type")
6583 (if_then_else (match_operand:QI 2 "incdec_operand")
6584 (const_string "incdec")
6585 (const_string "alu")))
6586 (set_attr "mode" "<MODE>")])
6587
6588 ;; Split non destructive adds if we cannot use lea.
6589 (define_split
6590 [(set (match_operand:SWI48 0 "register_operand")
6591 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6592 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6593 (clobber (reg:CC FLAGS_REG))]
6594 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6595 [(set (match_dup 0) (match_dup 1))
6596 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6597 (clobber (reg:CC FLAGS_REG))])])
6598
6599 ;; Split non destructive adds if we cannot use lea.
6600 (define_split
6601 [(set (match_operand:DI 0 "register_operand")
6602 (zero_extend:DI
6603 (plus:SI (match_operand:SI 1 "register_operand")
6604 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6605 (clobber (reg:CC FLAGS_REG))]
6606 "TARGET_64BIT
6607 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6608 [(set (match_dup 3) (match_dup 1))
6609 (parallel [(set (match_dup 0)
6610 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6611 (clobber (reg:CC FLAGS_REG))])]
6612 "operands[3] = gen_lowpart (SImode, operands[0]);")
6613
6614 ;; Convert add to the lea pattern to avoid flags dependency.
6615 (define_split
6616 [(set (match_operand:SWI 0 "register_operand")
6617 (plus:SWI (match_operand:SWI 1 "register_operand")
6618 (match_operand:SWI 2 "<nonmemory_operand>")))
6619 (clobber (reg:CC FLAGS_REG))]
6620 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6621 [(set (match_dup 0)
6622 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6623 {
6624 if (<MODE>mode != <LEAMODE>mode)
6625 {
6626 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6627 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6628 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6629 }
6630 })
6631
6632 ;; Convert add to the lea pattern to avoid flags dependency.
6633 (define_split
6634 [(set (match_operand:DI 0 "register_operand")
6635 (zero_extend:DI
6636 (plus:SI (match_operand:SI 1 "register_operand")
6637 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6638 (clobber (reg:CC FLAGS_REG))]
6639 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6640 [(set (match_dup 0)
6641 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6642
6643 (define_insn "*add<mode>_2"
6644 [(set (reg FLAGS_REG)
6645 (compare
6646 (plus:SWI
6647 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6648 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6649 (const_int 0)))
6650 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6651 (plus:SWI (match_dup 1) (match_dup 2)))]
6652 "ix86_match_ccmode (insn, CCGOCmode)
6653 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6654 {
6655 switch (get_attr_type (insn))
6656 {
6657 case TYPE_INCDEC:
6658 if (operands[2] == const1_rtx)
6659 return "inc{<imodesuffix>}\t%0";
6660 else
6661 {
6662 gcc_assert (operands[2] == constm1_rtx);
6663 return "dec{<imodesuffix>}\t%0";
6664 }
6665
6666 default:
6667 if (which_alternative == 2)
6668 std::swap (operands[1], operands[2]);
6669
6670 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6671 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6672 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6673
6674 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6675 }
6676 }
6677 [(set (attr "type")
6678 (if_then_else (match_operand:SWI 2 "incdec_operand")
6679 (const_string "incdec")
6680 (const_string "alu")))
6681 (set (attr "length_immediate")
6682 (if_then_else
6683 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6684 (const_string "1")
6685 (const_string "*")))
6686 (set_attr "mode" "<MODE>")])
6687
6688 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6689 (define_insn "*addsi_2_zext"
6690 [(set (reg FLAGS_REG)
6691 (compare
6692 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6693 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6694 (const_int 0)))
6695 (set (match_operand:DI 0 "register_operand" "=r,r")
6696 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6697 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6698 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6699 {
6700 switch (get_attr_type (insn))
6701 {
6702 case TYPE_INCDEC:
6703 if (operands[2] == const1_rtx)
6704 return "inc{l}\t%k0";
6705 else
6706 {
6707 gcc_assert (operands[2] == constm1_rtx);
6708 return "dec{l}\t%k0";
6709 }
6710
6711 default:
6712 if (which_alternative == 1)
6713 std::swap (operands[1], operands[2]);
6714
6715 if (x86_maybe_negate_const_int (&operands[2], SImode))
6716 return "sub{l}\t{%2, %k0|%k0, %2}";
6717
6718 return "add{l}\t{%2, %k0|%k0, %2}";
6719 }
6720 }
6721 [(set (attr "type")
6722 (if_then_else (match_operand:SI 2 "incdec_operand")
6723 (const_string "incdec")
6724 (const_string "alu")))
6725 (set (attr "length_immediate")
6726 (if_then_else
6727 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6728 (const_string "1")
6729 (const_string "*")))
6730 (set_attr "mode" "SI")])
6731
6732 (define_insn "*add<mode>_3"
6733 [(set (reg FLAGS_REG)
6734 (compare
6735 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6736 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6737 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6738 "ix86_match_ccmode (insn, CCZmode)
6739 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6740 {
6741 switch (get_attr_type (insn))
6742 {
6743 case TYPE_INCDEC:
6744 if (operands[2] == const1_rtx)
6745 return "inc{<imodesuffix>}\t%0";
6746 else
6747 {
6748 gcc_assert (operands[2] == constm1_rtx);
6749 return "dec{<imodesuffix>}\t%0";
6750 }
6751
6752 default:
6753 if (which_alternative == 1)
6754 std::swap (operands[1], operands[2]);
6755
6756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6757 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6758 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6759
6760 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6761 }
6762 }
6763 [(set (attr "type")
6764 (if_then_else (match_operand:SWI 2 "incdec_operand")
6765 (const_string "incdec")
6766 (const_string "alu")))
6767 (set (attr "length_immediate")
6768 (if_then_else
6769 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6770 (const_string "1")
6771 (const_string "*")))
6772 (set_attr "mode" "<MODE>")])
6773
6774 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6775 (define_insn "*addsi_3_zext"
6776 [(set (reg FLAGS_REG)
6777 (compare
6778 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6779 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6780 (set (match_operand:DI 0 "register_operand" "=r,r")
6781 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6782 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6783 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6784 {
6785 switch (get_attr_type (insn))
6786 {
6787 case TYPE_INCDEC:
6788 if (operands[2] == const1_rtx)
6789 return "inc{l}\t%k0";
6790 else
6791 {
6792 gcc_assert (operands[2] == constm1_rtx);
6793 return "dec{l}\t%k0";
6794 }
6795
6796 default:
6797 if (which_alternative == 1)
6798 std::swap (operands[1], operands[2]);
6799
6800 if (x86_maybe_negate_const_int (&operands[2], SImode))
6801 return "sub{l}\t{%2, %k0|%k0, %2}";
6802
6803 return "add{l}\t{%2, %k0|%k0, %2}";
6804 }
6805 }
6806 [(set (attr "type")
6807 (if_then_else (match_operand:SI 2 "incdec_operand")
6808 (const_string "incdec")
6809 (const_string "alu")))
6810 (set (attr "length_immediate")
6811 (if_then_else
6812 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6813 (const_string "1")
6814 (const_string "*")))
6815 (set_attr "mode" "SI")])
6816
6817 ; For comparisons against 1, -1 and 128, we may generate better code
6818 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6819 ; is matched then. We can't accept general immediate, because for
6820 ; case of overflows, the result is messed up.
6821 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6822 ; only for comparisons not depending on it.
6823
6824 (define_insn "*adddi_4"
6825 [(set (reg FLAGS_REG)
6826 (compare
6827 (match_operand:DI 1 "nonimmediate_operand" "0")
6828 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6829 (clobber (match_scratch:DI 0 "=r"))]
6830 "TARGET_64BIT
6831 && ix86_match_ccmode (insn, CCGCmode)"
6832 {
6833 switch (get_attr_type (insn))
6834 {
6835 case TYPE_INCDEC:
6836 if (operands[2] == constm1_rtx)
6837 return "inc{q}\t%0";
6838 else
6839 {
6840 gcc_assert (operands[2] == const1_rtx);
6841 return "dec{q}\t%0";
6842 }
6843
6844 default:
6845 if (x86_maybe_negate_const_int (&operands[2], DImode))
6846 return "add{q}\t{%2, %0|%0, %2}";
6847
6848 return "sub{q}\t{%2, %0|%0, %2}";
6849 }
6850 }
6851 [(set (attr "type")
6852 (if_then_else (match_operand:DI 2 "incdec_operand")
6853 (const_string "incdec")
6854 (const_string "alu")))
6855 (set (attr "length_immediate")
6856 (if_then_else
6857 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6858 (const_string "1")
6859 (const_string "*")))
6860 (set_attr "mode" "DI")])
6861
6862 ; For comparisons against 1, -1 and 128, we may generate better code
6863 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6864 ; is matched then. We can't accept general immediate, because for
6865 ; case of overflows, the result is messed up.
6866 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6867 ; only for comparisons not depending on it.
6868
6869 (define_insn "*add<mode>_4"
6870 [(set (reg FLAGS_REG)
6871 (compare
6872 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6873 (match_operand:SWI124 2 "const_int_operand")))
6874 (clobber (match_scratch:SWI124 0 "=<r>"))]
6875 "ix86_match_ccmode (insn, CCGCmode)"
6876 {
6877 switch (get_attr_type (insn))
6878 {
6879 case TYPE_INCDEC:
6880 if (operands[2] == constm1_rtx)
6881 return "inc{<imodesuffix>}\t%0";
6882 else
6883 {
6884 gcc_assert (operands[2] == const1_rtx);
6885 return "dec{<imodesuffix>}\t%0";
6886 }
6887
6888 default:
6889 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6890 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6891
6892 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6893 }
6894 }
6895 [(set (attr "type")
6896 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6897 (const_string "incdec")
6898 (const_string "alu")))
6899 (set (attr "length_immediate")
6900 (if_then_else
6901 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6902 (const_string "1")
6903 (const_string "*")))
6904 (set_attr "mode" "<MODE>")])
6905
6906 (define_insn "*add<mode>_5"
6907 [(set (reg FLAGS_REG)
6908 (compare
6909 (plus:SWI
6910 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6911 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6912 (const_int 0)))
6913 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6914 "ix86_match_ccmode (insn, CCGOCmode)
6915 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6916 {
6917 switch (get_attr_type (insn))
6918 {
6919 case TYPE_INCDEC:
6920 if (operands[2] == const1_rtx)
6921 return "inc{<imodesuffix>}\t%0";
6922 else
6923 {
6924 gcc_assert (operands[2] == constm1_rtx);
6925 return "dec{<imodesuffix>}\t%0";
6926 }
6927
6928 default:
6929 if (which_alternative == 1)
6930 std::swap (operands[1], operands[2]);
6931
6932 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6933 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6934 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6935
6936 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6937 }
6938 }
6939 [(set (attr "type")
6940 (if_then_else (match_operand:SWI 2 "incdec_operand")
6941 (const_string "incdec")
6942 (const_string "alu")))
6943 (set (attr "length_immediate")
6944 (if_then_else
6945 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6946 (const_string "1")
6947 (const_string "*")))
6948 (set_attr "mode" "<MODE>")])
6949
6950 (define_insn "*addqi_ext<mode>_0"
6951 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
6952 (plus:QI
6953 (subreg:QI
6954 (match_operator:SWI248 3 "extract_operator"
6955 [(match_operand 2 "int248_register_operand" "Q,Q")
6956 (const_int 8)
6957 (const_int 8)]) 0)
6958 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
6959 (clobber (reg:CC FLAGS_REG))]
6960 ""
6961 "add{b}\t{%h2, %0|%0, %h2}"
6962 [(set_attr "isa" "*,nox64")
6963 (set_attr "type" "alu")
6964 (set_attr "mode" "QI")])
6965
6966 (define_expand "addqi_ext_1"
6967 [(parallel
6968 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
6969 (const_int 8)
6970 (const_int 8))
6971 (subreg:HI
6972 (plus:QI
6973 (subreg:QI
6974 (zero_extract:HI (match_operand:HI 1 "register_operand")
6975 (const_int 8)
6976 (const_int 8)) 0)
6977 (match_operand:QI 2 "const_int_operand")) 0))
6978 (clobber (reg:CC FLAGS_REG))])])
6979
6980 (define_insn "*addqi_ext<mode>_1"
6981 [(set (zero_extract:SWI248
6982 (match_operand 0 "int248_register_operand" "+Q,Q")
6983 (const_int 8)
6984 (const_int 8))
6985 (subreg:SWI248
6986 (plus:QI
6987 (subreg:QI
6988 (match_operator:SWI248 3 "extract_operator"
6989 [(match_operand 1 "int248_register_operand" "0,0")
6990 (const_int 8)
6991 (const_int 8)]) 0)
6992 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
6993 (clobber (reg:CC FLAGS_REG))]
6994 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6995 rtx_equal_p (operands[0], operands[1])"
6996 {
6997 switch (get_attr_type (insn))
6998 {
6999 case TYPE_INCDEC:
7000 if (operands[2] == const1_rtx)
7001 return "inc{b}\t%h0";
7002 else
7003 {
7004 gcc_assert (operands[2] == constm1_rtx);
7005 return "dec{b}\t%h0";
7006 }
7007
7008 default:
7009 return "add{b}\t{%2, %h0|%h0, %2}";
7010 }
7011 }
7012 [(set_attr "isa" "*,nox64")
7013 (set (attr "type")
7014 (if_then_else (match_operand:QI 2 "incdec_operand")
7015 (const_string "incdec")
7016 (const_string "alu")))
7017 (set_attr "mode" "QI")])
7018
7019 (define_insn "*addqi_ext<mode>_2"
7020 [(set (zero_extract:SWI248
7021 (match_operand 0 "int248_register_operand" "+Q")
7022 (const_int 8)
7023 (const_int 8))
7024 (subreg:SWI248
7025 (plus:QI
7026 (subreg:QI
7027 (match_operator:SWI248 3 "extract_operator"
7028 [(match_operand 1 "int248_register_operand" "%0")
7029 (const_int 8)
7030 (const_int 8)]) 0)
7031 (subreg:QI
7032 (match_operator:SWI248 4 "extract_operator"
7033 [(match_operand 2 "int248_register_operand" "Q")
7034 (const_int 8)
7035 (const_int 8)]) 0)) 0))
7036 (clobber (reg:CC FLAGS_REG))]
7037 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7038 rtx_equal_p (operands[0], operands[1])
7039 || rtx_equal_p (operands[0], operands[2])"
7040 "add{b}\t{%h2, %h0|%h0, %h2}"
7041 [(set_attr "type" "alu")
7042 (set_attr "mode" "QI")])
7043
7044 ;; Like DWI, but use POImode instead of OImode.
7045 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7046
7047 ;; Add with jump on overflow.
7048 (define_expand "addv<mode>4"
7049 [(parallel [(set (reg:CCO FLAGS_REG)
7050 (eq:CCO
7051 (plus:<DPWI>
7052 (sign_extend:<DPWI>
7053 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7054 (match_dup 4))
7055 (sign_extend:<DPWI>
7056 (plus:SWIDWI (match_dup 1)
7057 (match_operand:SWIDWI 2
7058 "<general_hilo_operand>")))))
7059 (set (match_operand:SWIDWI 0 "register_operand")
7060 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7061 (set (pc) (if_then_else
7062 (eq (reg:CCO FLAGS_REG) (const_int 0))
7063 (label_ref (match_operand 3))
7064 (pc)))]
7065 ""
7066 {
7067 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7068 if (CONST_SCALAR_INT_P (operands[2]))
7069 operands[4] = operands[2];
7070 else
7071 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7072 })
7073
7074 (define_insn "*addv<mode>4"
7075 [(set (reg:CCO FLAGS_REG)
7076 (eq:CCO (plus:<DWI>
7077 (sign_extend:<DWI>
7078 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7079 (sign_extend:<DWI>
7080 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7081 (sign_extend:<DWI>
7082 (plus:SWI (match_dup 1) (match_dup 2)))))
7083 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7084 (plus:SWI (match_dup 1) (match_dup 2)))]
7085 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7086 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7087 [(set_attr "type" "alu")
7088 (set_attr "mode" "<MODE>")])
7089
7090 (define_insn "addv<mode>4_1"
7091 [(set (reg:CCO FLAGS_REG)
7092 (eq:CCO (plus:<DWI>
7093 (sign_extend:<DWI>
7094 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7095 (match_operand:<DWI> 3 "const_int_operand"))
7096 (sign_extend:<DWI>
7097 (plus:SWI
7098 (match_dup 1)
7099 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7100 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7101 (plus:SWI (match_dup 1) (match_dup 2)))]
7102 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7103 && CONST_INT_P (operands[2])
7104 && INTVAL (operands[2]) == INTVAL (operands[3])"
7105 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7106 [(set_attr "type" "alu")
7107 (set_attr "mode" "<MODE>")
7108 (set (attr "length_immediate")
7109 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7110 (const_string "1")
7111 (match_test "<MODE_SIZE> == 8")
7112 (const_string "4")]
7113 (const_string "<MODE_SIZE>")))])
7114
7115 ;; Quad word integer modes as mode attribute.
7116 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7117
7118 (define_insn_and_split "*addv<dwi>4_doubleword"
7119 [(set (reg:CCO FLAGS_REG)
7120 (eq:CCO
7121 (plus:<QPWI>
7122 (sign_extend:<QPWI>
7123 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7124 (sign_extend:<QPWI>
7125 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7126 (sign_extend:<QPWI>
7127 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7128 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7129 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7130 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7131 "#"
7132 "&& reload_completed"
7133 [(parallel [(set (reg:CCC FLAGS_REG)
7134 (compare:CCC
7135 (plus:DWIH (match_dup 1) (match_dup 2))
7136 (match_dup 1)))
7137 (set (match_dup 0)
7138 (plus:DWIH (match_dup 1) (match_dup 2)))])
7139 (parallel [(set (reg:CCO FLAGS_REG)
7140 (eq:CCO
7141 (plus:<DWI>
7142 (plus:<DWI>
7143 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7144 (sign_extend:<DWI> (match_dup 4)))
7145 (sign_extend:<DWI> (match_dup 5)))
7146 (sign_extend:<DWI>
7147 (plus:DWIH
7148 (plus:DWIH
7149 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7150 (match_dup 4))
7151 (match_dup 5)))))
7152 (set (match_dup 3)
7153 (plus:DWIH
7154 (plus:DWIH
7155 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7156 (match_dup 4))
7157 (match_dup 5)))])]
7158 {
7159 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7160 })
7161
7162 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7163 [(set (reg:CCO FLAGS_REG)
7164 (eq:CCO
7165 (plus:<QPWI>
7166 (sign_extend:<QPWI>
7167 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7168 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7169 (sign_extend:<QPWI>
7170 (plus:<DWI>
7171 (match_dup 1)
7172 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7173 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7174 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7175 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7176 && CONST_SCALAR_INT_P (operands[2])
7177 && rtx_equal_p (operands[2], operands[3])"
7178 "#"
7179 "&& reload_completed"
7180 [(parallel [(set (reg:CCC FLAGS_REG)
7181 (compare:CCC
7182 (plus:DWIH (match_dup 1) (match_dup 2))
7183 (match_dup 1)))
7184 (set (match_dup 0)
7185 (plus:DWIH (match_dup 1) (match_dup 2)))])
7186 (parallel [(set (reg:CCO FLAGS_REG)
7187 (eq:CCO
7188 (plus:<DWI>
7189 (plus:<DWI>
7190 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7191 (sign_extend:<DWI> (match_dup 4)))
7192 (match_dup 5))
7193 (sign_extend:<DWI>
7194 (plus:DWIH
7195 (plus:DWIH
7196 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7197 (match_dup 4))
7198 (match_dup 5)))))
7199 (set (match_dup 3)
7200 (plus:DWIH
7201 (plus:DWIH
7202 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7203 (match_dup 4))
7204 (match_dup 5)))])]
7205 {
7206 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7207 if (operands[2] == const0_rtx)
7208 {
7209 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7210 operands[5]));
7211 DONE;
7212 }
7213 })
7214
7215 (define_insn "*addv<mode>4_overflow_1"
7216 [(set (reg:CCO FLAGS_REG)
7217 (eq:CCO
7218 (plus:<DWI>
7219 (plus:<DWI>
7220 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7221 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7222 (sign_extend:<DWI>
7223 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7224 (sign_extend:<DWI>
7225 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7226 (sign_extend:<DWI>
7227 (plus:SWI
7228 (plus:SWI
7229 (match_operator:SWI 5 "ix86_carry_flag_operator"
7230 [(match_dup 3) (const_int 0)])
7231 (match_dup 1))
7232 (match_dup 2)))))
7233 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7234 (plus:SWI
7235 (plus:SWI
7236 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7237 (match_dup 1))
7238 (match_dup 2)))]
7239 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7240 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7241 [(set_attr "type" "alu")
7242 (set_attr "mode" "<MODE>")])
7243
7244 (define_insn "*addv<mode>4_overflow_2"
7245 [(set (reg:CCO FLAGS_REG)
7246 (eq:CCO
7247 (plus:<DWI>
7248 (plus:<DWI>
7249 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7250 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7251 (sign_extend:<DWI>
7252 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7253 (match_operand:<DWI> 6 "const_int_operand" "n"))
7254 (sign_extend:<DWI>
7255 (plus:SWI
7256 (plus:SWI
7257 (match_operator:SWI 5 "ix86_carry_flag_operator"
7258 [(match_dup 3) (const_int 0)])
7259 (match_dup 1))
7260 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7261 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7262 (plus:SWI
7263 (plus:SWI
7264 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7265 (match_dup 1))
7266 (match_dup 2)))]
7267 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7268 && CONST_INT_P (operands[2])
7269 && INTVAL (operands[2]) == INTVAL (operands[6])"
7270 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7271 [(set_attr "type" "alu")
7272 (set_attr "mode" "<MODE>")
7273 (set (attr "length_immediate")
7274 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7275 (const_string "1")
7276 (const_string "4")))])
7277
7278 (define_expand "uaddv<mode>4"
7279 [(parallel [(set (reg:CCC FLAGS_REG)
7280 (compare:CCC
7281 (plus:SWIDWI
7282 (match_operand:SWIDWI 1 "nonimmediate_operand")
7283 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7284 (match_dup 1)))
7285 (set (match_operand:SWIDWI 0 "register_operand")
7286 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7287 (set (pc) (if_then_else
7288 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7289 (label_ref (match_operand 3))
7290 (pc)))]
7291 ""
7292 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7293
7294 ;; The lea patterns for modes less than 32 bits need to be matched by
7295 ;; several insns converted to real lea by splitters.
7296
7297 (define_insn_and_split "*lea<mode>_general_1"
7298 [(set (match_operand:SWI12 0 "register_operand" "=r")
7299 (plus:SWI12
7300 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7301 (match_operand:SWI12 2 "register_operand" "r"))
7302 (match_operand:SWI12 3 "immediate_operand" "i")))]
7303 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7304 "#"
7305 "&& reload_completed"
7306 [(set (match_dup 0)
7307 (plus:SI
7308 (plus:SI (match_dup 1) (match_dup 2))
7309 (match_dup 3)))]
7310 {
7311 operands[0] = gen_lowpart (SImode, operands[0]);
7312 operands[1] = gen_lowpart (SImode, operands[1]);
7313 operands[2] = gen_lowpart (SImode, operands[2]);
7314 operands[3] = gen_lowpart (SImode, operands[3]);
7315 }
7316 [(set_attr "type" "lea")
7317 (set_attr "mode" "SI")])
7318
7319 (define_insn_and_split "*lea<mode>_general_2"
7320 [(set (match_operand:SWI12 0 "register_operand" "=r")
7321 (plus:SWI12
7322 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7323 (match_operand 2 "const248_operand" "n"))
7324 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7325 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7326 "#"
7327 "&& reload_completed"
7328 [(set (match_dup 0)
7329 (plus:SI
7330 (mult:SI (match_dup 1) (match_dup 2))
7331 (match_dup 3)))]
7332 {
7333 operands[0] = gen_lowpart (SImode, operands[0]);
7334 operands[1] = gen_lowpart (SImode, operands[1]);
7335 operands[3] = gen_lowpart (SImode, operands[3]);
7336 }
7337 [(set_attr "type" "lea")
7338 (set_attr "mode" "SI")])
7339
7340 (define_insn_and_split "*lea<mode>_general_2b"
7341 [(set (match_operand:SWI12 0 "register_operand" "=r")
7342 (plus:SWI12
7343 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7344 (match_operand 2 "const123_operand" "n"))
7345 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7346 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7347 "#"
7348 "&& reload_completed"
7349 [(set (match_dup 0)
7350 (plus:SI
7351 (ashift:SI (match_dup 1) (match_dup 2))
7352 (match_dup 3)))]
7353 {
7354 operands[0] = gen_lowpart (SImode, operands[0]);
7355 operands[1] = gen_lowpart (SImode, operands[1]);
7356 operands[3] = gen_lowpart (SImode, operands[3]);
7357 }
7358 [(set_attr "type" "lea")
7359 (set_attr "mode" "SI")])
7360
7361 (define_insn_and_split "*lea<mode>_general_3"
7362 [(set (match_operand:SWI12 0 "register_operand" "=r")
7363 (plus:SWI12
7364 (plus:SWI12
7365 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7366 (match_operand 2 "const248_operand" "n"))
7367 (match_operand:SWI12 3 "register_operand" "r"))
7368 (match_operand:SWI12 4 "immediate_operand" "i")))]
7369 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7370 "#"
7371 "&& reload_completed"
7372 [(set (match_dup 0)
7373 (plus:SI
7374 (plus:SI
7375 (mult:SI (match_dup 1) (match_dup 2))
7376 (match_dup 3))
7377 (match_dup 4)))]
7378 {
7379 operands[0] = gen_lowpart (SImode, operands[0]);
7380 operands[1] = gen_lowpart (SImode, operands[1]);
7381 operands[3] = gen_lowpart (SImode, operands[3]);
7382 operands[4] = gen_lowpart (SImode, operands[4]);
7383 }
7384 [(set_attr "type" "lea")
7385 (set_attr "mode" "SI")])
7386
7387 (define_insn_and_split "*lea<mode>_general_3b"
7388 [(set (match_operand:SWI12 0 "register_operand" "=r")
7389 (plus:SWI12
7390 (plus:SWI12
7391 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7392 (match_operand 2 "const123_operand" "n"))
7393 (match_operand:SWI12 3 "register_operand" "r"))
7394 (match_operand:SWI12 4 "immediate_operand" "i")))]
7395 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7396 "#"
7397 "&& reload_completed"
7398 [(set (match_dup 0)
7399 (plus:SI
7400 (plus:SI
7401 (ashift:SI (match_dup 1) (match_dup 2))
7402 (match_dup 3))
7403 (match_dup 4)))]
7404 {
7405 operands[0] = gen_lowpart (SImode, operands[0]);
7406 operands[1] = gen_lowpart (SImode, operands[1]);
7407 operands[3] = gen_lowpart (SImode, operands[3]);
7408 operands[4] = gen_lowpart (SImode, operands[4]);
7409 }
7410 [(set_attr "type" "lea")
7411 (set_attr "mode" "SI")])
7412
7413 (define_insn_and_split "*lea<mode>_general_4"
7414 [(set (match_operand:SWI12 0 "register_operand" "=r")
7415 (any_or:SWI12
7416 (ashift:SWI12
7417 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7418 (match_operand 2 "const_0_to_3_operand"))
7419 (match_operand 3 "const_int_operand")))]
7420 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7421 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7422 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7423 "#"
7424 "&& reload_completed"
7425 [(set (match_dup 0)
7426 (plus:SI
7427 (mult:SI (match_dup 1) (match_dup 2))
7428 (match_dup 3)))]
7429 {
7430 operands[0] = gen_lowpart (SImode, operands[0]);
7431 operands[1] = gen_lowpart (SImode, operands[1]);
7432 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7433 }
7434 [(set_attr "type" "lea")
7435 (set_attr "mode" "SI")])
7436
7437 (define_insn_and_split "*lea<mode>_general_4"
7438 [(set (match_operand:SWI48 0 "register_operand" "=r")
7439 (any_or:SWI48
7440 (ashift:SWI48
7441 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7442 (match_operand 2 "const_0_to_3_operand"))
7443 (match_operand 3 "const_int_operand")))]
7444 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7445 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7446 "#"
7447 "&& reload_completed"
7448 [(set (match_dup 0)
7449 (plus:SWI48
7450 (mult:SWI48 (match_dup 1) (match_dup 2))
7451 (match_dup 3)))]
7452 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7453 [(set_attr "type" "lea")
7454 (set_attr "mode" "<MODE>")])
7455 \f
7456 ;; Subtract instructions
7457
7458 (define_expand "sub<mode>3"
7459 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7460 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7461 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7462 ""
7463 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7464
7465 (define_insn_and_split "*sub<dwi>3_doubleword"
7466 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7467 (minus:<DWI>
7468 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7469 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7470 (clobber (reg:CC FLAGS_REG))]
7471 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7472 "#"
7473 "&& reload_completed"
7474 [(parallel [(set (reg:CC FLAGS_REG)
7475 (compare:CC (match_dup 1) (match_dup 2)))
7476 (set (match_dup 0)
7477 (minus:DWIH (match_dup 1) (match_dup 2)))])
7478 (parallel [(set (match_dup 3)
7479 (minus:DWIH
7480 (minus:DWIH
7481 (match_dup 4)
7482 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7483 (match_dup 5)))
7484 (clobber (reg:CC FLAGS_REG))])]
7485 {
7486 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7487 if (operands[2] == const0_rtx)
7488 {
7489 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7490 DONE;
7491 }
7492 })
7493
7494 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7495 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7496 (minus:<DWI>
7497 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7498 (zero_extend:<DWI>
7499 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7500 (clobber (reg:CC FLAGS_REG))]
7501 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7502 "#"
7503 "&& reload_completed"
7504 [(parallel [(set (reg:CC FLAGS_REG)
7505 (compare:CC (match_dup 1) (match_dup 2)))
7506 (set (match_dup 0)
7507 (minus:DWIH (match_dup 1) (match_dup 2)))])
7508 (parallel [(set (match_dup 3)
7509 (minus:DWIH
7510 (minus:DWIH
7511 (match_dup 4)
7512 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7513 (const_int 0)))
7514 (clobber (reg:CC FLAGS_REG))])]
7515 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7516
7517 (define_insn "*sub<mode>_1"
7518 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7519 (minus:SWI
7520 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7521 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7522 (clobber (reg:CC FLAGS_REG))]
7523 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7524 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7525 [(set_attr "type" "alu")
7526 (set_attr "mode" "<MODE>")])
7527
7528 (define_insn "*subsi_1_zext"
7529 [(set (match_operand:DI 0 "register_operand" "=r")
7530 (zero_extend:DI
7531 (minus:SI (match_operand:SI 1 "register_operand" "0")
7532 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7533 (clobber (reg:CC FLAGS_REG))]
7534 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7535 "sub{l}\t{%2, %k0|%k0, %2}"
7536 [(set_attr "type" "alu")
7537 (set_attr "mode" "SI")])
7538
7539 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7540 (define_insn_and_split "*sub<mode>_1_slp"
7541 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7542 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7543 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7544 (clobber (reg:CC FLAGS_REG))]
7545 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7546 "@
7547 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7548 #"
7549 "&& reload_completed"
7550 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7551 (parallel
7552 [(set (strict_low_part (match_dup 0))
7553 (minus:SWI12 (match_dup 0) (match_dup 2)))
7554 (clobber (reg:CC FLAGS_REG))])]
7555 ""
7556 [(set_attr "type" "alu")
7557 (set_attr "mode" "<MODE>")])
7558
7559 (define_insn "*sub<mode>_2"
7560 [(set (reg FLAGS_REG)
7561 (compare
7562 (minus:SWI
7563 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7564 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7565 (const_int 0)))
7566 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7567 (minus:SWI (match_dup 1) (match_dup 2)))]
7568 "ix86_match_ccmode (insn, CCGOCmode)
7569 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7570 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7571 [(set_attr "type" "alu")
7572 (set_attr "mode" "<MODE>")])
7573
7574 (define_insn "*subsi_2_zext"
7575 [(set (reg FLAGS_REG)
7576 (compare
7577 (minus:SI (match_operand:SI 1 "register_operand" "0")
7578 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7579 (const_int 0)))
7580 (set (match_operand:DI 0 "register_operand" "=r")
7581 (zero_extend:DI
7582 (minus:SI (match_dup 1)
7583 (match_dup 2))))]
7584 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7585 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7586 "sub{l}\t{%2, %k0|%k0, %2}"
7587 [(set_attr "type" "alu")
7588 (set_attr "mode" "SI")])
7589
7590 (define_insn "*subqi_ext<mode>_0"
7591 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
7592 (minus:QI
7593 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")
7594 (subreg:QI
7595 (match_operator:SWI248 3 "extract_operator"
7596 [(match_operand 2 "int248_register_operand" "Q,Q")
7597 (const_int 8)
7598 (const_int 8)]) 0)))
7599 (clobber (reg:CC FLAGS_REG))]
7600 ""
7601 "sub{b}\t{%h2, %0|%0, %h2}"
7602 [(set_attr "isa" "*,nox64")
7603 (set_attr "type" "alu")
7604 (set_attr "mode" "QI")])
7605
7606 (define_insn "*subqi_ext<mode>_2"
7607 [(set (zero_extract:SWI248
7608 (match_operand 0 "int248_register_operand" "+Q")
7609 (const_int 8)
7610 (const_int 8))
7611 (subreg:SWI248
7612 (minus:QI
7613 (subreg:QI
7614 (match_operator:SWI248 3 "extract_operator"
7615 [(match_operand 1 "int248_register_operand" "0")
7616 (const_int 8)
7617 (const_int 8)]) 0)
7618 (subreg:QI
7619 (match_operator:SWI248 4 "extract_operator"
7620 [(match_operand 2 "int248_register_operand" "Q")
7621 (const_int 8)
7622 (const_int 8)]) 0)) 0))
7623 (clobber (reg:CC FLAGS_REG))]
7624 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7625 rtx_equal_p (operands[0], operands[1])"
7626 "sub{b}\t{%h2, %h0|%h0, %h2}"
7627 [(set_attr "type" "alu")
7628 (set_attr "mode" "QI")])
7629
7630 ;; Subtract with jump on overflow.
7631 (define_expand "subv<mode>4"
7632 [(parallel [(set (reg:CCO FLAGS_REG)
7633 (eq:CCO
7634 (minus:<DPWI>
7635 (sign_extend:<DPWI>
7636 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7637 (match_dup 4))
7638 (sign_extend:<DPWI>
7639 (minus:SWIDWI (match_dup 1)
7640 (match_operand:SWIDWI 2
7641 "<general_hilo_operand>")))))
7642 (set (match_operand:SWIDWI 0 "register_operand")
7643 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7644 (set (pc) (if_then_else
7645 (eq (reg:CCO FLAGS_REG) (const_int 0))
7646 (label_ref (match_operand 3))
7647 (pc)))]
7648 ""
7649 {
7650 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7651 if (CONST_SCALAR_INT_P (operands[2]))
7652 operands[4] = operands[2];
7653 else
7654 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7655 })
7656
7657 (define_insn "*subv<mode>4"
7658 [(set (reg:CCO FLAGS_REG)
7659 (eq:CCO (minus:<DWI>
7660 (sign_extend:<DWI>
7661 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7662 (sign_extend:<DWI>
7663 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7664 (sign_extend:<DWI>
7665 (minus:SWI (match_dup 1) (match_dup 2)))))
7666 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7667 (minus:SWI (match_dup 1) (match_dup 2)))]
7668 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7669 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7670 [(set_attr "type" "alu")
7671 (set_attr "mode" "<MODE>")])
7672
7673 (define_insn "subv<mode>4_1"
7674 [(set (reg:CCO FLAGS_REG)
7675 (eq:CCO (minus:<DWI>
7676 (sign_extend:<DWI>
7677 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7678 (match_operand:<DWI> 3 "const_int_operand"))
7679 (sign_extend:<DWI>
7680 (minus:SWI
7681 (match_dup 1)
7682 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7683 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7684 (minus:SWI (match_dup 1) (match_dup 2)))]
7685 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7686 && CONST_INT_P (operands[2])
7687 && INTVAL (operands[2]) == INTVAL (operands[3])"
7688 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7689 [(set_attr "type" "alu")
7690 (set_attr "mode" "<MODE>")
7691 (set (attr "length_immediate")
7692 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7693 (const_string "1")
7694 (match_test "<MODE_SIZE> == 8")
7695 (const_string "4")]
7696 (const_string "<MODE_SIZE>")))])
7697
7698 (define_insn_and_split "*subv<dwi>4_doubleword"
7699 [(set (reg:CCO FLAGS_REG)
7700 (eq:CCO
7701 (minus:<QPWI>
7702 (sign_extend:<QPWI>
7703 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7704 (sign_extend:<QPWI>
7705 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7706 (sign_extend:<QPWI>
7707 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7708 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7709 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7710 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7711 "#"
7712 "&& reload_completed"
7713 [(parallel [(set (reg:CC FLAGS_REG)
7714 (compare:CC (match_dup 1) (match_dup 2)))
7715 (set (match_dup 0)
7716 (minus:DWIH (match_dup 1) (match_dup 2)))])
7717 (parallel [(set (reg:CCO FLAGS_REG)
7718 (eq:CCO
7719 (minus:<DWI>
7720 (minus:<DWI>
7721 (sign_extend:<DWI> (match_dup 4))
7722 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7723 (sign_extend:<DWI> (match_dup 5)))
7724 (sign_extend:<DWI>
7725 (minus:DWIH
7726 (minus:DWIH
7727 (match_dup 4)
7728 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7729 (match_dup 5)))))
7730 (set (match_dup 3)
7731 (minus:DWIH
7732 (minus:DWIH
7733 (match_dup 4)
7734 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7735 (match_dup 5)))])]
7736 {
7737 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7738 })
7739
7740 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7741 [(set (reg:CCO FLAGS_REG)
7742 (eq:CCO
7743 (minus:<QPWI>
7744 (sign_extend:<QPWI>
7745 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7746 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7747 (sign_extend:<QPWI>
7748 (minus:<DWI>
7749 (match_dup 1)
7750 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7751 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7752 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7753 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7754 && CONST_SCALAR_INT_P (operands[2])
7755 && rtx_equal_p (operands[2], operands[3])"
7756 "#"
7757 "&& reload_completed"
7758 [(parallel [(set (reg:CC FLAGS_REG)
7759 (compare:CC (match_dup 1) (match_dup 2)))
7760 (set (match_dup 0)
7761 (minus:DWIH (match_dup 1) (match_dup 2)))])
7762 (parallel [(set (reg:CCO FLAGS_REG)
7763 (eq:CCO
7764 (minus:<DWI>
7765 (minus:<DWI>
7766 (sign_extend:<DWI> (match_dup 4))
7767 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7768 (match_dup 5))
7769 (sign_extend:<DWI>
7770 (minus:DWIH
7771 (minus:DWIH
7772 (match_dup 4)
7773 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7774 (match_dup 5)))))
7775 (set (match_dup 3)
7776 (minus:DWIH
7777 (minus:DWIH
7778 (match_dup 4)
7779 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7780 (match_dup 5)))])]
7781 {
7782 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7783 if (operands[2] == const0_rtx)
7784 {
7785 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7786 operands[5]));
7787 DONE;
7788 }
7789 })
7790
7791 (define_insn "*subv<mode>4_overflow_1"
7792 [(set (reg:CCO FLAGS_REG)
7793 (eq:CCO
7794 (minus:<DWI>
7795 (minus:<DWI>
7796 (sign_extend:<DWI>
7797 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7798 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7799 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7800 (sign_extend:<DWI>
7801 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7802 (sign_extend:<DWI>
7803 (minus:SWI
7804 (minus:SWI
7805 (match_dup 1)
7806 (match_operator:SWI 5 "ix86_carry_flag_operator"
7807 [(match_dup 3) (const_int 0)]))
7808 (match_dup 2)))))
7809 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7810 (minus:SWI
7811 (minus:SWI
7812 (match_dup 1)
7813 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7814 (match_dup 2)))]
7815 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7816 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7817 [(set_attr "type" "alu")
7818 (set_attr "mode" "<MODE>")])
7819
7820 (define_insn "*subv<mode>4_overflow_2"
7821 [(set (reg:CCO FLAGS_REG)
7822 (eq:CCO
7823 (minus:<DWI>
7824 (minus:<DWI>
7825 (sign_extend:<DWI>
7826 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7827 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7828 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7829 (match_operand:<DWI> 6 "const_int_operand" "n"))
7830 (sign_extend:<DWI>
7831 (minus:SWI
7832 (minus:SWI
7833 (match_dup 1)
7834 (match_operator:SWI 5 "ix86_carry_flag_operator"
7835 [(match_dup 3) (const_int 0)]))
7836 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7837 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7838 (minus:SWI
7839 (minus:SWI
7840 (match_dup 1)
7841 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7842 (match_dup 2)))]
7843 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7844 && CONST_INT_P (operands[2])
7845 && INTVAL (operands[2]) == INTVAL (operands[6])"
7846 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7847 [(set_attr "type" "alu")
7848 (set_attr "mode" "<MODE>")
7849 (set (attr "length_immediate")
7850 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7851 (const_string "1")
7852 (const_string "4")))])
7853
7854 (define_expand "usubv<mode>4"
7855 [(parallel [(set (reg:CC FLAGS_REG)
7856 (compare:CC
7857 (match_operand:SWI 1 "nonimmediate_operand")
7858 (match_operand:SWI 2 "<general_operand>")))
7859 (set (match_operand:SWI 0 "register_operand")
7860 (minus:SWI (match_dup 1) (match_dup 2)))])
7861 (set (pc) (if_then_else
7862 (ltu (reg:CC FLAGS_REG) (const_int 0))
7863 (label_ref (match_operand 3))
7864 (pc)))]
7865 ""
7866 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
7867
7868 (define_insn "*sub<mode>_3"
7869 [(set (reg FLAGS_REG)
7870 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7871 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7872 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7873 (minus:SWI (match_dup 1) (match_dup 2)))]
7874 "ix86_match_ccmode (insn, CCmode)
7875 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7876 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7877 [(set_attr "type" "alu")
7878 (set_attr "mode" "<MODE>")])
7879
7880 (define_peephole2
7881 [(parallel
7882 [(set (reg:CC FLAGS_REG)
7883 (compare:CC (match_operand:SWI 0 "general_reg_operand")
7884 (match_operand:SWI 1 "general_gr_operand")))
7885 (set (match_dup 0)
7886 (minus:SWI (match_dup 0) (match_dup 1)))])]
7887 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
7888 [(set (reg:CC FLAGS_REG)
7889 (compare:CC (match_dup 0) (match_dup 1)))])
7890
7891 (define_peephole2
7892 [(set (match_operand:SWI 0 "general_reg_operand")
7893 (match_operand:SWI 1 "memory_operand"))
7894 (parallel [(set (reg:CC FLAGS_REG)
7895 (compare:CC (match_dup 0)
7896 (match_operand:SWI 2 "memory_operand")))
7897 (set (match_dup 0)
7898 (minus:SWI (match_dup 0) (match_dup 2)))])
7899 (set (match_dup 1) (match_dup 0))]
7900 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7901 && peep2_reg_dead_p (3, operands[0])
7902 && !reg_overlap_mentioned_p (operands[0], operands[1])
7903 && !reg_overlap_mentioned_p (operands[0], operands[2])"
7904 [(set (match_dup 0) (match_dup 2))
7905 (parallel [(set (reg:CC FLAGS_REG)
7906 (compare:CC (match_dup 1) (match_dup 0)))
7907 (set (match_dup 1)
7908 (minus:SWI (match_dup 1) (match_dup 0)))])])
7909
7910 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
7911 ;; subl $1, %eax; jnc .Lxx;
7912 (define_peephole2
7913 [(parallel
7914 [(set (match_operand:SWI 0 "general_reg_operand")
7915 (plus:SWI (match_dup 0) (const_int -1)))
7916 (clobber (reg FLAGS_REG))])
7917 (set (reg:CCZ FLAGS_REG)
7918 (compare:CCZ (match_dup 0) (const_int -1)))
7919 (set (pc)
7920 (if_then_else (match_operator 1 "bt_comparison_operator"
7921 [(reg:CCZ FLAGS_REG) (const_int 0)])
7922 (match_operand 2)
7923 (pc)))]
7924 "peep2_regno_dead_p (3, FLAGS_REG)"
7925 [(parallel
7926 [(set (reg:CC FLAGS_REG)
7927 (compare:CC (match_dup 0) (const_int 1)))
7928 (set (match_dup 0)
7929 (minus:SWI (match_dup 0) (const_int 1)))])
7930 (set (pc)
7931 (if_then_else (match_dup 3)
7932 (match_dup 2)
7933 (pc)))]
7934 {
7935 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
7936 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7937 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7938 })
7939
7940 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
7941 (define_insn_and_split "*dec_cmov<mode>"
7942 [(set (match_operand:SWI248 0 "register_operand" "=r")
7943 (if_then_else:SWI248
7944 (match_operator 1 "bt_comparison_operator"
7945 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
7946 (plus:SWI248 (match_dup 2) (const_int -1))
7947 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
7948 (clobber (reg:CC FLAGS_REG))]
7949 "TARGET_CMOVE"
7950 "#"
7951 "&& reload_completed"
7952 [(parallel [(set (reg:CC FLAGS_REG)
7953 (compare:CC (match_dup 2) (const_int 1)))
7954 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
7955 (set (match_dup 0)
7956 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
7957 {
7958 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
7959 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7960 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7961 })
7962
7963 (define_insn "*subsi_3_zext"
7964 [(set (reg FLAGS_REG)
7965 (compare (match_operand:SI 1 "register_operand" "0")
7966 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
7967 (set (match_operand:DI 0 "register_operand" "=r")
7968 (zero_extend:DI
7969 (minus:SI (match_dup 1)
7970 (match_dup 2))))]
7971 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7972 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7973 "sub{l}\t{%2, %1|%1, %2}"
7974 [(set_attr "type" "alu")
7975 (set_attr "mode" "SI")])
7976 \f
7977 ;; Add with carry and subtract with borrow
7978
7979 (define_insn "@add<mode>3_carry"
7980 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7981 (plus:SWI
7982 (plus:SWI
7983 (match_operator:SWI 4 "ix86_carry_flag_operator"
7984 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7985 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7986 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7987 (clobber (reg:CC FLAGS_REG))]
7988 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7989 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7990 [(set_attr "type" "alu")
7991 (set_attr "use_carry" "1")
7992 (set_attr "pent_pair" "pu")
7993 (set_attr "mode" "<MODE>")])
7994
7995 (define_peephole2
7996 [(set (match_operand:SWI 0 "general_reg_operand")
7997 (match_operand:SWI 1 "memory_operand"))
7998 (parallel [(set (match_dup 0)
7999 (plus:SWI
8000 (plus:SWI
8001 (match_operator:SWI 4 "ix86_carry_flag_operator"
8002 [(match_operand 3 "flags_reg_operand")
8003 (const_int 0)])
8004 (match_dup 0))
8005 (match_operand:SWI 2 "memory_operand")))
8006 (clobber (reg:CC FLAGS_REG))])
8007 (set (match_dup 1) (match_dup 0))]
8008 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8009 && peep2_reg_dead_p (3, operands[0])
8010 && !reg_overlap_mentioned_p (operands[0], operands[1])
8011 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8012 [(set (match_dup 0) (match_dup 2))
8013 (parallel [(set (match_dup 1)
8014 (plus:SWI (plus:SWI (match_op_dup 4
8015 [(match_dup 3) (const_int 0)])
8016 (match_dup 1))
8017 (match_dup 0)))
8018 (clobber (reg:CC FLAGS_REG))])])
8019
8020 (define_peephole2
8021 [(set (match_operand:SWI 0 "general_reg_operand")
8022 (match_operand:SWI 1 "memory_operand"))
8023 (parallel [(set (match_dup 0)
8024 (plus:SWI
8025 (plus:SWI
8026 (match_operator:SWI 4 "ix86_carry_flag_operator"
8027 [(match_operand 3 "flags_reg_operand")
8028 (const_int 0)])
8029 (match_dup 0))
8030 (match_operand:SWI 2 "memory_operand")))
8031 (clobber (reg:CC FLAGS_REG))])
8032 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8033 (set (match_dup 1) (match_dup 5))]
8034 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8035 && peep2_reg_dead_p (3, operands[0])
8036 && peep2_reg_dead_p (4, operands[5])
8037 && !reg_overlap_mentioned_p (operands[0], operands[1])
8038 && !reg_overlap_mentioned_p (operands[0], operands[2])
8039 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8040 [(set (match_dup 0) (match_dup 2))
8041 (parallel [(set (match_dup 1)
8042 (plus:SWI (plus:SWI (match_op_dup 4
8043 [(match_dup 3) (const_int 0)])
8044 (match_dup 1))
8045 (match_dup 0)))
8046 (clobber (reg:CC FLAGS_REG))])])
8047
8048 (define_insn "*add<mode>3_carry_0"
8049 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8050 (plus:SWI
8051 (match_operator:SWI 2 "ix86_carry_flag_operator"
8052 [(reg FLAGS_REG) (const_int 0)])
8053 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8054 (clobber (reg:CC FLAGS_REG))]
8055 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8056 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8057 [(set_attr "type" "alu")
8058 (set_attr "use_carry" "1")
8059 (set_attr "pent_pair" "pu")
8060 (set_attr "mode" "<MODE>")])
8061
8062 (define_insn "*add<mode>3_carry_0r"
8063 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8064 (plus:SWI
8065 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8066 [(reg FLAGS_REG) (const_int 0)])
8067 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8068 (clobber (reg:CC FLAGS_REG))]
8069 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8070 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8071 [(set_attr "type" "alu")
8072 (set_attr "use_carry" "1")
8073 (set_attr "pent_pair" "pu")
8074 (set_attr "mode" "<MODE>")])
8075
8076 (define_insn "*addsi3_carry_zext"
8077 [(set (match_operand:DI 0 "register_operand" "=r")
8078 (zero_extend:DI
8079 (plus:SI
8080 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8081 [(reg FLAGS_REG) (const_int 0)])
8082 (match_operand:SI 1 "register_operand" "%0"))
8083 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8084 (clobber (reg:CC FLAGS_REG))]
8085 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8086 "adc{l}\t{%2, %k0|%k0, %2}"
8087 [(set_attr "type" "alu")
8088 (set_attr "use_carry" "1")
8089 (set_attr "pent_pair" "pu")
8090 (set_attr "mode" "SI")])
8091
8092 (define_insn "*addsi3_carry_zext_0"
8093 [(set (match_operand:DI 0 "register_operand" "=r")
8094 (zero_extend:DI
8095 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8096 [(reg FLAGS_REG) (const_int 0)])
8097 (match_operand:SI 1 "register_operand" "0"))))
8098 (clobber (reg:CC FLAGS_REG))]
8099 "TARGET_64BIT"
8100 "adc{l}\t{$0, %k0|%k0, 0}"
8101 [(set_attr "type" "alu")
8102 (set_attr "use_carry" "1")
8103 (set_attr "pent_pair" "pu")
8104 (set_attr "mode" "SI")])
8105
8106 (define_insn "*addsi3_carry_zext_0r"
8107 [(set (match_operand:DI 0 "register_operand" "=r")
8108 (zero_extend:DI
8109 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8110 [(reg FLAGS_REG) (const_int 0)])
8111 (match_operand:SI 1 "register_operand" "0"))))
8112 (clobber (reg:CC FLAGS_REG))]
8113 "TARGET_64BIT"
8114 "sbb{l}\t{$-1, %k0|%k0, -1}"
8115 [(set_attr "type" "alu")
8116 (set_attr "use_carry" "1")
8117 (set_attr "pent_pair" "pu")
8118 (set_attr "mode" "SI")])
8119
8120 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8121
8122 (define_insn "addcarry<mode>"
8123 [(set (reg:CCC FLAGS_REG)
8124 (compare:CCC
8125 (zero_extend:<DWI>
8126 (plus:SWI48
8127 (plus:SWI48
8128 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8129 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8130 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8131 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8132 (plus:<DWI>
8133 (zero_extend:<DWI> (match_dup 2))
8134 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8135 [(match_dup 3) (const_int 0)]))))
8136 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8137 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8138 [(match_dup 3) (const_int 0)])
8139 (match_dup 1))
8140 (match_dup 2)))]
8141 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8142 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8143 [(set_attr "type" "alu")
8144 (set_attr "use_carry" "1")
8145 (set_attr "pent_pair" "pu")
8146 (set_attr "mode" "<MODE>")])
8147
8148 (define_peephole2
8149 [(parallel [(set (reg:CCC FLAGS_REG)
8150 (compare:CCC
8151 (zero_extend:<DWI>
8152 (plus:SWI48
8153 (plus:SWI48
8154 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8155 [(match_operand 2 "flags_reg_operand")
8156 (const_int 0)])
8157 (match_operand:SWI48 0 "general_reg_operand"))
8158 (match_operand:SWI48 1 "memory_operand")))
8159 (plus:<DWI>
8160 (zero_extend:<DWI> (match_dup 1))
8161 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8162 [(match_dup 2) (const_int 0)]))))
8163 (set (match_dup 0)
8164 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8165 [(match_dup 2) (const_int 0)])
8166 (match_dup 0))
8167 (match_dup 1)))])
8168 (set (match_dup 1) (match_dup 0))]
8169 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8170 && peep2_reg_dead_p (2, operands[0])
8171 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8172 [(parallel [(set (reg:CCC FLAGS_REG)
8173 (compare:CCC
8174 (zero_extend:<DWI>
8175 (plus:SWI48
8176 (plus:SWI48
8177 (match_op_dup 4
8178 [(match_dup 2) (const_int 0)])
8179 (match_dup 1))
8180 (match_dup 0)))
8181 (plus:<DWI>
8182 (zero_extend:<DWI> (match_dup 0))
8183 (match_op_dup 3
8184 [(match_dup 2) (const_int 0)]))))
8185 (set (match_dup 1)
8186 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8187 [(match_dup 2) (const_int 0)])
8188 (match_dup 1))
8189 (match_dup 0)))])])
8190
8191 (define_peephole2
8192 [(set (match_operand:SWI48 0 "general_reg_operand")
8193 (match_operand:SWI48 1 "memory_operand"))
8194 (parallel [(set (reg:CCC FLAGS_REG)
8195 (compare:CCC
8196 (zero_extend:<DWI>
8197 (plus:SWI48
8198 (plus:SWI48
8199 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8200 [(match_operand 3 "flags_reg_operand")
8201 (const_int 0)])
8202 (match_dup 0))
8203 (match_operand:SWI48 2 "memory_operand")))
8204 (plus:<DWI>
8205 (zero_extend:<DWI> (match_dup 2))
8206 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8207 [(match_dup 3) (const_int 0)]))))
8208 (set (match_dup 0)
8209 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8210 [(match_dup 3) (const_int 0)])
8211 (match_dup 0))
8212 (match_dup 2)))])
8213 (set (match_dup 1) (match_dup 0))]
8214 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8215 && peep2_reg_dead_p (3, operands[0])
8216 && !reg_overlap_mentioned_p (operands[0], operands[1])
8217 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8218 [(set (match_dup 0) (match_dup 2))
8219 (parallel [(set (reg:CCC FLAGS_REG)
8220 (compare:CCC
8221 (zero_extend:<DWI>
8222 (plus:SWI48
8223 (plus:SWI48
8224 (match_op_dup 5
8225 [(match_dup 3) (const_int 0)])
8226 (match_dup 1))
8227 (match_dup 0)))
8228 (plus:<DWI>
8229 (zero_extend:<DWI> (match_dup 0))
8230 (match_op_dup 4
8231 [(match_dup 3) (const_int 0)]))))
8232 (set (match_dup 1)
8233 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8234 [(match_dup 3) (const_int 0)])
8235 (match_dup 1))
8236 (match_dup 0)))])])
8237
8238 (define_peephole2
8239 [(parallel [(set (reg:CCC FLAGS_REG)
8240 (compare:CCC
8241 (zero_extend:<DWI>
8242 (plus:SWI48
8243 (plus:SWI48
8244 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8245 [(match_operand 2 "flags_reg_operand")
8246 (const_int 0)])
8247 (match_operand:SWI48 0 "general_reg_operand"))
8248 (match_operand:SWI48 1 "memory_operand")))
8249 (plus:<DWI>
8250 (zero_extend:<DWI> (match_dup 1))
8251 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8252 [(match_dup 2) (const_int 0)]))))
8253 (set (match_dup 0)
8254 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8255 [(match_dup 2) (const_int 0)])
8256 (match_dup 0))
8257 (match_dup 1)))])
8258 (set (match_operand:QI 5 "general_reg_operand")
8259 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8260 (set (match_operand:SWI48 6 "general_reg_operand")
8261 (zero_extend:SWI48 (match_dup 5)))
8262 (set (match_dup 1) (match_dup 0))]
8263 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8264 && peep2_reg_dead_p (4, operands[0])
8265 && !reg_overlap_mentioned_p (operands[0], operands[1])
8266 && !reg_overlap_mentioned_p (operands[0], operands[5])
8267 && !reg_overlap_mentioned_p (operands[5], operands[1])
8268 && !reg_overlap_mentioned_p (operands[0], operands[6])
8269 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8270 [(parallel [(set (reg:CCC FLAGS_REG)
8271 (compare:CCC
8272 (zero_extend:<DWI>
8273 (plus:SWI48
8274 (plus:SWI48
8275 (match_op_dup 4
8276 [(match_dup 2) (const_int 0)])
8277 (match_dup 1))
8278 (match_dup 0)))
8279 (plus:<DWI>
8280 (zero_extend:<DWI> (match_dup 0))
8281 (match_op_dup 3
8282 [(match_dup 2) (const_int 0)]))))
8283 (set (match_dup 1)
8284 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8285 [(match_dup 2) (const_int 0)])
8286 (match_dup 1))
8287 (match_dup 0)))])
8288 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8289 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8290
8291 (define_expand "addcarry<mode>_0"
8292 [(parallel
8293 [(set (reg:CCC FLAGS_REG)
8294 (compare:CCC
8295 (plus:SWI48
8296 (match_operand:SWI48 1 "nonimmediate_operand")
8297 (match_operand:SWI48 2 "x86_64_general_operand"))
8298 (match_dup 1)))
8299 (set (match_operand:SWI48 0 "nonimmediate_operand")
8300 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8301 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8302
8303 (define_insn "*addcarry<mode>_1"
8304 [(set (reg:CCC FLAGS_REG)
8305 (compare:CCC
8306 (zero_extend:<DWI>
8307 (plus:SWI48
8308 (plus:SWI48
8309 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8310 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8311 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8312 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8313 (plus:<DWI>
8314 (match_operand:<DWI> 6 "const_scalar_int_operand")
8315 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8316 [(match_dup 3) (const_int 0)]))))
8317 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8318 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8319 [(match_dup 3) (const_int 0)])
8320 (match_dup 1))
8321 (match_dup 2)))]
8322 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8323 && CONST_INT_P (operands[2])
8324 /* Check that operands[6] is operands[2] zero extended from
8325 <MODE>mode to <DWI>mode. */
8326 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8327 ? (CONST_INT_P (operands[6])
8328 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8329 & GET_MODE_MASK (<MODE>mode)))
8330 : (CONST_WIDE_INT_P (operands[6])
8331 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8332 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8333 == UINTVAL (operands[2]))
8334 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8335 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "use_carry" "1")
8338 (set_attr "pent_pair" "pu")
8339 (set_attr "mode" "<MODE>")
8340 (set (attr "length_immediate")
8341 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8342 (const_string "1")
8343 (const_string "4")))])
8344
8345 (define_insn "@sub<mode>3_carry"
8346 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8347 (minus:SWI
8348 (minus:SWI
8349 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8350 (match_operator:SWI 4 "ix86_carry_flag_operator"
8351 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8352 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8353 (clobber (reg:CC FLAGS_REG))]
8354 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8355 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8356 [(set_attr "type" "alu")
8357 (set_attr "use_carry" "1")
8358 (set_attr "pent_pair" "pu")
8359 (set_attr "mode" "<MODE>")])
8360
8361 (define_peephole2
8362 [(set (match_operand:SWI 0 "general_reg_operand")
8363 (match_operand:SWI 1 "memory_operand"))
8364 (parallel [(set (match_dup 0)
8365 (minus:SWI
8366 (minus:SWI
8367 (match_dup 0)
8368 (match_operator:SWI 4 "ix86_carry_flag_operator"
8369 [(match_operand 3 "flags_reg_operand")
8370 (const_int 0)]))
8371 (match_operand:SWI 2 "memory_operand")))
8372 (clobber (reg:CC FLAGS_REG))])
8373 (set (match_dup 1) (match_dup 0))]
8374 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8375 && peep2_reg_dead_p (3, operands[0])
8376 && !reg_overlap_mentioned_p (operands[0], operands[1])
8377 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8378 [(set (match_dup 0) (match_dup 2))
8379 (parallel [(set (match_dup 1)
8380 (minus:SWI (minus:SWI (match_dup 1)
8381 (match_op_dup 4
8382 [(match_dup 3) (const_int 0)]))
8383 (match_dup 0)))
8384 (clobber (reg:CC FLAGS_REG))])])
8385
8386 (define_peephole2
8387 [(set (match_operand:SWI 0 "general_reg_operand")
8388 (match_operand:SWI 1 "memory_operand"))
8389 (parallel [(set (match_dup 0)
8390 (minus:SWI
8391 (minus:SWI
8392 (match_dup 0)
8393 (match_operator:SWI 4 "ix86_carry_flag_operator"
8394 [(match_operand 3 "flags_reg_operand")
8395 (const_int 0)]))
8396 (match_operand:SWI 2 "memory_operand")))
8397 (clobber (reg:CC FLAGS_REG))])
8398 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8399 (set (match_dup 1) (match_dup 5))]
8400 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8401 && peep2_reg_dead_p (3, operands[0])
8402 && peep2_reg_dead_p (4, operands[5])
8403 && !reg_overlap_mentioned_p (operands[0], operands[1])
8404 && !reg_overlap_mentioned_p (operands[0], operands[2])
8405 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8406 [(set (match_dup 0) (match_dup 2))
8407 (parallel [(set (match_dup 1)
8408 (minus:SWI (minus:SWI (match_dup 1)
8409 (match_op_dup 4
8410 [(match_dup 3) (const_int 0)]))
8411 (match_dup 0)))
8412 (clobber (reg:CC FLAGS_REG))])])
8413
8414 (define_insn "*sub<mode>3_carry_0"
8415 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8416 (minus:SWI
8417 (match_operand:SWI 1 "nonimmediate_operand" "0")
8418 (match_operator:SWI 2 "ix86_carry_flag_operator"
8419 [(reg FLAGS_REG) (const_int 0)])))
8420 (clobber (reg:CC FLAGS_REG))]
8421 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8422 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8423 [(set_attr "type" "alu")
8424 (set_attr "use_carry" "1")
8425 (set_attr "pent_pair" "pu")
8426 (set_attr "mode" "<MODE>")])
8427
8428 (define_insn "*sub<mode>3_carry_0r"
8429 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8430 (minus:SWI
8431 (match_operand:SWI 1 "nonimmediate_operand" "0")
8432 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8433 [(reg FLAGS_REG) (const_int 0)])))
8434 (clobber (reg:CC FLAGS_REG))]
8435 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8436 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8437 [(set_attr "type" "alu")
8438 (set_attr "use_carry" "1")
8439 (set_attr "pent_pair" "pu")
8440 (set_attr "mode" "<MODE>")])
8441
8442 (define_insn "*subsi3_carry_zext"
8443 [(set (match_operand:DI 0 "register_operand" "=r")
8444 (zero_extend:DI
8445 (minus:SI
8446 (minus:SI
8447 (match_operand:SI 1 "register_operand" "0")
8448 (match_operator:SI 3 "ix86_carry_flag_operator"
8449 [(reg FLAGS_REG) (const_int 0)]))
8450 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8451 (clobber (reg:CC FLAGS_REG))]
8452 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8453 "sbb{l}\t{%2, %k0|%k0, %2}"
8454 [(set_attr "type" "alu")
8455 (set_attr "use_carry" "1")
8456 (set_attr "pent_pair" "pu")
8457 (set_attr "mode" "SI")])
8458
8459 (define_insn "*subsi3_carry_zext_0"
8460 [(set (match_operand:DI 0 "register_operand" "=r")
8461 (zero_extend:DI
8462 (minus:SI
8463 (match_operand:SI 1 "register_operand" "0")
8464 (match_operator:SI 2 "ix86_carry_flag_operator"
8465 [(reg FLAGS_REG) (const_int 0)]))))
8466 (clobber (reg:CC FLAGS_REG))]
8467 "TARGET_64BIT"
8468 "sbb{l}\t{$0, %k0|%k0, 0}"
8469 [(set_attr "type" "alu")
8470 (set_attr "use_carry" "1")
8471 (set_attr "pent_pair" "pu")
8472 (set_attr "mode" "SI")])
8473
8474 (define_insn "*subsi3_carry_zext_0r"
8475 [(set (match_operand:DI 0 "register_operand" "=r")
8476 (zero_extend:DI
8477 (minus:SI
8478 (match_operand:SI 1 "register_operand" "0")
8479 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8480 [(reg FLAGS_REG) (const_int 0)]))))
8481 (clobber (reg:CC FLAGS_REG))]
8482 "TARGET_64BIT"
8483 "adc{l}\t{$-1, %k0|%k0, -1}"
8484 [(set_attr "type" "alu")
8485 (set_attr "use_carry" "1")
8486 (set_attr "pent_pair" "pu")
8487 (set_attr "mode" "SI")])
8488
8489 (define_insn "@sub<mode>3_carry_ccc"
8490 [(set (reg:CCC FLAGS_REG)
8491 (compare:CCC
8492 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8493 (plus:<DWI>
8494 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8495 (zero_extend:<DWI>
8496 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8497 (clobber (match_scratch:DWIH 0 "=r"))]
8498 ""
8499 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8500 [(set_attr "type" "alu")
8501 (set_attr "mode" "<MODE>")])
8502
8503 (define_insn "*sub<mode>3_carry_ccc_1"
8504 [(set (reg:CCC FLAGS_REG)
8505 (compare:CCC
8506 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8507 (plus:<DWI>
8508 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8509 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8510 (clobber (match_scratch:DWIH 0 "=r"))]
8511 ""
8512 {
8513 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8514 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8515 }
8516 [(set_attr "type" "alu")
8517 (set_attr "mode" "<MODE>")])
8518
8519 ;; The sign flag is set from the
8520 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8521 ;; result, the overflow flag likewise, but the overflow flag is also
8522 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8523 (define_insn "@sub<mode>3_carry_ccgz"
8524 [(set (reg:CCGZ FLAGS_REG)
8525 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8526 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8527 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8528 UNSPEC_SBB))
8529 (clobber (match_scratch:DWIH 0 "=r"))]
8530 ""
8531 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8532 [(set_attr "type" "alu")
8533 (set_attr "mode" "<MODE>")])
8534
8535 (define_insn "subborrow<mode>"
8536 [(set (reg:CCC FLAGS_REG)
8537 (compare:CCC
8538 (zero_extend:<DWI>
8539 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8540 (plus:<DWI>
8541 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8542 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8543 (zero_extend:<DWI>
8544 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8545 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8546 (minus:SWI48 (minus:SWI48
8547 (match_dup 1)
8548 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8549 [(match_dup 3) (const_int 0)]))
8550 (match_dup 2)))]
8551 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8552 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8553 [(set_attr "type" "alu")
8554 (set_attr "use_carry" "1")
8555 (set_attr "pent_pair" "pu")
8556 (set_attr "mode" "<MODE>")])
8557
8558 (define_peephole2
8559 [(set (match_operand:SWI48 0 "general_reg_operand")
8560 (match_operand:SWI48 1 "memory_operand"))
8561 (parallel [(set (reg:CCC FLAGS_REG)
8562 (compare:CCC
8563 (zero_extend:<DWI> (match_dup 0))
8564 (plus:<DWI>
8565 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8566 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8567 (zero_extend:<DWI>
8568 (match_operand:SWI48 2 "memory_operand")))))
8569 (set (match_dup 0)
8570 (minus:SWI48
8571 (minus:SWI48
8572 (match_dup 0)
8573 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8574 [(match_dup 3) (const_int 0)]))
8575 (match_dup 2)))])
8576 (set (match_dup 1) (match_dup 0))]
8577 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8578 && peep2_reg_dead_p (3, operands[0])
8579 && !reg_overlap_mentioned_p (operands[0], operands[1])
8580 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8581 [(set (match_dup 0) (match_dup 2))
8582 (parallel [(set (reg:CCC FLAGS_REG)
8583 (compare:CCC
8584 (zero_extend:<DWI> (match_dup 1))
8585 (plus:<DWI> (match_op_dup 4
8586 [(match_dup 3) (const_int 0)])
8587 (zero_extend:<DWI> (match_dup 0)))))
8588 (set (match_dup 1)
8589 (minus:SWI48 (minus:SWI48 (match_dup 1)
8590 (match_op_dup 5
8591 [(match_dup 3) (const_int 0)]))
8592 (match_dup 0)))])])
8593
8594 (define_peephole2
8595 [(set (match_operand:SWI48 6 "general_reg_operand")
8596 (match_operand:SWI48 7 "memory_operand"))
8597 (set (match_operand:SWI48 8 "general_reg_operand")
8598 (match_operand:SWI48 9 "memory_operand"))
8599 (parallel [(set (reg:CCC FLAGS_REG)
8600 (compare:CCC
8601 (zero_extend:<DWI>
8602 (match_operand:SWI48 0 "general_reg_operand"))
8603 (plus:<DWI>
8604 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8605 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8606 (zero_extend:<DWI>
8607 (match_operand:SWI48 2 "general_reg_operand")))))
8608 (set (match_dup 0)
8609 (minus:SWI48
8610 (minus:SWI48
8611 (match_dup 0)
8612 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8613 [(match_dup 3) (const_int 0)]))
8614 (match_dup 2)))])
8615 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8616 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8617 && peep2_reg_dead_p (4, operands[0])
8618 && peep2_reg_dead_p (3, operands[2])
8619 && !reg_overlap_mentioned_p (operands[0], operands[1])
8620 && !reg_overlap_mentioned_p (operands[2], operands[1])
8621 && !reg_overlap_mentioned_p (operands[6], operands[9])
8622 && (rtx_equal_p (operands[6], operands[0])
8623 ? (rtx_equal_p (operands[7], operands[1])
8624 && rtx_equal_p (operands[8], operands[2]))
8625 : (rtx_equal_p (operands[8], operands[0])
8626 && rtx_equal_p (operands[9], operands[1])
8627 && rtx_equal_p (operands[6], operands[2])))"
8628 [(set (match_dup 0) (match_dup 9))
8629 (parallel [(set (reg:CCC FLAGS_REG)
8630 (compare:CCC
8631 (zero_extend:<DWI> (match_dup 1))
8632 (plus:<DWI> (match_op_dup 4
8633 [(match_dup 3) (const_int 0)])
8634 (zero_extend:<DWI> (match_dup 0)))))
8635 (set (match_dup 1)
8636 (minus:SWI48 (minus:SWI48 (match_dup 1)
8637 (match_op_dup 5
8638 [(match_dup 3) (const_int 0)]))
8639 (match_dup 0)))])]
8640 {
8641 if (!rtx_equal_p (operands[6], operands[0]))
8642 operands[9] = operands[7];
8643 })
8644
8645 (define_peephole2
8646 [(set (match_operand:SWI48 6 "general_reg_operand")
8647 (match_operand:SWI48 7 "memory_operand"))
8648 (set (match_operand:SWI48 8 "general_reg_operand")
8649 (match_operand:SWI48 9 "memory_operand"))
8650 (parallel [(set (reg:CCC FLAGS_REG)
8651 (compare:CCC
8652 (zero_extend:<DWI>
8653 (match_operand:SWI48 0 "general_reg_operand"))
8654 (plus:<DWI>
8655 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8656 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8657 (zero_extend:<DWI>
8658 (match_operand:SWI48 2 "general_reg_operand")))))
8659 (set (match_dup 0)
8660 (minus:SWI48
8661 (minus:SWI48
8662 (match_dup 0)
8663 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8664 [(match_dup 3) (const_int 0)]))
8665 (match_dup 2)))])
8666 (set (match_operand:QI 10 "general_reg_operand")
8667 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8668 (set (match_operand:SWI48 11 "general_reg_operand")
8669 (zero_extend:SWI48 (match_dup 10)))
8670 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8671 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8672 && peep2_reg_dead_p (6, operands[0])
8673 && peep2_reg_dead_p (3, operands[2])
8674 && !reg_overlap_mentioned_p (operands[0], operands[1])
8675 && !reg_overlap_mentioned_p (operands[2], operands[1])
8676 && !reg_overlap_mentioned_p (operands[6], operands[9])
8677 && !reg_overlap_mentioned_p (operands[0], operands[10])
8678 && !reg_overlap_mentioned_p (operands[10], operands[1])
8679 && !reg_overlap_mentioned_p (operands[0], operands[11])
8680 && !reg_overlap_mentioned_p (operands[11], operands[1])
8681 && (rtx_equal_p (operands[6], operands[0])
8682 ? (rtx_equal_p (operands[7], operands[1])
8683 && rtx_equal_p (operands[8], operands[2]))
8684 : (rtx_equal_p (operands[8], operands[0])
8685 && rtx_equal_p (operands[9], operands[1])
8686 && rtx_equal_p (operands[6], operands[2])))"
8687 [(set (match_dup 0) (match_dup 9))
8688 (parallel [(set (reg:CCC FLAGS_REG)
8689 (compare:CCC
8690 (zero_extend:<DWI> (match_dup 1))
8691 (plus:<DWI> (match_op_dup 4
8692 [(match_dup 3) (const_int 0)])
8693 (zero_extend:<DWI> (match_dup 0)))))
8694 (set (match_dup 1)
8695 (minus:SWI48 (minus:SWI48 (match_dup 1)
8696 (match_op_dup 5
8697 [(match_dup 3) (const_int 0)]))
8698 (match_dup 0)))])
8699 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8700 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8701 {
8702 if (!rtx_equal_p (operands[6], operands[0]))
8703 operands[9] = operands[7];
8704 })
8705
8706 (define_expand "subborrow<mode>_0"
8707 [(parallel
8708 [(set (reg:CC FLAGS_REG)
8709 (compare:CC
8710 (match_operand:SWI48 1 "nonimmediate_operand")
8711 (match_operand:SWI48 2 "<general_operand>")))
8712 (set (match_operand:SWI48 0 "register_operand")
8713 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8714 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8715
8716 (define_expand "uaddc<mode>5"
8717 [(match_operand:SWI48 0 "register_operand")
8718 (match_operand:SWI48 1 "register_operand")
8719 (match_operand:SWI48 2 "register_operand")
8720 (match_operand:SWI48 3 "register_operand")
8721 (match_operand:SWI48 4 "nonmemory_operand")]
8722 ""
8723 {
8724 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8725 if (operands[4] == const0_rtx)
8726 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8727 else
8728 {
8729 ix86_expand_carry (operands[4]);
8730 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8731 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8732 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8733 cf, pat, pat2));
8734 }
8735 rtx cc = gen_reg_rtx (QImode);
8736 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8737 emit_insn (gen_rtx_SET (cc, pat));
8738 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8739 DONE;
8740 })
8741
8742 (define_expand "usubc<mode>5"
8743 [(match_operand:SWI48 0 "register_operand")
8744 (match_operand:SWI48 1 "register_operand")
8745 (match_operand:SWI48 2 "register_operand")
8746 (match_operand:SWI48 3 "register_operand")
8747 (match_operand:SWI48 4 "nonmemory_operand")]
8748 ""
8749 {
8750 rtx cf, pat, pat2;
8751 if (operands[4] == const0_rtx)
8752 {
8753 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8754 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8755 operands[3]));
8756 }
8757 else
8758 {
8759 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8760 ix86_expand_carry (operands[4]);
8761 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8762 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8763 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8764 cf, pat, pat2));
8765 }
8766 rtx cc = gen_reg_rtx (QImode);
8767 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8768 emit_insn (gen_rtx_SET (cc, pat));
8769 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8770 DONE;
8771 })
8772
8773 (define_mode_iterator CC_CCC [CC CCC])
8774
8775 ;; Pre-reload splitter to optimize
8776 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8777 ;; operand and no intervening flags modifications into nothing.
8778 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8779 [(set (reg:CCC FLAGS_REG)
8780 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8781 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8782 "ix86_pre_reload_split ()"
8783 "#"
8784 "&& 1"
8785 [(const_int 0)]
8786 "emit_note (NOTE_INSN_DELETED); DONE;")
8787
8788 ;; Set the carry flag from the carry flag.
8789 (define_insn_and_split "*setccc"
8790 [(set (reg:CCC FLAGS_REG)
8791 (reg:CCC FLAGS_REG))]
8792 "ix86_pre_reload_split ()"
8793 "#"
8794 "&& 1"
8795 [(const_int 0)]
8796 "emit_note (NOTE_INSN_DELETED); DONE;")
8797
8798 ;; Set the carry flag from the carry flag.
8799 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8800 [(set (reg:CCC FLAGS_REG)
8801 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8802 "ix86_pre_reload_split ()"
8803 "#"
8804 "&& 1"
8805 [(const_int 0)]
8806 "emit_note (NOTE_INSN_DELETED); DONE;")
8807
8808 ;; Set the carry flag from the carry flag.
8809 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8810 [(set (reg:CCC FLAGS_REG)
8811 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8812 (const_int 0)] UNSPEC_CC_NE))]
8813 "ix86_pre_reload_split ()"
8814 "#"
8815 "&& 1"
8816 [(const_int 0)]
8817 "emit_note (NOTE_INSN_DELETED); DONE;")
8818 \f
8819 ;; Overflow setting add instructions
8820
8821 (define_expand "addqi3_cconly_overflow"
8822 [(parallel
8823 [(set (reg:CCC FLAGS_REG)
8824 (compare:CCC
8825 (plus:QI
8826 (match_operand:QI 0 "nonimmediate_operand")
8827 (match_operand:QI 1 "general_operand"))
8828 (match_dup 0)))
8829 (clobber (scratch:QI))])]
8830 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8831
8832 (define_insn "*add<mode>3_cconly_overflow_1"
8833 [(set (reg:CCC FLAGS_REG)
8834 (compare:CCC
8835 (plus:SWI
8836 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8837 (match_operand:SWI 2 "<general_operand>" "<g>"))
8838 (match_dup 1)))
8839 (clobber (match_scratch:SWI 0 "=<r>"))]
8840 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8841 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8842 [(set_attr "type" "alu")
8843 (set_attr "mode" "<MODE>")])
8844
8845 (define_insn "*add<mode>3_cc_overflow_1"
8846 [(set (reg:CCC FLAGS_REG)
8847 (compare:CCC
8848 (plus:SWI
8849 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8850 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8851 (match_dup 1)))
8852 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8853 (plus:SWI (match_dup 1) (match_dup 2)))]
8854 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8855 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8856 [(set_attr "type" "alu")
8857 (set_attr "mode" "<MODE>")])
8858
8859 (define_peephole2
8860 [(parallel [(set (reg:CCC FLAGS_REG)
8861 (compare:CCC
8862 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
8863 (match_operand:SWI 1 "memory_operand"))
8864 (match_dup 0)))
8865 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
8866 (set (match_dup 1) (match_dup 0))]
8867 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8868 && peep2_reg_dead_p (2, operands[0])
8869 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8870 [(parallel [(set (reg:CCC FLAGS_REG)
8871 (compare:CCC
8872 (plus:SWI (match_dup 1) (match_dup 0))
8873 (match_dup 1)))
8874 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8875
8876 (define_peephole2
8877 [(set (match_operand:SWI 0 "general_reg_operand")
8878 (match_operand:SWI 1 "memory_operand"))
8879 (parallel [(set (reg:CCC FLAGS_REG)
8880 (compare:CCC
8881 (plus:SWI (match_dup 0)
8882 (match_operand:SWI 2 "memory_operand"))
8883 (match_dup 0)))
8884 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
8885 (set (match_dup 1) (match_dup 0))]
8886 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8887 && peep2_reg_dead_p (3, operands[0])
8888 && !reg_overlap_mentioned_p (operands[0], operands[1])
8889 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8890 [(set (match_dup 0) (match_dup 2))
8891 (parallel [(set (reg:CCC FLAGS_REG)
8892 (compare:CCC
8893 (plus:SWI (match_dup 1) (match_dup 0))
8894 (match_dup 1)))
8895 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8896
8897 (define_insn "*addsi3_zext_cc_overflow_1"
8898 [(set (reg:CCC FLAGS_REG)
8899 (compare:CCC
8900 (plus:SI
8901 (match_operand:SI 1 "nonimmediate_operand" "%0")
8902 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8903 (match_dup 1)))
8904 (set (match_operand:DI 0 "register_operand" "=r")
8905 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8906 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8907 "add{l}\t{%2, %k0|%k0, %2}"
8908 [(set_attr "type" "alu")
8909 (set_attr "mode" "SI")])
8910
8911 (define_insn "*add<mode>3_cconly_overflow_2"
8912 [(set (reg:CCC FLAGS_REG)
8913 (compare:CCC
8914 (plus:SWI
8915 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8916 (match_operand:SWI 2 "<general_operand>" "<g>"))
8917 (match_dup 2)))
8918 (clobber (match_scratch:SWI 0 "=<r>"))]
8919 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8920 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8921 [(set_attr "type" "alu")
8922 (set_attr "mode" "<MODE>")])
8923
8924 (define_insn "*add<mode>3_cc_overflow_2"
8925 [(set (reg:CCC FLAGS_REG)
8926 (compare:CCC
8927 (plus:SWI
8928 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8929 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8930 (match_dup 2)))
8931 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8932 (plus:SWI (match_dup 1) (match_dup 2)))]
8933 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8934 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8935 [(set_attr "type" "alu")
8936 (set_attr "mode" "<MODE>")])
8937
8938 (define_insn "*addsi3_zext_cc_overflow_2"
8939 [(set (reg:CCC FLAGS_REG)
8940 (compare:CCC
8941 (plus:SI
8942 (match_operand:SI 1 "nonimmediate_operand" "%0")
8943 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8944 (match_dup 2)))
8945 (set (match_operand:DI 0 "register_operand" "=r")
8946 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8947 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8948 "add{l}\t{%2, %k0|%k0, %2}"
8949 [(set_attr "type" "alu")
8950 (set_attr "mode" "SI")])
8951
8952 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
8953 [(set (reg:CCC FLAGS_REG)
8954 (compare:CCC
8955 (plus:<DWI>
8956 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
8957 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
8958 (match_dup 1)))
8959 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
8960 (plus:<DWI> (match_dup 1) (match_dup 2)))]
8961 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
8962 "#"
8963 "&& reload_completed"
8964 [(parallel [(set (reg:CCC FLAGS_REG)
8965 (compare:CCC
8966 (plus:DWIH (match_dup 1) (match_dup 2))
8967 (match_dup 1)))
8968 (set (match_dup 0)
8969 (plus:DWIH (match_dup 1) (match_dup 2)))])
8970 (parallel [(set (reg:CCC FLAGS_REG)
8971 (compare:CCC
8972 (zero_extend:<DWI>
8973 (plus:DWIH
8974 (plus:DWIH
8975 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8976 (match_dup 4))
8977 (match_dup 5)))
8978 (plus:<DWI>
8979 (match_dup 6)
8980 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
8981 (set (match_dup 3)
8982 (plus:DWIH
8983 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8984 (match_dup 4))
8985 (match_dup 5)))])]
8986 {
8987 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8988 if (operands[2] == const0_rtx)
8989 {
8990 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
8991 DONE;
8992 }
8993 if (CONST_INT_P (operands[5]))
8994 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
8995 operands[5], <MODE>mode);
8996 else
8997 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
8998 })
8999
9000 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
9001 ;; test, where the latter is preferrable if we have some carry consuming
9002 ;; instruction.
9003 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
9004 ;; + (1 - CF).
9005 (define_insn_and_split "*add<mode>3_eq"
9006 [(set (match_operand:SWI 0 "nonimmediate_operand")
9007 (plus:SWI
9008 (plus:SWI
9009 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9010 (match_operand:SWI 1 "nonimmediate_operand"))
9011 (match_operand:SWI 2 "<general_operand>")))
9012 (clobber (reg:CC FLAGS_REG))]
9013 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9014 && ix86_pre_reload_split ()"
9015 "#"
9016 "&& 1"
9017 [(set (reg:CC FLAGS_REG)
9018 (compare:CC (match_dup 3) (const_int 1)))
9019 (parallel [(set (match_dup 0)
9020 (plus:SWI
9021 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9022 (match_dup 1))
9023 (match_dup 2)))
9024 (clobber (reg:CC FLAGS_REG))])])
9025
9026 (define_insn_and_split "*add<mode>3_ne"
9027 [(set (match_operand:SWI 0 "nonimmediate_operand")
9028 (plus:SWI
9029 (plus:SWI
9030 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
9031 (match_operand:SWI 1 "nonimmediate_operand"))
9032 (match_operand:SWI 2 "<immediate_operand>")))
9033 (clobber (reg:CC FLAGS_REG))]
9034 "CONST_INT_P (operands[2])
9035 && (<MODE>mode != DImode
9036 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9037 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9038 && ix86_pre_reload_split ()"
9039 "#"
9040 "&& 1"
9041 [(set (reg:CC FLAGS_REG)
9042 (compare:CC (match_dup 3) (const_int 1)))
9043 (parallel [(set (match_dup 0)
9044 (minus:SWI
9045 (minus:SWI (match_dup 1)
9046 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9047 (match_dup 2)))
9048 (clobber (reg:CC FLAGS_REG))])]
9049 {
9050 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9051 <MODE>mode == DImode ? SImode : <MODE>mode);
9052 })
9053
9054 (define_insn_and_split "*add<mode>3_eq_0"
9055 [(set (match_operand:SWI 0 "nonimmediate_operand")
9056 (plus:SWI
9057 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9058 (match_operand:SWI 1 "<general_operand>")))
9059 (clobber (reg:CC FLAGS_REG))]
9060 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9061 && ix86_pre_reload_split ()"
9062 "#"
9063 "&& 1"
9064 [(set (reg:CC FLAGS_REG)
9065 (compare:CC (match_dup 2) (const_int 1)))
9066 (parallel [(set (match_dup 0)
9067 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9068 (match_dup 1)))
9069 (clobber (reg:CC FLAGS_REG))])]
9070 {
9071 if (!nonimmediate_operand (operands[1], <MODE>mode))
9072 operands[1] = force_reg (<MODE>mode, operands[1]);
9073 })
9074
9075 (define_insn_and_split "*add<mode>3_ne_0"
9076 [(set (match_operand:SWI 0 "nonimmediate_operand")
9077 (plus:SWI
9078 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9079 (match_operand:SWI 1 "<general_operand>")))
9080 (clobber (reg:CC FLAGS_REG))]
9081 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9082 && ix86_pre_reload_split ()"
9083 "#"
9084 "&& 1"
9085 [(set (reg:CC FLAGS_REG)
9086 (compare:CC (match_dup 2) (const_int 1)))
9087 (parallel [(set (match_dup 0)
9088 (minus:SWI (minus:SWI
9089 (match_dup 1)
9090 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9091 (const_int -1)))
9092 (clobber (reg:CC FLAGS_REG))])]
9093 {
9094 if (!nonimmediate_operand (operands[1], <MODE>mode))
9095 operands[1] = force_reg (<MODE>mode, operands[1]);
9096 })
9097
9098 (define_insn_and_split "*sub<mode>3_eq"
9099 [(set (match_operand:SWI 0 "nonimmediate_operand")
9100 (minus:SWI
9101 (minus:SWI
9102 (match_operand:SWI 1 "nonimmediate_operand")
9103 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9104 (const_int 0)))
9105 (match_operand:SWI 2 "<general_operand>")))
9106 (clobber (reg:CC FLAGS_REG))]
9107 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9108 && ix86_pre_reload_split ()"
9109 "#"
9110 "&& 1"
9111 [(set (reg:CC FLAGS_REG)
9112 (compare:CC (match_dup 3) (const_int 1)))
9113 (parallel [(set (match_dup 0)
9114 (minus:SWI
9115 (minus:SWI (match_dup 1)
9116 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9117 (match_dup 2)))
9118 (clobber (reg:CC FLAGS_REG))])])
9119
9120 (define_insn_and_split "*sub<mode>3_ne"
9121 [(set (match_operand:SWI 0 "nonimmediate_operand")
9122 (plus:SWI
9123 (minus:SWI
9124 (match_operand:SWI 1 "nonimmediate_operand")
9125 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9126 (const_int 0)))
9127 (match_operand:SWI 2 "<immediate_operand>")))
9128 (clobber (reg:CC FLAGS_REG))]
9129 "CONST_INT_P (operands[2])
9130 && (<MODE>mode != DImode
9131 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9132 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9133 && ix86_pre_reload_split ()"
9134 "#"
9135 "&& 1"
9136 [(set (reg:CC FLAGS_REG)
9137 (compare:CC (match_dup 3) (const_int 1)))
9138 (parallel [(set (match_dup 0)
9139 (plus:SWI
9140 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9141 (match_dup 1))
9142 (match_dup 2)))
9143 (clobber (reg:CC FLAGS_REG))])]
9144 {
9145 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9146 <MODE>mode == DImode ? SImode : <MODE>mode);
9147 })
9148
9149 (define_insn_and_split "*sub<mode>3_eq_1"
9150 [(set (match_operand:SWI 0 "nonimmediate_operand")
9151 (plus:SWI
9152 (minus:SWI
9153 (match_operand:SWI 1 "nonimmediate_operand")
9154 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9155 (const_int 0)))
9156 (match_operand:SWI 2 "<immediate_operand>")))
9157 (clobber (reg:CC FLAGS_REG))]
9158 "CONST_INT_P (operands[2])
9159 && (<MODE>mode != DImode
9160 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9161 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9162 && ix86_pre_reload_split ()"
9163 "#"
9164 "&& 1"
9165 [(set (reg:CC FLAGS_REG)
9166 (compare:CC (match_dup 3) (const_int 1)))
9167 (parallel [(set (match_dup 0)
9168 (minus:SWI
9169 (minus:SWI (match_dup 1)
9170 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9171 (match_dup 2)))
9172 (clobber (reg:CC FLAGS_REG))])]
9173 {
9174 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9175 <MODE>mode == DImode ? SImode : <MODE>mode);
9176 })
9177
9178 (define_insn_and_split "*sub<mode>3_eq_0"
9179 [(set (match_operand:SWI 0 "nonimmediate_operand")
9180 (minus:SWI
9181 (match_operand:SWI 1 "<general_operand>")
9182 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9183 (clobber (reg:CC FLAGS_REG))]
9184 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9185 && ix86_pre_reload_split ()"
9186 "#"
9187 "&& 1"
9188 [(set (reg:CC FLAGS_REG)
9189 (compare:CC (match_dup 2) (const_int 1)))
9190 (parallel [(set (match_dup 0)
9191 (minus:SWI (match_dup 1)
9192 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9193 (clobber (reg:CC FLAGS_REG))])]
9194 {
9195 if (!nonimmediate_operand (operands[1], <MODE>mode))
9196 operands[1] = force_reg (<MODE>mode, operands[1]);
9197 })
9198
9199 (define_insn_and_split "*sub<mode>3_ne_0"
9200 [(set (match_operand:SWI 0 "nonimmediate_operand")
9201 (minus:SWI
9202 (match_operand:SWI 1 "<general_operand>")
9203 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9204 (clobber (reg:CC FLAGS_REG))]
9205 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9206 && ix86_pre_reload_split ()"
9207 "#"
9208 "&& 1"
9209 [(set (reg:CC FLAGS_REG)
9210 (compare:CC (match_dup 2) (const_int 1)))
9211 (parallel [(set (match_dup 0)
9212 (plus:SWI (plus:SWI
9213 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9214 (match_dup 1))
9215 (const_int -1)))
9216 (clobber (reg:CC FLAGS_REG))])]
9217 {
9218 if (!nonimmediate_operand (operands[1], <MODE>mode))
9219 operands[1] = force_reg (<MODE>mode, operands[1]);
9220 })
9221
9222 ;; The patterns that match these are at the end of this file.
9223
9224 (define_expand "<insn>xf3"
9225 [(set (match_operand:XF 0 "register_operand")
9226 (plusminus:XF
9227 (match_operand:XF 1 "register_operand")
9228 (match_operand:XF 2 "register_operand")))]
9229 "TARGET_80387")
9230
9231 (define_expand "<insn>hf3"
9232 [(set (match_operand:HF 0 "register_operand")
9233 (plusminus:HF
9234 (match_operand:HF 1 "register_operand")
9235 (match_operand:HF 2 "nonimmediate_operand")))]
9236 "TARGET_AVX512FP16")
9237
9238 (define_expand "<insn><mode>3"
9239 [(set (match_operand:MODEF 0 "register_operand")
9240 (plusminus:MODEF
9241 (match_operand:MODEF 1 "register_operand")
9242 (match_operand:MODEF 2 "nonimmediate_operand")))]
9243 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9244 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9245 \f
9246 ;; Multiply instructions
9247
9248 (define_expand "mul<mode>3"
9249 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9250 (mult:SWIM248
9251 (match_operand:SWIM248 1 "register_operand")
9252 (match_operand:SWIM248 2 "<general_operand>")))
9253 (clobber (reg:CC FLAGS_REG))])])
9254
9255 (define_expand "mulqi3"
9256 [(parallel [(set (match_operand:QI 0 "register_operand")
9257 (mult:QI
9258 (match_operand:QI 1 "register_operand")
9259 (match_operand:QI 2 "nonimmediate_operand")))
9260 (clobber (reg:CC FLAGS_REG))])]
9261 "TARGET_QIMODE_MATH")
9262
9263 ;; On AMDFAM10
9264 ;; IMUL reg32/64, reg32/64, imm8 Direct
9265 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9266 ;; IMUL reg32/64, reg32/64, imm32 Direct
9267 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9268 ;; IMUL reg32/64, reg32/64 Direct
9269 ;; IMUL reg32/64, mem32/64 Direct
9270 ;;
9271 ;; On BDVER1, all above IMULs use DirectPath
9272 ;;
9273 ;; On AMDFAM10
9274 ;; IMUL reg16, reg16, imm8 VectorPath
9275 ;; IMUL reg16, mem16, imm8 VectorPath
9276 ;; IMUL reg16, reg16, imm16 VectorPath
9277 ;; IMUL reg16, mem16, imm16 VectorPath
9278 ;; IMUL reg16, reg16 Direct
9279 ;; IMUL reg16, mem16 Direct
9280 ;;
9281 ;; On BDVER1, all HI MULs use DoublePath
9282
9283 (define_insn "*mul<mode>3_1"
9284 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9285 (mult:SWIM248
9286 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9287 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9288 (clobber (reg:CC FLAGS_REG))]
9289 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9290 "@
9291 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9292 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9293 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9294 [(set_attr "type" "imul")
9295 (set_attr "prefix_0f" "0,0,1")
9296 (set (attr "athlon_decode")
9297 (cond [(eq_attr "cpu" "athlon")
9298 (const_string "vector")
9299 (eq_attr "alternative" "1")
9300 (const_string "vector")
9301 (and (eq_attr "alternative" "2")
9302 (ior (match_test "<MODE>mode == HImode")
9303 (match_operand 1 "memory_operand")))
9304 (const_string "vector")]
9305 (const_string "direct")))
9306 (set (attr "amdfam10_decode")
9307 (cond [(and (eq_attr "alternative" "0,1")
9308 (ior (match_test "<MODE>mode == HImode")
9309 (match_operand 1 "memory_operand")))
9310 (const_string "vector")]
9311 (const_string "direct")))
9312 (set (attr "bdver1_decode")
9313 (if_then_else
9314 (match_test "<MODE>mode == HImode")
9315 (const_string "double")
9316 (const_string "direct")))
9317 (set_attr "mode" "<MODE>")])
9318
9319 (define_insn "*mulsi3_1_zext"
9320 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9321 (zero_extend:DI
9322 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9323 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9324 (clobber (reg:CC FLAGS_REG))]
9325 "TARGET_64BIT
9326 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9327 "@
9328 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9329 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9330 imul{l}\t{%2, %k0|%k0, %2}"
9331 [(set_attr "type" "imul")
9332 (set_attr "prefix_0f" "0,0,1")
9333 (set (attr "athlon_decode")
9334 (cond [(eq_attr "cpu" "athlon")
9335 (const_string "vector")
9336 (eq_attr "alternative" "1")
9337 (const_string "vector")
9338 (and (eq_attr "alternative" "2")
9339 (match_operand 1 "memory_operand"))
9340 (const_string "vector")]
9341 (const_string "direct")))
9342 (set (attr "amdfam10_decode")
9343 (cond [(and (eq_attr "alternative" "0,1")
9344 (match_operand 1 "memory_operand"))
9345 (const_string "vector")]
9346 (const_string "direct")))
9347 (set_attr "bdver1_decode" "direct")
9348 (set_attr "mode" "SI")])
9349
9350 ;;On AMDFAM10 and BDVER1
9351 ;; MUL reg8 Direct
9352 ;; MUL mem8 Direct
9353
9354 (define_insn "*mulqi3_1"
9355 [(set (match_operand:QI 0 "register_operand" "=a")
9356 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9357 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9358 (clobber (reg:CC FLAGS_REG))]
9359 "TARGET_QIMODE_MATH
9360 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9361 "mul{b}\t%2"
9362 [(set_attr "type" "imul")
9363 (set_attr "length_immediate" "0")
9364 (set (attr "athlon_decode")
9365 (if_then_else (eq_attr "cpu" "athlon")
9366 (const_string "vector")
9367 (const_string "direct")))
9368 (set_attr "amdfam10_decode" "direct")
9369 (set_attr "bdver1_decode" "direct")
9370 (set_attr "mode" "QI")])
9371
9372 ;; Multiply with jump on overflow.
9373 (define_expand "mulv<mode>4"
9374 [(parallel [(set (reg:CCO FLAGS_REG)
9375 (eq:CCO (mult:<DWI>
9376 (sign_extend:<DWI>
9377 (match_operand:SWI248 1 "register_operand"))
9378 (match_dup 4))
9379 (sign_extend:<DWI>
9380 (mult:SWI248 (match_dup 1)
9381 (match_operand:SWI248 2
9382 "<general_operand>")))))
9383 (set (match_operand:SWI248 0 "register_operand")
9384 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9385 (set (pc) (if_then_else
9386 (eq (reg:CCO FLAGS_REG) (const_int 0))
9387 (label_ref (match_operand 3))
9388 (pc)))]
9389 ""
9390 {
9391 if (CONST_INT_P (operands[2]))
9392 operands[4] = operands[2];
9393 else
9394 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9395 })
9396
9397 (define_insn "*mulv<mode>4"
9398 [(set (reg:CCO FLAGS_REG)
9399 (eq:CCO (mult:<DWI>
9400 (sign_extend:<DWI>
9401 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9402 (sign_extend:<DWI>
9403 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9404 (sign_extend:<DWI>
9405 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9406 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9407 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9408 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9409 "@
9410 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9411 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9412 [(set_attr "type" "imul")
9413 (set_attr "prefix_0f" "0,1")
9414 (set (attr "athlon_decode")
9415 (cond [(eq_attr "cpu" "athlon")
9416 (const_string "vector")
9417 (eq_attr "alternative" "0")
9418 (const_string "vector")
9419 (and (eq_attr "alternative" "1")
9420 (match_operand 1 "memory_operand"))
9421 (const_string "vector")]
9422 (const_string "direct")))
9423 (set (attr "amdfam10_decode")
9424 (cond [(and (eq_attr "alternative" "1")
9425 (match_operand 1 "memory_operand"))
9426 (const_string "vector")]
9427 (const_string "direct")))
9428 (set_attr "bdver1_decode" "direct")
9429 (set_attr "mode" "<MODE>")])
9430
9431 (define_insn "*mulvhi4"
9432 [(set (reg:CCO FLAGS_REG)
9433 (eq:CCO (mult:SI
9434 (sign_extend:SI
9435 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9436 (sign_extend:SI
9437 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9438 (sign_extend:SI
9439 (mult:HI (match_dup 1) (match_dup 2)))))
9440 (set (match_operand:HI 0 "register_operand" "=r")
9441 (mult:HI (match_dup 1) (match_dup 2)))]
9442 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9443 "imul{w}\t{%2, %0|%0, %2}"
9444 [(set_attr "type" "imul")
9445 (set_attr "prefix_0f" "1")
9446 (set_attr "athlon_decode" "vector")
9447 (set_attr "amdfam10_decode" "direct")
9448 (set_attr "bdver1_decode" "double")
9449 (set_attr "mode" "HI")])
9450
9451 (define_insn "*mulv<mode>4_1"
9452 [(set (reg:CCO FLAGS_REG)
9453 (eq:CCO (mult:<DWI>
9454 (sign_extend:<DWI>
9455 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9456 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9457 (sign_extend:<DWI>
9458 (mult:SWI248 (match_dup 1)
9459 (match_operand:SWI248 2
9460 "<immediate_operand>" "K,<i>")))))
9461 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9462 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9463 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9464 && CONST_INT_P (operands[2])
9465 && INTVAL (operands[2]) == INTVAL (operands[3])"
9466 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9467 [(set_attr "type" "imul")
9468 (set (attr "prefix_0f")
9469 (if_then_else
9470 (match_test "<MODE>mode == HImode")
9471 (const_string "0")
9472 (const_string "*")))
9473 (set (attr "athlon_decode")
9474 (cond [(eq_attr "cpu" "athlon")
9475 (const_string "vector")
9476 (eq_attr "alternative" "1")
9477 (const_string "vector")]
9478 (const_string "direct")))
9479 (set (attr "amdfam10_decode")
9480 (cond [(ior (match_test "<MODE>mode == HImode")
9481 (match_operand 1 "memory_operand"))
9482 (const_string "vector")]
9483 (const_string "direct")))
9484 (set (attr "bdver1_decode")
9485 (if_then_else
9486 (match_test "<MODE>mode == HImode")
9487 (const_string "double")
9488 (const_string "direct")))
9489 (set_attr "mode" "<MODE>")
9490 (set (attr "length_immediate")
9491 (cond [(eq_attr "alternative" "0")
9492 (const_string "1")
9493 (match_test "<MODE_SIZE> == 8")
9494 (const_string "4")]
9495 (const_string "<MODE_SIZE>")))])
9496
9497 (define_expand "umulv<mode>4"
9498 [(parallel [(set (reg:CCO FLAGS_REG)
9499 (eq:CCO (mult:<DWI>
9500 (zero_extend:<DWI>
9501 (match_operand:SWI248 1
9502 "nonimmediate_operand"))
9503 (zero_extend:<DWI>
9504 (match_operand:SWI248 2
9505 "nonimmediate_operand")))
9506 (zero_extend:<DWI>
9507 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9508 (set (match_operand:SWI248 0 "register_operand")
9509 (mult:SWI248 (match_dup 1) (match_dup 2)))
9510 (clobber (scratch:SWI248))])
9511 (set (pc) (if_then_else
9512 (eq (reg:CCO FLAGS_REG) (const_int 0))
9513 (label_ref (match_operand 3))
9514 (pc)))]
9515 ""
9516 {
9517 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9518 operands[1] = force_reg (<MODE>mode, operands[1]);
9519 })
9520
9521 (define_insn "*umulv<mode>4"
9522 [(set (reg:CCO FLAGS_REG)
9523 (eq:CCO (mult:<DWI>
9524 (zero_extend:<DWI>
9525 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9526 (zero_extend:<DWI>
9527 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9528 (zero_extend:<DWI>
9529 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9530 (set (match_operand:SWI248 0 "register_operand" "=a")
9531 (mult:SWI248 (match_dup 1) (match_dup 2)))
9532 (clobber (match_scratch:SWI248 3 "=d"))]
9533 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9534 "mul{<imodesuffix>}\t%2"
9535 [(set_attr "type" "imul")
9536 (set_attr "length_immediate" "0")
9537 (set (attr "athlon_decode")
9538 (if_then_else (eq_attr "cpu" "athlon")
9539 (const_string "vector")
9540 (const_string "double")))
9541 (set_attr "amdfam10_decode" "double")
9542 (set_attr "bdver1_decode" "direct")
9543 (set_attr "mode" "<MODE>")])
9544
9545 (define_expand "<u>mulvqi4"
9546 [(parallel [(set (reg:CCO FLAGS_REG)
9547 (eq:CCO (mult:HI
9548 (any_extend:HI
9549 (match_operand:QI 1 "nonimmediate_operand"))
9550 (any_extend:HI
9551 (match_operand:QI 2 "nonimmediate_operand")))
9552 (any_extend:HI
9553 (mult:QI (match_dup 1) (match_dup 2)))))
9554 (set (match_operand:QI 0 "register_operand")
9555 (mult:QI (match_dup 1) (match_dup 2)))])
9556 (set (pc) (if_then_else
9557 (eq (reg:CCO FLAGS_REG) (const_int 0))
9558 (label_ref (match_operand 3))
9559 (pc)))]
9560 "TARGET_QIMODE_MATH"
9561 {
9562 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9563 operands[1] = force_reg (QImode, operands[1]);
9564 })
9565
9566 (define_insn "*<u>mulvqi4"
9567 [(set (reg:CCO FLAGS_REG)
9568 (eq:CCO (mult:HI
9569 (any_extend:HI
9570 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9571 (any_extend:HI
9572 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9573 (any_extend:HI
9574 (mult:QI (match_dup 1) (match_dup 2)))))
9575 (set (match_operand:QI 0 "register_operand" "=a")
9576 (mult:QI (match_dup 1) (match_dup 2)))]
9577 "TARGET_QIMODE_MATH
9578 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9579 "<sgnprefix>mul{b}\t%2"
9580 [(set_attr "type" "imul")
9581 (set_attr "length_immediate" "0")
9582 (set (attr "athlon_decode")
9583 (if_then_else (eq_attr "cpu" "athlon")
9584 (const_string "vector")
9585 (const_string "direct")))
9586 (set_attr "amdfam10_decode" "direct")
9587 (set_attr "bdver1_decode" "direct")
9588 (set_attr "mode" "QI")])
9589
9590 (define_expand "<u>mul<mode><dwi>3"
9591 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9592 (mult:<DWI>
9593 (any_extend:<DWI>
9594 (match_operand:DWIH 1 "nonimmediate_operand"))
9595 (any_extend:<DWI>
9596 (match_operand:DWIH 2 "register_operand"))))
9597 (clobber (reg:CC FLAGS_REG))])])
9598
9599 (define_expand "<u>mulqihi3"
9600 [(parallel [(set (match_operand:HI 0 "register_operand")
9601 (mult:HI
9602 (any_extend:HI
9603 (match_operand:QI 1 "nonimmediate_operand"))
9604 (any_extend:HI
9605 (match_operand:QI 2 "register_operand"))))
9606 (clobber (reg:CC FLAGS_REG))])]
9607 "TARGET_QIMODE_MATH")
9608
9609 (define_insn "*bmi2_umul<mode><dwi>3_1"
9610 [(set (match_operand:DWIH 0 "register_operand" "=r")
9611 (mult:DWIH
9612 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
9613 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9614 (set (match_operand:DWIH 1 "register_operand" "=r")
9615 (truncate:DWIH
9616 (lshiftrt:<DWI>
9617 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9618 (zero_extend:<DWI> (match_dup 3)))
9619 (match_operand:QI 4 "const_int_operand"))))]
9620 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
9621 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
9622 "mulx\t{%3, %0, %1|%1, %0, %3}"
9623 [(set_attr "type" "imulx")
9624 (set_attr "prefix" "vex")
9625 (set_attr "mode" "<MODE>")])
9626
9627 (define_insn "*umul<mode><dwi>3_1"
9628 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9629 (mult:<DWI>
9630 (zero_extend:<DWI>
9631 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
9632 (zero_extend:<DWI>
9633 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9634 (clobber (reg:CC FLAGS_REG))]
9635 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9636 "@
9637 #
9638 mul{<imodesuffix>}\t%2"
9639 [(set_attr "isa" "bmi2,*")
9640 (set_attr "type" "imulx,imul")
9641 (set_attr "length_immediate" "*,0")
9642 (set (attr "athlon_decode")
9643 (cond [(eq_attr "alternative" "1")
9644 (if_then_else (eq_attr "cpu" "athlon")
9645 (const_string "vector")
9646 (const_string "double"))]
9647 (const_string "*")))
9648 (set_attr "amdfam10_decode" "*,double")
9649 (set_attr "bdver1_decode" "*,direct")
9650 (set_attr "prefix" "vex,orig")
9651 (set_attr "mode" "<MODE>")])
9652
9653 ;; Convert mul to the mulx pattern to avoid flags dependency.
9654 (define_split
9655 [(set (match_operand:<DWI> 0 "register_operand")
9656 (mult:<DWI>
9657 (zero_extend:<DWI>
9658 (match_operand:DWIH 1 "register_operand"))
9659 (zero_extend:<DWI>
9660 (match_operand:DWIH 2 "nonimmediate_operand"))))
9661 (clobber (reg:CC FLAGS_REG))]
9662 "TARGET_BMI2 && reload_completed
9663 && REGNO (operands[1]) == DX_REG"
9664 [(parallel [(set (match_dup 3)
9665 (mult:DWIH (match_dup 1) (match_dup 2)))
9666 (set (match_dup 4)
9667 (truncate:DWIH
9668 (lshiftrt:<DWI>
9669 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
9670 (zero_extend:<DWI> (match_dup 2)))
9671 (match_dup 5))))])]
9672 {
9673 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9674
9675 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9676 })
9677
9678 (define_insn "*mul<mode><dwi>3_1"
9679 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9680 (mult:<DWI>
9681 (sign_extend:<DWI>
9682 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
9683 (sign_extend:<DWI>
9684 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9685 (clobber (reg:CC FLAGS_REG))]
9686 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9687 "imul{<imodesuffix>}\t%2"
9688 [(set_attr "type" "imul")
9689 (set_attr "length_immediate" "0")
9690 (set (attr "athlon_decode")
9691 (if_then_else (eq_attr "cpu" "athlon")
9692 (const_string "vector")
9693 (const_string "double")))
9694 (set_attr "amdfam10_decode" "double")
9695 (set_attr "bdver1_decode" "direct")
9696 (set_attr "mode" "<MODE>")])
9697
9698 (define_insn "*<u>mulqihi3_1"
9699 [(set (match_operand:HI 0 "register_operand" "=a")
9700 (mult:HI
9701 (any_extend:HI
9702 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9703 (any_extend:HI
9704 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9705 (clobber (reg:CC FLAGS_REG))]
9706 "TARGET_QIMODE_MATH
9707 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9708 "<sgnprefix>mul{b}\t%2"
9709 [(set_attr "type" "imul")
9710 (set_attr "length_immediate" "0")
9711 (set (attr "athlon_decode")
9712 (if_then_else (eq_attr "cpu" "athlon")
9713 (const_string "vector")
9714 (const_string "direct")))
9715 (set_attr "amdfam10_decode" "direct")
9716 (set_attr "bdver1_decode" "direct")
9717 (set_attr "mode" "QI")])
9718
9719 ;; Highpart multiplication patterns
9720 (define_insn "<s>mul<mode>3_highpart"
9721 [(set (match_operand:DWIH 0 "register_operand" "=d")
9722 (any_mul_highpart:DWIH
9723 (match_operand:DWIH 1 "register_operand" "%a")
9724 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9725 (clobber (match_scratch:DWIH 3 "=1"))
9726 (clobber (reg:CC FLAGS_REG))]
9727 ""
9728 "<sgnprefix>mul{<imodesuffix>}\t%2"
9729 [(set_attr "type" "imul")
9730 (set_attr "length_immediate" "0")
9731 (set (attr "athlon_decode")
9732 (if_then_else (eq_attr "cpu" "athlon")
9733 (const_string "vector")
9734 (const_string "double")))
9735 (set_attr "amdfam10_decode" "double")
9736 (set_attr "bdver1_decode" "direct")
9737 (set_attr "mode" "<MODE>")])
9738
9739 (define_insn "*<s>mulsi3_highpart_zext"
9740 [(set (match_operand:DI 0 "register_operand" "=d")
9741 (zero_extend:DI
9742 (any_mul_highpart:SI
9743 (match_operand:SI 1 "register_operand" "%a")
9744 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9745 (clobber (match_scratch:SI 3 "=1"))
9746 (clobber (reg:CC FLAGS_REG))]
9747 "TARGET_64BIT"
9748 "<sgnprefix>mul{l}\t%2"
9749 [(set_attr "type" "imul")
9750 (set_attr "length_immediate" "0")
9751 (set (attr "athlon_decode")
9752 (if_then_else (eq_attr "cpu" "athlon")
9753 (const_string "vector")
9754 (const_string "double")))
9755 (set_attr "amdfam10_decode" "double")
9756 (set_attr "bdver1_decode" "direct")
9757 (set_attr "mode" "SI")])
9758
9759 (define_insn "*<s>muldi3_highpart_1"
9760 [(set (match_operand:DI 0 "register_operand" "=d")
9761 (truncate:DI
9762 (lshiftrt:TI
9763 (mult:TI
9764 (any_extend:TI
9765 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9766 (any_extend:TI
9767 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9768 (const_int 64))))
9769 (clobber (match_scratch:DI 3 "=1"))
9770 (clobber (reg:CC FLAGS_REG))]
9771 "TARGET_64BIT
9772 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9773 "<sgnprefix>mul{q}\t%2"
9774 [(set_attr "type" "imul")
9775 (set_attr "length_immediate" "0")
9776 (set (attr "athlon_decode")
9777 (if_then_else (eq_attr "cpu" "athlon")
9778 (const_string "vector")
9779 (const_string "double")))
9780 (set_attr "amdfam10_decode" "double")
9781 (set_attr "bdver1_decode" "direct")
9782 (set_attr "mode" "DI")])
9783
9784 (define_insn "*<s>mulsi3_highpart_zext"
9785 [(set (match_operand:DI 0 "register_operand" "=d")
9786 (zero_extend:DI (truncate:SI
9787 (lshiftrt:DI
9788 (mult:DI (any_extend:DI
9789 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9790 (any_extend:DI
9791 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9792 (const_int 32)))))
9793 (clobber (match_scratch:SI 3 "=1"))
9794 (clobber (reg:CC FLAGS_REG))]
9795 "TARGET_64BIT
9796 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9797 "<sgnprefix>mul{l}\t%2"
9798 [(set_attr "type" "imul")
9799 (set_attr "length_immediate" "0")
9800 (set (attr "athlon_decode")
9801 (if_then_else (eq_attr "cpu" "athlon")
9802 (const_string "vector")
9803 (const_string "double")))
9804 (set_attr "amdfam10_decode" "double")
9805 (set_attr "bdver1_decode" "direct")
9806 (set_attr "mode" "SI")])
9807
9808 (define_insn "*<s>mulsi3_highpart_1"
9809 [(set (match_operand:SI 0 "register_operand" "=d")
9810 (truncate:SI
9811 (lshiftrt:DI
9812 (mult:DI
9813 (any_extend:DI
9814 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9815 (any_extend:DI
9816 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9817 (const_int 32))))
9818 (clobber (match_scratch:SI 3 "=1"))
9819 (clobber (reg:CC FLAGS_REG))]
9820 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9821 "<sgnprefix>mul{l}\t%2"
9822 [(set_attr "type" "imul")
9823 (set_attr "length_immediate" "0")
9824 (set (attr "athlon_decode")
9825 (if_then_else (eq_attr "cpu" "athlon")
9826 (const_string "vector")
9827 (const_string "double")))
9828 (set_attr "amdfam10_decode" "double")
9829 (set_attr "bdver1_decode" "direct")
9830 (set_attr "mode" "SI")])
9831
9832 ;; Highpart multiplication peephole2s to tweak register allocation.
9833 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
9834 (define_peephole2
9835 [(set (match_operand:SWI48 0 "general_reg_operand")
9836 (match_operand:SWI48 1 "immediate_operand"))
9837 (set (match_operand:SWI48 2 "general_reg_operand")
9838 (match_operand:SWI48 3 "general_reg_operand"))
9839 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
9840 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
9841 (clobber (match_dup 2))
9842 (clobber (reg:CC FLAGS_REG))])]
9843 "REGNO (operands[3]) != AX_REG
9844 && REGNO (operands[0]) != REGNO (operands[2])
9845 && REGNO (operands[0]) != REGNO (operands[3])
9846 && (REGNO (operands[0]) == REGNO (operands[4])
9847 || peep2_reg_dead_p (3, operands[0]))"
9848 [(set (match_dup 2) (match_dup 1))
9849 (parallel [(set (match_dup 4)
9850 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
9851 (clobber (match_dup 2))
9852 (clobber (reg:CC FLAGS_REG))])])
9853
9854 (define_peephole2
9855 [(set (match_operand:SI 0 "general_reg_operand")
9856 (match_operand:SI 1 "immediate_operand"))
9857 (set (match_operand:SI 2 "general_reg_operand")
9858 (match_operand:SI 3 "general_reg_operand"))
9859 (parallel [(set (match_operand:DI 4 "general_reg_operand")
9860 (zero_extend:DI
9861 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
9862 (clobber (match_dup 2))
9863 (clobber (reg:CC FLAGS_REG))])]
9864 "TARGET_64BIT
9865 && REGNO (operands[3]) != AX_REG
9866 && REGNO (operands[0]) != REGNO (operands[2])
9867 && REGNO (operands[2]) != REGNO (operands[3])
9868 && REGNO (operands[0]) != REGNO (operands[3])
9869 && (REGNO (operands[0]) == REGNO (operands[4])
9870 || peep2_reg_dead_p (3, operands[0]))"
9871 [(set (match_dup 2) (match_dup 1))
9872 (parallel [(set (match_dup 4)
9873 (zero_extend:DI
9874 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
9875 (clobber (match_dup 2))
9876 (clobber (reg:CC FLAGS_REG))])])
9877
9878 ;; The patterns that match these are at the end of this file.
9879
9880 (define_expand "mulxf3"
9881 [(set (match_operand:XF 0 "register_operand")
9882 (mult:XF (match_operand:XF 1 "register_operand")
9883 (match_operand:XF 2 "register_operand")))]
9884 "TARGET_80387")
9885
9886 (define_expand "mulhf3"
9887 [(set (match_operand:HF 0 "register_operand")
9888 (mult:HF (match_operand:HF 1 "register_operand")
9889 (match_operand:HF 2 "nonimmediate_operand")))]
9890 "TARGET_AVX512FP16")
9891
9892 (define_expand "mul<mode>3"
9893 [(set (match_operand:MODEF 0 "register_operand")
9894 (mult:MODEF (match_operand:MODEF 1 "register_operand")
9895 (match_operand:MODEF 2 "nonimmediate_operand")))]
9896 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9897 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9898 \f
9899 ;; Divide instructions
9900
9901 ;; The patterns that match these are at the end of this file.
9902
9903 (define_expand "divxf3"
9904 [(set (match_operand:XF 0 "register_operand")
9905 (div:XF (match_operand:XF 1 "register_operand")
9906 (match_operand:XF 2 "register_operand")))]
9907 "TARGET_80387")
9908
9909 /* There is no more precision loss than Newton-Rhapson approximation
9910 when using HFmode rcp/rsqrt, so do the transformation directly under
9911 TARGET_RECIP_DIV and fast-math. */
9912 (define_expand "divhf3"
9913 [(set (match_operand:HF 0 "register_operand")
9914 (div:HF (match_operand:HF 1 "register_operand")
9915 (match_operand:HF 2 "nonimmediate_operand")))]
9916 "TARGET_AVX512FP16"
9917 {
9918 if (TARGET_RECIP_DIV
9919 && optimize_insn_for_speed_p ()
9920 && flag_finite_math_only && !flag_trapping_math
9921 && flag_unsafe_math_optimizations)
9922 {
9923 rtx op = gen_reg_rtx (HFmode);
9924 operands[2] = force_reg (HFmode, operands[2]);
9925 emit_insn (gen_rcphf2 (op, operands[2]));
9926 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
9927 DONE;
9928 }
9929 })
9930
9931 (define_expand "div<mode>3"
9932 [(set (match_operand:MODEF 0 "register_operand")
9933 (div:MODEF (match_operand:MODEF 1 "register_operand")
9934 (match_operand:MODEF 2 "nonimmediate_operand")))]
9935 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9936 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9937 {
9938 if (<MODE>mode == SFmode
9939 && TARGET_SSE && TARGET_SSE_MATH
9940 && TARGET_RECIP_DIV
9941 && optimize_insn_for_speed_p ()
9942 && flag_finite_math_only && !flag_trapping_math
9943 && flag_unsafe_math_optimizations)
9944 {
9945 ix86_emit_swdivsf (operands[0], operands[1],
9946 operands[2], SFmode);
9947 DONE;
9948 }
9949 })
9950 \f
9951 ;; Divmod instructions.
9952
9953 (define_code_iterator any_div [div udiv])
9954 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
9955
9956 (define_expand "<u>divmod<mode>4"
9957 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9958 (any_div:SWIM248
9959 (match_operand:SWIM248 1 "register_operand")
9960 (match_operand:SWIM248 2 "nonimmediate_operand")))
9961 (set (match_operand:SWIM248 3 "register_operand")
9962 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
9963 (clobber (reg:CC FLAGS_REG))])])
9964
9965 ;; Split with 8bit unsigned divide:
9966 ;; if (dividend an divisor are in [0-255])
9967 ;; use 8bit unsigned integer divide
9968 ;; else
9969 ;; use original integer divide
9970 (define_split
9971 [(set (match_operand:SWI48 0 "register_operand")
9972 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
9973 (match_operand:SWI48 3 "nonimmediate_operand")))
9974 (set (match_operand:SWI48 1 "register_operand")
9975 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
9976 (clobber (reg:CC FLAGS_REG))]
9977 "TARGET_USE_8BIT_IDIV
9978 && TARGET_QIMODE_MATH
9979 && can_create_pseudo_p ()
9980 && !optimize_insn_for_size_p ()"
9981 [(const_int 0)]
9982 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
9983
9984 (define_split
9985 [(set (match_operand:DI 0 "register_operand")
9986 (zero_extend:DI
9987 (any_div:SI (match_operand:SI 2 "register_operand")
9988 (match_operand:SI 3 "nonimmediate_operand"))))
9989 (set (match_operand:SI 1 "register_operand")
9990 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
9991 (clobber (reg:CC FLAGS_REG))]
9992 "TARGET_64BIT
9993 && TARGET_USE_8BIT_IDIV
9994 && TARGET_QIMODE_MATH
9995 && can_create_pseudo_p ()
9996 && !optimize_insn_for_size_p ()"
9997 [(const_int 0)]
9998 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
9999
10000 (define_split
10001 [(set (match_operand:DI 1 "register_operand")
10002 (zero_extend:DI
10003 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
10004 (match_operand:SI 3 "nonimmediate_operand"))))
10005 (set (match_operand:SI 0 "register_operand")
10006 (any_div:SI (match_dup 2) (match_dup 3)))
10007 (clobber (reg:CC FLAGS_REG))]
10008 "TARGET_64BIT
10009 && TARGET_USE_8BIT_IDIV
10010 && TARGET_QIMODE_MATH
10011 && can_create_pseudo_p ()
10012 && !optimize_insn_for_size_p ()"
10013 [(const_int 0)]
10014 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
10015
10016 (define_insn_and_split "divmod<mode>4_1"
10017 [(set (match_operand:SWI48 0 "register_operand" "=a")
10018 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10019 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10020 (set (match_operand:SWI48 1 "register_operand" "=&d")
10021 (mod:SWI48 (match_dup 2) (match_dup 3)))
10022 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10023 (clobber (reg:CC FLAGS_REG))]
10024 ""
10025 "#"
10026 "reload_completed"
10027 [(parallel [(set (match_dup 1)
10028 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
10029 (clobber (reg:CC FLAGS_REG))])
10030 (parallel [(set (match_dup 0)
10031 (div:SWI48 (match_dup 2) (match_dup 3)))
10032 (set (match_dup 1)
10033 (mod:SWI48 (match_dup 2) (match_dup 3)))
10034 (use (match_dup 1))
10035 (clobber (reg:CC FLAGS_REG))])]
10036 {
10037 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10038
10039 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10040 operands[4] = operands[2];
10041 else
10042 {
10043 /* Avoid use of cltd in favor of a mov+shift. */
10044 emit_move_insn (operands[1], operands[2]);
10045 operands[4] = operands[1];
10046 }
10047 }
10048 [(set_attr "type" "multi")
10049 (set_attr "mode" "<MODE>")])
10050
10051 (define_insn_and_split "udivmod<mode>4_1"
10052 [(set (match_operand:SWI48 0 "register_operand" "=a")
10053 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10054 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10055 (set (match_operand:SWI48 1 "register_operand" "=&d")
10056 (umod:SWI48 (match_dup 2) (match_dup 3)))
10057 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10058 (clobber (reg:CC FLAGS_REG))]
10059 ""
10060 "#"
10061 "reload_completed"
10062 [(set (match_dup 1) (const_int 0))
10063 (parallel [(set (match_dup 0)
10064 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10065 (set (match_dup 1)
10066 (umod:SWI48 (match_dup 2) (match_dup 3)))
10067 (use (match_dup 1))
10068 (clobber (reg:CC FLAGS_REG))])]
10069 ""
10070 [(set_attr "type" "multi")
10071 (set_attr "mode" "<MODE>")])
10072
10073 (define_insn_and_split "divmodsi4_zext_1"
10074 [(set (match_operand:DI 0 "register_operand" "=a")
10075 (zero_extend:DI
10076 (div:SI (match_operand:SI 2 "register_operand" "0")
10077 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10078 (set (match_operand:SI 1 "register_operand" "=&d")
10079 (mod:SI (match_dup 2) (match_dup 3)))
10080 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10081 (clobber (reg:CC FLAGS_REG))]
10082 "TARGET_64BIT"
10083 "#"
10084 "&& reload_completed"
10085 [(parallel [(set (match_dup 1)
10086 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10087 (clobber (reg:CC FLAGS_REG))])
10088 (parallel [(set (match_dup 0)
10089 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10090 (set (match_dup 1)
10091 (mod:SI (match_dup 2) (match_dup 3)))
10092 (use (match_dup 1))
10093 (clobber (reg:CC FLAGS_REG))])]
10094 {
10095 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10096
10097 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10098 operands[4] = operands[2];
10099 else
10100 {
10101 /* Avoid use of cltd in favor of a mov+shift. */
10102 emit_move_insn (operands[1], operands[2]);
10103 operands[4] = operands[1];
10104 }
10105 }
10106 [(set_attr "type" "multi")
10107 (set_attr "mode" "SI")])
10108
10109 (define_insn_and_split "udivmodsi4_zext_1"
10110 [(set (match_operand:DI 0 "register_operand" "=a")
10111 (zero_extend:DI
10112 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10113 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10114 (set (match_operand:SI 1 "register_operand" "=&d")
10115 (umod:SI (match_dup 2) (match_dup 3)))
10116 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10117 (clobber (reg:CC FLAGS_REG))]
10118 "TARGET_64BIT"
10119 "#"
10120 "&& reload_completed"
10121 [(set (match_dup 1) (const_int 0))
10122 (parallel [(set (match_dup 0)
10123 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10124 (set (match_dup 1)
10125 (umod:SI (match_dup 2) (match_dup 3)))
10126 (use (match_dup 1))
10127 (clobber (reg:CC FLAGS_REG))])]
10128 ""
10129 [(set_attr "type" "multi")
10130 (set_attr "mode" "SI")])
10131
10132 (define_insn_and_split "divmodsi4_zext_2"
10133 [(set (match_operand:DI 1 "register_operand" "=&d")
10134 (zero_extend:DI
10135 (mod:SI (match_operand:SI 2 "register_operand" "0")
10136 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10137 (set (match_operand:SI 0 "register_operand" "=a")
10138 (div:SI (match_dup 2) (match_dup 3)))
10139 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10140 (clobber (reg:CC FLAGS_REG))]
10141 "TARGET_64BIT"
10142 "#"
10143 "&& reload_completed"
10144 [(parallel [(set (match_dup 6)
10145 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10146 (clobber (reg:CC FLAGS_REG))])
10147 (parallel [(set (match_dup 1)
10148 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10149 (set (match_dup 0)
10150 (div:SI (match_dup 2) (match_dup 3)))
10151 (use (match_dup 6))
10152 (clobber (reg:CC FLAGS_REG))])]
10153 {
10154 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10155 operands[6] = gen_lowpart (SImode, operands[1]);
10156
10157 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10158 operands[4] = operands[2];
10159 else
10160 {
10161 /* Avoid use of cltd in favor of a mov+shift. */
10162 emit_move_insn (operands[6], operands[2]);
10163 operands[4] = operands[6];
10164 }
10165 }
10166 [(set_attr "type" "multi")
10167 (set_attr "mode" "SI")])
10168
10169 (define_insn_and_split "udivmodsi4_zext_2"
10170 [(set (match_operand:DI 1 "register_operand" "=&d")
10171 (zero_extend:DI
10172 (umod:SI (match_operand:SI 2 "register_operand" "0")
10173 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10174 (set (match_operand:SI 0 "register_operand" "=a")
10175 (udiv:SI (match_dup 2) (match_dup 3)))
10176 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10177 (clobber (reg:CC FLAGS_REG))]
10178 "TARGET_64BIT"
10179 "#"
10180 "&& reload_completed"
10181 [(set (match_dup 4) (const_int 0))
10182 (parallel [(set (match_dup 1)
10183 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10184 (set (match_dup 0)
10185 (udiv:SI (match_dup 2) (match_dup 3)))
10186 (use (match_dup 4))
10187 (clobber (reg:CC FLAGS_REG))])]
10188 "operands[4] = gen_lowpart (SImode, operands[1]);"
10189 [(set_attr "type" "multi")
10190 (set_attr "mode" "SI")])
10191
10192 (define_insn_and_split "*divmod<mode>4"
10193 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10194 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10195 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10196 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10197 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10198 (clobber (reg:CC FLAGS_REG))]
10199 ""
10200 "#"
10201 "reload_completed"
10202 [(parallel [(set (match_dup 1)
10203 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10204 (clobber (reg:CC FLAGS_REG))])
10205 (parallel [(set (match_dup 0)
10206 (div:SWIM248 (match_dup 2) (match_dup 3)))
10207 (set (match_dup 1)
10208 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10209 (use (match_dup 1))
10210 (clobber (reg:CC FLAGS_REG))])]
10211 {
10212 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10213
10214 if (<MODE>mode != HImode
10215 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10216 operands[4] = operands[2];
10217 else
10218 {
10219 /* Avoid use of cltd in favor of a mov+shift. */
10220 emit_move_insn (operands[1], operands[2]);
10221 operands[4] = operands[1];
10222 }
10223 }
10224 [(set_attr "type" "multi")
10225 (set_attr "mode" "<MODE>")])
10226
10227 (define_insn_and_split "*udivmod<mode>4"
10228 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10229 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10230 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10231 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10232 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10233 (clobber (reg:CC FLAGS_REG))]
10234 ""
10235 "#"
10236 "reload_completed"
10237 [(set (match_dup 1) (const_int 0))
10238 (parallel [(set (match_dup 0)
10239 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10240 (set (match_dup 1)
10241 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10242 (use (match_dup 1))
10243 (clobber (reg:CC FLAGS_REG))])]
10244 ""
10245 [(set_attr "type" "multi")
10246 (set_attr "mode" "<MODE>")])
10247
10248 ;; Optimize division or modulo by constant power of 2, if the constant
10249 ;; materializes only after expansion.
10250 (define_insn_and_split "*udivmod<mode>4_pow2"
10251 [(set (match_operand:SWI48 0 "register_operand" "=r")
10252 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10253 (match_operand:SWI48 3 "const_int_operand")))
10254 (set (match_operand:SWI48 1 "register_operand" "=r")
10255 (umod:SWI48 (match_dup 2) (match_dup 3)))
10256 (clobber (reg:CC FLAGS_REG))]
10257 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10258 "#"
10259 "&& reload_completed"
10260 [(set (match_dup 1) (match_dup 2))
10261 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10262 (clobber (reg:CC FLAGS_REG))])
10263 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10264 (clobber (reg:CC FLAGS_REG))])]
10265 {
10266 int v = exact_log2 (UINTVAL (operands[3]));
10267 operands[4] = GEN_INT (v);
10268 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10269 }
10270 [(set_attr "type" "multi")
10271 (set_attr "mode" "<MODE>")])
10272
10273 (define_insn_and_split "*divmodsi4_zext_1"
10274 [(set (match_operand:DI 0 "register_operand" "=a")
10275 (zero_extend:DI
10276 (div:SI (match_operand:SI 2 "register_operand" "0")
10277 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10278 (set (match_operand:SI 1 "register_operand" "=&d")
10279 (mod:SI (match_dup 2) (match_dup 3)))
10280 (clobber (reg:CC FLAGS_REG))]
10281 "TARGET_64BIT"
10282 "#"
10283 "&& reload_completed"
10284 [(parallel [(set (match_dup 1)
10285 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10286 (clobber (reg:CC FLAGS_REG))])
10287 (parallel [(set (match_dup 0)
10288 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10289 (set (match_dup 1)
10290 (mod:SI (match_dup 2) (match_dup 3)))
10291 (use (match_dup 1))
10292 (clobber (reg:CC FLAGS_REG))])]
10293 {
10294 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10295
10296 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10297 operands[4] = operands[2];
10298 else
10299 {
10300 /* Avoid use of cltd in favor of a mov+shift. */
10301 emit_move_insn (operands[1], operands[2]);
10302 operands[4] = operands[1];
10303 }
10304 }
10305 [(set_attr "type" "multi")
10306 (set_attr "mode" "SI")])
10307
10308 (define_insn_and_split "*udivmodsi4_zext_1"
10309 [(set (match_operand:DI 0 "register_operand" "=a")
10310 (zero_extend:DI
10311 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10312 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10313 (set (match_operand:SI 1 "register_operand" "=&d")
10314 (umod:SI (match_dup 2) (match_dup 3)))
10315 (clobber (reg:CC FLAGS_REG))]
10316 "TARGET_64BIT"
10317 "#"
10318 "&& reload_completed"
10319 [(set (match_dup 1) (const_int 0))
10320 (parallel [(set (match_dup 0)
10321 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10322 (set (match_dup 1)
10323 (umod:SI (match_dup 2) (match_dup 3)))
10324 (use (match_dup 1))
10325 (clobber (reg:CC FLAGS_REG))])]
10326 ""
10327 [(set_attr "type" "multi")
10328 (set_attr "mode" "SI")])
10329
10330 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10331 [(set (match_operand:DI 0 "register_operand" "=r")
10332 (zero_extend:DI
10333 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10334 (match_operand:SI 3 "const_int_operand"))))
10335 (set (match_operand:SI 1 "register_operand" "=r")
10336 (umod:SI (match_dup 2) (match_dup 3)))
10337 (clobber (reg:CC FLAGS_REG))]
10338 "TARGET_64BIT
10339 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10340 "#"
10341 "&& reload_completed"
10342 [(set (match_dup 1) (match_dup 2))
10343 (parallel [(set (match_dup 0)
10344 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10345 (clobber (reg:CC FLAGS_REG))])
10346 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10347 (clobber (reg:CC FLAGS_REG))])]
10348 {
10349 int v = exact_log2 (UINTVAL (operands[3]));
10350 operands[4] = GEN_INT (v);
10351 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10352 }
10353 [(set_attr "type" "multi")
10354 (set_attr "mode" "SI")])
10355
10356 (define_insn_and_split "*divmodsi4_zext_2"
10357 [(set (match_operand:DI 1 "register_operand" "=&d")
10358 (zero_extend:DI
10359 (mod:SI (match_operand:SI 2 "register_operand" "0")
10360 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10361 (set (match_operand:SI 0 "register_operand" "=a")
10362 (div:SI (match_dup 2) (match_dup 3)))
10363 (clobber (reg:CC FLAGS_REG))]
10364 "TARGET_64BIT"
10365 "#"
10366 "&& reload_completed"
10367 [(parallel [(set (match_dup 6)
10368 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10369 (clobber (reg:CC FLAGS_REG))])
10370 (parallel [(set (match_dup 1)
10371 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10372 (set (match_dup 0)
10373 (div:SI (match_dup 2) (match_dup 3)))
10374 (use (match_dup 6))
10375 (clobber (reg:CC FLAGS_REG))])]
10376 {
10377 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10378 operands[6] = gen_lowpart (SImode, operands[1]);
10379
10380 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10381 operands[4] = operands[2];
10382 else
10383 {
10384 /* Avoid use of cltd in favor of a mov+shift. */
10385 emit_move_insn (operands[6], operands[2]);
10386 operands[4] = operands[6];
10387 }
10388 }
10389 [(set_attr "type" "multi")
10390 (set_attr "mode" "SI")])
10391
10392 (define_insn_and_split "*udivmodsi4_zext_2"
10393 [(set (match_operand:DI 1 "register_operand" "=&d")
10394 (zero_extend:DI
10395 (umod:SI (match_operand:SI 2 "register_operand" "0")
10396 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10397 (set (match_operand:SI 0 "register_operand" "=a")
10398 (udiv:SI (match_dup 2) (match_dup 3)))
10399 (clobber (reg:CC FLAGS_REG))]
10400 "TARGET_64BIT"
10401 "#"
10402 "&& reload_completed"
10403 [(set (match_dup 4) (const_int 0))
10404 (parallel [(set (match_dup 1)
10405 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10406 (set (match_dup 0)
10407 (udiv:SI (match_dup 2) (match_dup 3)))
10408 (use (match_dup 4))
10409 (clobber (reg:CC FLAGS_REG))])]
10410 "operands[4] = gen_lowpart (SImode, operands[1]);"
10411 [(set_attr "type" "multi")
10412 (set_attr "mode" "SI")])
10413
10414 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10415 [(set (match_operand:DI 1 "register_operand" "=r")
10416 (zero_extend:DI
10417 (umod:SI (match_operand:SI 2 "register_operand" "0")
10418 (match_operand:SI 3 "const_int_operand"))))
10419 (set (match_operand:SI 0 "register_operand" "=r")
10420 (udiv:SI (match_dup 2) (match_dup 3)))
10421 (clobber (reg:CC FLAGS_REG))]
10422 "TARGET_64BIT
10423 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10424 "#"
10425 "&& reload_completed"
10426 [(set (match_dup 1) (match_dup 2))
10427 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10428 (clobber (reg:CC FLAGS_REG))])
10429 (parallel [(set (match_dup 1)
10430 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10431 (clobber (reg:CC FLAGS_REG))])]
10432 {
10433 int v = exact_log2 (UINTVAL (operands[3]));
10434 operands[4] = GEN_INT (v);
10435 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10436 }
10437 [(set_attr "type" "multi")
10438 (set_attr "mode" "SI")])
10439
10440 (define_insn "*<u>divmod<mode>4_noext"
10441 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10442 (any_div:SWIM248
10443 (match_operand:SWIM248 2 "register_operand" "0")
10444 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10445 (set (match_operand:SWIM248 1 "register_operand" "=d")
10446 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10447 (use (match_operand:SWIM248 4 "register_operand" "1"))
10448 (clobber (reg:CC FLAGS_REG))]
10449 ""
10450 "<sgnprefix>div{<imodesuffix>}\t%3"
10451 [(set_attr "type" "idiv")
10452 (set_attr "mode" "<MODE>")])
10453
10454 (define_insn "*<u>divmodsi4_noext_zext_1"
10455 [(set (match_operand:DI 0 "register_operand" "=a")
10456 (zero_extend:DI
10457 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10458 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10459 (set (match_operand:SI 1 "register_operand" "=d")
10460 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10461 (use (match_operand:SI 4 "register_operand" "1"))
10462 (clobber (reg:CC FLAGS_REG))]
10463 "TARGET_64BIT"
10464 "<sgnprefix>div{l}\t%3"
10465 [(set_attr "type" "idiv")
10466 (set_attr "mode" "SI")])
10467
10468 (define_insn "*<u>divmodsi4_noext_zext_2"
10469 [(set (match_operand:DI 1 "register_operand" "=d")
10470 (zero_extend:DI
10471 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10472 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10473 (set (match_operand:SI 0 "register_operand" "=a")
10474 (any_div:SI (match_dup 2) (match_dup 3)))
10475 (use (match_operand:SI 4 "register_operand" "1"))
10476 (clobber (reg:CC FLAGS_REG))]
10477 "TARGET_64BIT"
10478 "<sgnprefix>div{l}\t%3"
10479 [(set_attr "type" "idiv")
10480 (set_attr "mode" "SI")])
10481
10482 ;; Avoid sign-extension (using cdq) for constant numerators.
10483 (define_insn_and_split "*divmodsi4_const"
10484 [(set (match_operand:SI 0 "register_operand" "=&a")
10485 (div:SI (match_operand:SI 2 "const_int_operand")
10486 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10487 (set (match_operand:SI 1 "register_operand" "=&d")
10488 (mod:SI (match_dup 2) (match_dup 3)))
10489 (clobber (reg:CC FLAGS_REG))]
10490 "!optimize_function_for_size_p (cfun)"
10491 "#"
10492 "&& reload_completed"
10493 [(set (match_dup 0) (match_dup 2))
10494 (set (match_dup 1) (match_dup 4))
10495 (parallel [(set (match_dup 0)
10496 (div:SI (match_dup 0) (match_dup 3)))
10497 (set (match_dup 1)
10498 (mod:SI (match_dup 0) (match_dup 3)))
10499 (use (match_dup 1))
10500 (clobber (reg:CC FLAGS_REG))])]
10501 {
10502 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10503 }
10504 [(set_attr "type" "multi")
10505 (set_attr "mode" "SI")])
10506
10507 (define_expand "divmodqi4"
10508 [(parallel [(set (match_operand:QI 0 "register_operand")
10509 (div:QI
10510 (match_operand:QI 1 "register_operand")
10511 (match_operand:QI 2 "nonimmediate_operand")))
10512 (set (match_operand:QI 3 "register_operand")
10513 (mod:QI (match_dup 1) (match_dup 2)))
10514 (clobber (reg:CC FLAGS_REG))])]
10515 "TARGET_QIMODE_MATH"
10516 {
10517 rtx div, mod;
10518 rtx tmp0, tmp1;
10519
10520 tmp0 = gen_reg_rtx (HImode);
10521 tmp1 = gen_reg_rtx (HImode);
10522
10523 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10524 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10525 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10526
10527 /* Extract remainder from AH. */
10528 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10529 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10530 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10531
10532 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10533 set_unique_reg_note (insn, REG_EQUAL, mod);
10534
10535 /* Extract quotient from AL. */
10536 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10537
10538 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10539 set_unique_reg_note (insn, REG_EQUAL, div);
10540
10541 DONE;
10542 })
10543
10544 (define_expand "udivmodqi4"
10545 [(parallel [(set (match_operand:QI 0 "register_operand")
10546 (udiv:QI
10547 (match_operand:QI 1 "register_operand")
10548 (match_operand:QI 2 "nonimmediate_operand")))
10549 (set (match_operand:QI 3 "register_operand")
10550 (umod:QI (match_dup 1) (match_dup 2)))
10551 (clobber (reg:CC FLAGS_REG))])]
10552 "TARGET_QIMODE_MATH"
10553 {
10554 rtx div, mod;
10555 rtx tmp0, tmp1;
10556
10557 tmp0 = gen_reg_rtx (HImode);
10558 tmp1 = gen_reg_rtx (HImode);
10559
10560 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10561 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10562 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10563
10564 /* Extract remainder from AH. */
10565 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10566 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10567 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10568
10569 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10570 set_unique_reg_note (insn, REG_EQUAL, mod);
10571
10572 /* Extract quotient from AL. */
10573 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10574
10575 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10576 set_unique_reg_note (insn, REG_EQUAL, div);
10577
10578 DONE;
10579 })
10580
10581 ;; Divide AX by r/m8, with result stored in
10582 ;; AL <- Quotient
10583 ;; AH <- Remainder
10584 ;; Change div/mod to HImode and extend the second argument to HImode
10585 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10586 ;; combine may fail.
10587 (define_insn "<u>divmodhiqi3"
10588 [(set (match_operand:HI 0 "register_operand" "=a")
10589 (ior:HI
10590 (ashift:HI
10591 (zero_extend:HI
10592 (truncate:QI
10593 (mod:HI (match_operand:HI 1 "register_operand" "0")
10594 (any_extend:HI
10595 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10596 (const_int 8))
10597 (zero_extend:HI
10598 (truncate:QI
10599 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10600 (clobber (reg:CC FLAGS_REG))]
10601 "TARGET_QIMODE_MATH"
10602 "<sgnprefix>div{b}\t%2"
10603 [(set_attr "type" "idiv")
10604 (set_attr "mode" "QI")])
10605
10606 ;; We cannot use div/idiv for double division, because it causes
10607 ;; "division by zero" on the overflow and that's not what we expect
10608 ;; from truncate. Because true (non truncating) double division is
10609 ;; never generated, we can't create this insn anyway.
10610 ;
10611 ;(define_insn ""
10612 ; [(set (match_operand:SI 0 "register_operand" "=a")
10613 ; (truncate:SI
10614 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10615 ; (zero_extend:DI
10616 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10617 ; (set (match_operand:SI 3 "register_operand" "=d")
10618 ; (truncate:SI
10619 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10620 ; (clobber (reg:CC FLAGS_REG))]
10621 ; ""
10622 ; "div{l}\t{%2, %0|%0, %2}"
10623 ; [(set_attr "type" "idiv")])
10624 \f
10625 ;;- Logical AND instructions
10626
10627 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10628 ;; Note that this excludes ah.
10629
10630 (define_expand "@test<mode>_ccno_1"
10631 [(set (reg:CCNO FLAGS_REG)
10632 (compare:CCNO
10633 (and:SWI48
10634 (match_operand:SWI48 0 "nonimmediate_operand")
10635 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10636 (const_int 0)))])
10637
10638 (define_expand "testqi_ccz_1"
10639 [(set (reg:CCZ FLAGS_REG)
10640 (compare:CCZ
10641 (and:QI
10642 (match_operand:QI 0 "nonimmediate_operand")
10643 (match_operand:QI 1 "nonmemory_operand"))
10644 (const_int 0)))])
10645
10646 (define_insn "*testdi_1"
10647 [(set (reg FLAGS_REG)
10648 (compare
10649 (and:DI
10650 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10651 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10652 (const_int 0)))]
10653 "TARGET_64BIT
10654 && ix86_match_ccmode
10655 (insn,
10656 /* If we are going to emit testl instead of testq, and the operands[1]
10657 constant might have the SImode sign bit set, make sure the sign
10658 flag isn't tested, because the instruction will set the sign flag
10659 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10660 conservatively assume it might have bit 31 set. */
10661 (satisfies_constraint_Z (operands[1])
10662 && (!CONST_INT_P (operands[1])
10663 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10664 ? CCZmode : CCNOmode)"
10665 "@
10666 test{l}\t{%k1, %k0|%k0, %k1}
10667 test{q}\t{%1, %0|%0, %1}"
10668 [(set_attr "type" "test")
10669 (set_attr "mode" "SI,DI")])
10670
10671 (define_insn "*testqi_1_maybe_si"
10672 [(set (reg FLAGS_REG)
10673 (compare
10674 (and:QI
10675 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10676 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10677 (const_int 0)))]
10678 "ix86_match_ccmode (insn,
10679 CONST_INT_P (operands[1])
10680 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10681 {
10682 if (get_attr_mode (insn) == MODE_SI)
10683 {
10684 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10685 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10686 return "test{l}\t{%1, %k0|%k0, %1}";
10687 }
10688 return "test{b}\t{%1, %0|%0, %1}";
10689 }
10690 [(set_attr "type" "test")
10691 (set (attr "mode")
10692 (cond [(eq_attr "alternative" "2")
10693 (const_string "SI")
10694 (and (match_test "optimize_insn_for_size_p ()")
10695 (and (match_operand 0 "ext_QIreg_operand")
10696 (match_operand 1 "const_0_to_127_operand")))
10697 (const_string "SI")
10698 ]
10699 (const_string "QI")))
10700 (set_attr "pent_pair" "uv,np,np")])
10701
10702 (define_insn "*test<mode>_1"
10703 [(set (reg FLAGS_REG)
10704 (compare
10705 (and:SWI124
10706 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10707 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10708 (const_int 0)))]
10709 "ix86_match_ccmode (insn, CCNOmode)"
10710 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10711 [(set_attr "type" "test")
10712 (set_attr "mode" "<MODE>")
10713 (set_attr "pent_pair" "uv,uv,np")])
10714
10715 (define_expand "testqi_ext_1_ccno"
10716 [(set (reg:CCNO FLAGS_REG)
10717 (compare:CCNO
10718 (and:QI
10719 (subreg:QI
10720 (zero_extract:HI
10721 (match_operand:HI 0 "register_operand")
10722 (const_int 8)
10723 (const_int 8)) 0)
10724 (match_operand:QI 1 "const_int_operand"))
10725 (const_int 0)))])
10726
10727 (define_insn "*testqi_ext<mode>_1"
10728 [(set (reg FLAGS_REG)
10729 (compare
10730 (and:QI
10731 (subreg:QI
10732 (match_operator:SWI248 2 "extract_operator"
10733 [(match_operand 0 "int248_register_operand" "Q,Q")
10734 (const_int 8)
10735 (const_int 8)]) 0)
10736 (match_operand:QI 1 "general_x64constmem_operand" "QnBc,m"))
10737 (const_int 0)))]
10738 "ix86_match_ccmode (insn, CCNOmode)"
10739 "test{b}\t{%1, %h0|%h0, %1}"
10740 [(set_attr "isa" "*,nox64")
10741 (set_attr "type" "test")
10742 (set_attr "mode" "QI")])
10743
10744 (define_insn "*testqi_ext<mode>_2"
10745 [(set (reg FLAGS_REG)
10746 (compare
10747 (and:QI
10748 (subreg:QI
10749 (match_operator:SWI248 2 "extract_operator"
10750 [(match_operand 0 "int248_register_operand" "Q")
10751 (const_int 8)
10752 (const_int 8)]) 0)
10753 (subreg:QI
10754 (match_operator:SWI248 3 "extract_operator"
10755 [(match_operand 1 "int248_register_operand" "Q")
10756 (const_int 8)
10757 (const_int 8)]) 0))
10758 (const_int 0)))]
10759 "ix86_match_ccmode (insn, CCNOmode)"
10760 "test{b}\t{%h1, %h0|%h0, %h1}"
10761 [(set_attr "type" "test")
10762 (set_attr "mode" "QI")])
10763
10764 ;; Provide a *testti instruction that STV can implement using ptest.
10765 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10766 (define_insn_and_split "*testti_doubleword"
10767 [(set (reg:CCZ FLAGS_REG)
10768 (compare:CCZ
10769 (and:TI (match_operand:TI 0 "register_operand")
10770 (match_operand:TI 1 "general_operand"))
10771 (const_int 0)))]
10772 "TARGET_64BIT
10773 && ix86_pre_reload_split ()"
10774 "#"
10775 "&& 1"
10776 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10777 (clobber (reg:CC FLAGS_REG))])
10778 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10779 {
10780 operands[2] = gen_reg_rtx (TImode);
10781 if (!x86_64_hilo_general_operand (operands[1], TImode))
10782 operands[1] = force_reg (TImode, operands[1]);
10783 })
10784
10785 ;; Combine likes to form bit extractions for some tests. Humor it.
10786 (define_insn_and_split "*testqi_ext_3"
10787 [(set (match_operand 0 "flags_reg_operand")
10788 (match_operator 1 "compare_operator"
10789 [(zero_extract:SWI248
10790 (match_operand 2 "int_nonimmediate_operand" "rm")
10791 (match_operand 3 "const_int_operand")
10792 (match_operand 4 "const_int_operand"))
10793 (const_int 0)]))]
10794 "/* Ensure that resulting mask is zero or sign extended operand. */
10795 INTVAL (operands[4]) >= 0
10796 && ((INTVAL (operands[3]) > 0
10797 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
10798 || (<MODE>mode == DImode
10799 && INTVAL (operands[3]) > 32
10800 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
10801 && ix86_match_ccmode (insn,
10802 /* If zero_extract mode precision is the same
10803 as len, the SF of the zero_extract
10804 comparison will be the most significant
10805 extracted bit, but this could be matched
10806 after splitting only for pos 0 len all bits
10807 trivial extractions. Require CCZmode. */
10808 (GET_MODE_PRECISION (<MODE>mode)
10809 == INTVAL (operands[3]))
10810 /* Otherwise, require CCZmode if we'd use a mask
10811 with the most significant bit set and can't
10812 widen it to wider mode. *testdi_1 also
10813 requires CCZmode if the mask has bit
10814 31 set and all bits above it clear. */
10815 || (INTVAL (operands[3]) + INTVAL (operands[4])
10816 >= 32)
10817 /* We can't widen also if val is not a REG. */
10818 || (INTVAL (operands[3]) + INTVAL (operands[4])
10819 == GET_MODE_PRECISION (GET_MODE (operands[2]))
10820 && !register_operand (operands[2],
10821 GET_MODE (operands[2])))
10822 /* And we shouldn't widen if
10823 TARGET_PARTIAL_REG_STALL. */
10824 || (TARGET_PARTIAL_REG_STALL
10825 && (INTVAL (operands[3]) + INTVAL (operands[4])
10826 >= (paradoxical_subreg_p (operands[2])
10827 && (GET_MODE_CLASS
10828 (GET_MODE (SUBREG_REG (operands[2])))
10829 == MODE_INT)
10830 ? GET_MODE_PRECISION
10831 (GET_MODE (SUBREG_REG (operands[2])))
10832 : GET_MODE_PRECISION
10833 (GET_MODE (operands[2])))))
10834 ? CCZmode : CCNOmode)"
10835 "#"
10836 "&& 1"
10837 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10838 {
10839 rtx val = operands[2];
10840 HOST_WIDE_INT len = INTVAL (operands[3]);
10841 HOST_WIDE_INT pos = INTVAL (operands[4]);
10842 machine_mode mode = GET_MODE (val);
10843
10844 if (SUBREG_P (val))
10845 {
10846 machine_mode submode = GET_MODE (SUBREG_REG (val));
10847
10848 /* Narrow paradoxical subregs to prevent partial register stalls. */
10849 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
10850 && GET_MODE_CLASS (submode) == MODE_INT
10851 && (GET_MODE (operands[0]) == CCZmode
10852 || pos + len < GET_MODE_PRECISION (submode)
10853 || REG_P (SUBREG_REG (val))))
10854 {
10855 val = SUBREG_REG (val);
10856 mode = submode;
10857 }
10858 }
10859
10860 /* Small HImode tests can be converted to QImode. */
10861 if (pos + len <= 8
10862 && register_operand (val, HImode))
10863 {
10864 rtx nval = gen_lowpart (QImode, val);
10865 if (!MEM_P (nval)
10866 || GET_MODE (operands[0]) == CCZmode
10867 || pos + len < 8)
10868 {
10869 val = nval;
10870 mode = QImode;
10871 }
10872 }
10873
10874 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
10875
10876 /* If the mask is going to have the sign bit set in the mode
10877 we want to do the comparison in and user isn't interested just
10878 in the zero flag, then we must widen the target mode. */
10879 if (pos + len == GET_MODE_PRECISION (mode)
10880 && GET_MODE (operands[0]) != CCZmode)
10881 {
10882 gcc_assert (pos + len < 32 && !MEM_P (val));
10883 mode = SImode;
10884 val = gen_lowpart (mode, val);
10885 }
10886
10887 wide_int mask
10888 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
10889
10890 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
10891 })
10892
10893 ;; Split and;cmp (as optimized by combine) into not;test
10894 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
10895 (define_insn_and_split "*test<mode>_not"
10896 [(set (reg:CCZ FLAGS_REG)
10897 (compare:CCZ
10898 (and:SWI
10899 (not:SWI (match_operand:SWI 0 "register_operand"))
10900 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
10901 (const_int 0)))]
10902 "ix86_pre_reload_split ()
10903 && (!TARGET_BMI || !REG_P (operands[1]))"
10904 "#"
10905 "&& 1"
10906 [(set (match_dup 2) (not:SWI (match_dup 0)))
10907 (set (reg:CCZ FLAGS_REG)
10908 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
10909 (const_int 0)))]
10910 "operands[2] = gen_reg_rtx (<MODE>mode);")
10911
10912 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
10913 (define_insn_and_split "*test<mode>_not_doubleword"
10914 [(set (reg:CCZ FLAGS_REG)
10915 (compare:CCZ
10916 (and:DWI
10917 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
10918 (match_operand:DWI 1 "nonimmediate_operand"))
10919 (const_int 0)))]
10920 "ix86_pre_reload_split ()"
10921 "#"
10922 "&& 1"
10923 [(parallel
10924 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
10925 (clobber (reg:CC FLAGS_REG))])
10926 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10927 {
10928 operands[0] = force_reg (<MODE>mode, operands[0]);
10929 operands[2] = gen_reg_rtx (<MODE>mode);
10930 })
10931
10932 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
10933 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
10934 ;; this is relatively important trick.
10935 ;; Do the conversion only post-reload to avoid limiting of the register class
10936 ;; to QI regs.
10937 (define_split
10938 [(set (match_operand 0 "flags_reg_operand")
10939 (match_operator 1 "compare_operator"
10940 [(and (match_operand 2 "QIreg_operand")
10941 (match_operand 3 "const_int_operand"))
10942 (const_int 0)]))]
10943 "reload_completed
10944 && GET_MODE (operands[2]) != QImode
10945 && ((ix86_match_ccmode (insn, CCZmode)
10946 && !(INTVAL (operands[3]) & ~(255 << 8)))
10947 || (ix86_match_ccmode (insn, CCNOmode)
10948 && !(INTVAL (operands[3]) & ~(127 << 8))))"
10949 [(set (match_dup 0)
10950 (match_op_dup 1
10951 [(and:QI
10952 (subreg:QI
10953 (zero_extract:HI (match_dup 2)
10954 (const_int 8)
10955 (const_int 8)) 0)
10956 (match_dup 3))
10957 (const_int 0)]))]
10958 {
10959 operands[2] = gen_lowpart (HImode, operands[2]);
10960 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
10961 })
10962
10963 (define_split
10964 [(set (match_operand 0 "flags_reg_operand")
10965 (match_operator 1 "compare_operator"
10966 [(and (match_operand 2 "nonimmediate_operand")
10967 (match_operand 3 "const_int_operand"))
10968 (const_int 0)]))]
10969 "reload_completed
10970 && GET_MODE (operands[2]) != QImode
10971 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
10972 && ((ix86_match_ccmode (insn, CCZmode)
10973 && !(INTVAL (operands[3]) & ~255))
10974 || (ix86_match_ccmode (insn, CCNOmode)
10975 && !(INTVAL (operands[3]) & ~127)))"
10976 [(set (match_dup 0)
10977 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
10978 (const_int 0)]))]
10979 {
10980 operands[2] = gen_lowpart (QImode, operands[2]);
10981 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
10982 })
10983
10984 ;; %%% This used to optimize known byte-wide and operations to memory,
10985 ;; and sometimes to QImode registers. If this is considered useful,
10986 ;; it should be done with splitters.
10987
10988 (define_expand "and<mode>3"
10989 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
10990 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
10991 (match_operand:SDWIM 2 "<general_szext_operand>")))]
10992 ""
10993 {
10994 machine_mode mode = <MODE>mode;
10995
10996 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
10997 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
10998 operands[2] = force_reg (<MODE>mode, operands[2]);
10999
11000 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
11001 && const_int_operand (operands[2], <MODE>mode)
11002 && register_operand (operands[0], <MODE>mode)
11003 && !(TARGET_ZERO_EXTEND_WITH_AND
11004 && optimize_function_for_speed_p (cfun)))
11005 {
11006 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11007
11008 if (ival == GET_MODE_MASK (SImode))
11009 mode = SImode;
11010 else if (ival == GET_MODE_MASK (HImode))
11011 mode = HImode;
11012 else if (ival == GET_MODE_MASK (QImode))
11013 mode = QImode;
11014 }
11015
11016 if (mode != <MODE>mode)
11017 emit_insn (gen_extend_insn
11018 (operands[0], gen_lowpart (mode, operands[1]),
11019 <MODE>mode, mode, 1));
11020 else
11021 ix86_expand_binary_operator (AND, <MODE>mode, operands);
11022
11023 DONE;
11024 })
11025
11026 (define_insn_and_split "*and<dwi>3_doubleword"
11027 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11028 (and:<DWI>
11029 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11030 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11031 (clobber (reg:CC FLAGS_REG))]
11032 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11033 "#"
11034 "&& reload_completed"
11035 [(const_int:DWIH 0)]
11036 {
11037 bool emit_insn_deleted_note_p = false;
11038
11039 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11040
11041 if (operands[2] == const0_rtx)
11042 emit_move_insn (operands[0], const0_rtx);
11043 else if (operands[2] == constm1_rtx)
11044 emit_insn_deleted_note_p = true;
11045 else
11046 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11047
11048 if (operands[5] == const0_rtx)
11049 emit_move_insn (operands[3], const0_rtx);
11050 else if (operands[5] == constm1_rtx)
11051 {
11052 if (emit_insn_deleted_note_p)
11053 emit_note (NOTE_INSN_DELETED);
11054 }
11055 else
11056 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11057
11058 DONE;
11059 })
11060
11061 (define_insn "*anddi_1"
11062 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11063 (and:DI
11064 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11065 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11066 (clobber (reg:CC FLAGS_REG))]
11067 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11068 "@
11069 and{l}\t{%k2, %k0|%k0, %k2}
11070 and{q}\t{%2, %0|%0, %2}
11071 and{q}\t{%2, %0|%0, %2}
11072 #
11073 #"
11074 [(set_attr "isa" "x64,x64,x64,x64,avx512bw")
11075 (set_attr "type" "alu,alu,alu,imovx,msklog")
11076 (set_attr "length_immediate" "*,*,*,0,*")
11077 (set (attr "prefix_rex")
11078 (if_then_else
11079 (and (eq_attr "type" "imovx")
11080 (and (match_test "INTVAL (operands[2]) == 0xff")
11081 (match_operand 1 "ext_QIreg_operand")))
11082 (const_string "1")
11083 (const_string "*")))
11084 (set_attr "mode" "SI,DI,DI,SI,DI")])
11085
11086 (define_insn_and_split "*anddi_1_btr"
11087 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11088 (and:DI
11089 (match_operand:DI 1 "nonimmediate_operand" "%0")
11090 (match_operand:DI 2 "const_int_operand" "n")))
11091 (clobber (reg:CC FLAGS_REG))]
11092 "TARGET_64BIT && TARGET_USE_BT
11093 && ix86_binary_operator_ok (AND, DImode, operands)
11094 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11095 "#"
11096 "&& reload_completed"
11097 [(parallel [(set (zero_extract:DI (match_dup 0)
11098 (const_int 1)
11099 (match_dup 3))
11100 (const_int 0))
11101 (clobber (reg:CC FLAGS_REG))])]
11102 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11103 [(set_attr "type" "alu1")
11104 (set_attr "prefix_0f" "1")
11105 (set_attr "znver1_decode" "double")
11106 (set_attr "mode" "DI")])
11107
11108 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11109 (define_split
11110 [(set (match_operand:DI 0 "register_operand")
11111 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11112 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11113 (clobber (reg:CC FLAGS_REG))]
11114 "TARGET_64BIT"
11115 [(parallel [(set (match_dup 0)
11116 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11117 (clobber (reg:CC FLAGS_REG))])]
11118 {
11119 if (GET_CODE (operands[2]) == SYMBOL_REF
11120 || GET_CODE (operands[2]) == LABEL_REF)
11121 {
11122 operands[2] = shallow_copy_rtx (operands[2]);
11123 PUT_MODE (operands[2], SImode);
11124 }
11125 else if (GET_CODE (operands[2]) == CONST)
11126 {
11127 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11128 operands[2] = copy_rtx (operands[2]);
11129 PUT_MODE (operands[2], SImode);
11130 PUT_MODE (XEXP (operands[2], 0), SImode);
11131 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11132 }
11133 else
11134 operands[2] = gen_lowpart (SImode, operands[2]);
11135 })
11136
11137 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11138 (define_insn "*andsi_1_zext"
11139 [(set (match_operand:DI 0 "register_operand" "=r")
11140 (zero_extend:DI
11141 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11142 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11143 (clobber (reg:CC FLAGS_REG))]
11144 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11145 "and{l}\t{%2, %k0|%k0, %2}"
11146 [(set_attr "type" "alu")
11147 (set_attr "mode" "SI")])
11148
11149 (define_insn "*and<mode>_1"
11150 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11151 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11152 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11153 (clobber (reg:CC FLAGS_REG))]
11154 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11155 "@
11156 and{<imodesuffix>}\t{%2, %0|%0, %2}
11157 and{<imodesuffix>}\t{%2, %0|%0, %2}
11158 #
11159 #"
11160 [(set (attr "isa")
11161 (cond [(eq_attr "alternative" "3")
11162 (if_then_else (eq_attr "mode" "SI")
11163 (const_string "avx512bw")
11164 (const_string "avx512f"))
11165 ]
11166 (const_string "*")))
11167 (set_attr "type" "alu,alu,imovx,msklog")
11168 (set_attr "length_immediate" "*,*,0,*")
11169 (set (attr "prefix_rex")
11170 (if_then_else
11171 (and (eq_attr "type" "imovx")
11172 (and (match_test "INTVAL (operands[2]) == 0xff")
11173 (match_operand 1 "ext_QIreg_operand")))
11174 (const_string "1")
11175 (const_string "*")))
11176 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11177
11178 (define_insn "*andqi_1"
11179 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11180 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11181 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11182 (clobber (reg:CC FLAGS_REG))]
11183 "ix86_binary_operator_ok (AND, QImode, operands)"
11184 "@
11185 and{b}\t{%2, %0|%0, %2}
11186 and{b}\t{%2, %0|%0, %2}
11187 and{l}\t{%k2, %k0|%k0, %k2}
11188 #"
11189 [(set_attr "type" "alu,alu,alu,msklog")
11190 (set (attr "mode")
11191 (cond [(eq_attr "alternative" "2")
11192 (const_string "SI")
11193 (and (eq_attr "alternative" "3")
11194 (match_test "!TARGET_AVX512DQ"))
11195 (const_string "HI")
11196 ]
11197 (const_string "QI")))
11198 ;; Potential partial reg stall on alternative 2.
11199 (set (attr "preferred_for_speed")
11200 (cond [(eq_attr "alternative" "2")
11201 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11202 (symbol_ref "true")))])
11203
11204 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11205 (define_insn_and_split "*and<mode>_1_slp"
11206 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11207 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11208 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11209 (clobber (reg:CC FLAGS_REG))]
11210 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11211 "@
11212 and{<imodesuffix>}\t{%2, %0|%0, %2}
11213 #"
11214 "&& reload_completed"
11215 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11216 (parallel
11217 [(set (strict_low_part (match_dup 0))
11218 (and:SWI12 (match_dup 0) (match_dup 2)))
11219 (clobber (reg:CC FLAGS_REG))])]
11220 ""
11221 [(set_attr "type" "alu")
11222 (set_attr "mode" "<MODE>")])
11223
11224 (define_split
11225 [(set (match_operand:SWI248 0 "register_operand")
11226 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11227 (match_operand:SWI248 2 "const_int_operand")))
11228 (clobber (reg:CC FLAGS_REG))]
11229 "reload_completed
11230 && (!REG_P (operands[1])
11231 || REGNO (operands[0]) != REGNO (operands[1]))"
11232 [(const_int 0)]
11233 {
11234 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11235 machine_mode mode;
11236
11237 if (ival == GET_MODE_MASK (SImode))
11238 mode = SImode;
11239 else if (ival == GET_MODE_MASK (HImode))
11240 mode = HImode;
11241 else if (ival == GET_MODE_MASK (QImode))
11242 mode = QImode;
11243 else
11244 gcc_unreachable ();
11245
11246 /* Zero extend to SImode to avoid partial register stalls. */
11247 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11248 operands[0] = gen_lowpart (SImode, operands[0]);
11249
11250 emit_insn (gen_extend_insn
11251 (operands[0], gen_lowpart (mode, operands[1]),
11252 GET_MODE (operands[0]), mode, 1));
11253 DONE;
11254 })
11255
11256 (define_split
11257 [(set (match_operand:SWI48 0 "register_operand")
11258 (and:SWI48 (match_dup 0)
11259 (const_int -65536)))
11260 (clobber (reg:CC FLAGS_REG))]
11261 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11262 || optimize_function_for_size_p (cfun)"
11263 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11264 "operands[1] = gen_lowpart (HImode, operands[0]);")
11265
11266 (define_split
11267 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11268 (and:SWI248 (match_dup 0)
11269 (const_int -256)))
11270 (clobber (reg:CC FLAGS_REG))]
11271 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11272 && reload_completed"
11273 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11274 "operands[1] = gen_lowpart (QImode, operands[0]);")
11275
11276 (define_split
11277 [(set (match_operand:SWI248 0 "QIreg_operand")
11278 (and:SWI248 (match_dup 0)
11279 (const_int -65281)))
11280 (clobber (reg:CC FLAGS_REG))]
11281 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11282 && reload_completed"
11283 [(parallel
11284 [(set (zero_extract:HI (match_dup 0)
11285 (const_int 8)
11286 (const_int 8))
11287 (subreg:HI
11288 (xor:QI
11289 (subreg:QI
11290 (zero_extract:HI (match_dup 0)
11291 (const_int 8)
11292 (const_int 8)) 0)
11293 (subreg:QI
11294 (zero_extract:HI (match_dup 0)
11295 (const_int 8)
11296 (const_int 8)) 0)) 0))
11297 (clobber (reg:CC FLAGS_REG))])]
11298 "operands[0] = gen_lowpart (HImode, operands[0]);")
11299
11300 (define_insn "*anddi_2"
11301 [(set (reg FLAGS_REG)
11302 (compare
11303 (and:DI
11304 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11305 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11306 (const_int 0)))
11307 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11308 (and:DI (match_dup 1) (match_dup 2)))]
11309 "TARGET_64BIT
11310 && ix86_match_ccmode
11311 (insn,
11312 /* If we are going to emit andl instead of andq, and the operands[2]
11313 constant might have the SImode sign bit set, make sure the sign
11314 flag isn't tested, because the instruction will set the sign flag
11315 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11316 conservatively assume it might have bit 31 set. */
11317 (satisfies_constraint_Z (operands[2])
11318 && (!CONST_INT_P (operands[2])
11319 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11320 ? CCZmode : CCNOmode)
11321 && ix86_binary_operator_ok (AND, DImode, operands)"
11322 "@
11323 and{l}\t{%k2, %k0|%k0, %k2}
11324 and{q}\t{%2, %0|%0, %2}
11325 and{q}\t{%2, %0|%0, %2}"
11326 [(set_attr "type" "alu")
11327 (set_attr "mode" "SI,DI,DI")])
11328
11329 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11330 (define_insn "*andsi_2_zext"
11331 [(set (reg FLAGS_REG)
11332 (compare (and:SI
11333 (match_operand:SI 1 "nonimmediate_operand" "%0")
11334 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11335 (const_int 0)))
11336 (set (match_operand:DI 0 "register_operand" "=r")
11337 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11338 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11339 && ix86_binary_operator_ok (AND, SImode, operands)"
11340 "and{l}\t{%2, %k0|%k0, %2}"
11341 [(set_attr "type" "alu")
11342 (set_attr "mode" "SI")])
11343
11344 (define_insn "*andqi_2_maybe_si"
11345 [(set (reg FLAGS_REG)
11346 (compare (and:QI
11347 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11348 (match_operand:QI 2 "general_operand" "qn,m,n"))
11349 (const_int 0)))
11350 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11351 (and:QI (match_dup 1) (match_dup 2)))]
11352 "ix86_binary_operator_ok (AND, QImode, operands)
11353 && ix86_match_ccmode (insn,
11354 CONST_INT_P (operands[2])
11355 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11356 {
11357 if (get_attr_mode (insn) == MODE_SI)
11358 {
11359 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11360 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11361 return "and{l}\t{%2, %k0|%k0, %2}";
11362 }
11363 return "and{b}\t{%2, %0|%0, %2}";
11364 }
11365 [(set_attr "type" "alu")
11366 (set (attr "mode")
11367 (cond [(eq_attr "alternative" "2")
11368 (const_string "SI")
11369 (and (match_test "optimize_insn_for_size_p ()")
11370 (and (match_operand 0 "ext_QIreg_operand")
11371 (match_operand 2 "const_0_to_127_operand")))
11372 (const_string "SI")
11373 ]
11374 (const_string "QI")))
11375 ;; Potential partial reg stall on alternative 2.
11376 (set (attr "preferred_for_speed")
11377 (cond [(eq_attr "alternative" "2")
11378 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11379 (symbol_ref "true")))])
11380
11381 (define_insn "*and<mode>_2"
11382 [(set (reg FLAGS_REG)
11383 (compare (and:SWI124
11384 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11385 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11386 (const_int 0)))
11387 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11388 (and:SWI124 (match_dup 1) (match_dup 2)))]
11389 "ix86_match_ccmode (insn, CCNOmode)
11390 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11391 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11392 [(set_attr "type" "alu")
11393 (set_attr "mode" "<MODE>")])
11394
11395 (define_insn "*andqi_ext<mode>_0"
11396 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
11397 (and:QI
11398 (subreg:QI
11399 (match_operator:SWI248 3 "extract_operator"
11400 [(match_operand 2 "int248_register_operand" "Q,Q")
11401 (const_int 8)
11402 (const_int 8)]) 0)
11403 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
11404 (clobber (reg:CC FLAGS_REG))]
11405 ""
11406 "and{b}\t{%h2, %0|%0, %h2}"
11407 [(set_attr "isa" "*,nox64")
11408 (set_attr "type" "alu")
11409 (set_attr "mode" "QI")])
11410
11411 (define_expand "andqi_ext_1"
11412 [(parallel
11413 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11414 (const_int 8)
11415 (const_int 8))
11416 (subreg:HI
11417 (and:QI
11418 (subreg:QI
11419 (zero_extract:HI (match_operand:HI 1 "register_operand")
11420 (const_int 8)
11421 (const_int 8)) 0)
11422 (match_operand:QI 2 "const_int_operand")) 0))
11423 (clobber (reg:CC FLAGS_REG))])])
11424
11425 (define_insn "*andqi_ext<mode>_1"
11426 [(set (zero_extract:SWI248
11427 (match_operand 0 "int248_register_operand" "+Q,Q")
11428 (const_int 8)
11429 (const_int 8))
11430 (subreg:SWI248
11431 (and:QI
11432 (subreg:QI
11433 (match_operator:SWI248 3 "extract_operator"
11434 [(match_operand 1 "int248_register_operand" "0,0")
11435 (const_int 8)
11436 (const_int 8)]) 0)
11437 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
11438 (clobber (reg:CC FLAGS_REG))]
11439 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11440 rtx_equal_p (operands[0], operands[1])"
11441 "and{b}\t{%2, %h0|%h0, %2}"
11442 [(set_attr "isa" "*,nox64")
11443 (set_attr "type" "alu")
11444 (set_attr "mode" "QI")])
11445
11446 ;; Generated by peephole translating test to and. This shows up
11447 ;; often in fp comparisons.
11448 (define_insn "*andqi_ext<mode>_1_cc"
11449 [(set (reg FLAGS_REG)
11450 (compare
11451 (and:QI
11452 (subreg:QI
11453 (match_operator:SWI248 3 "extract_operator"
11454 [(match_operand 1 "int248_register_operand" "0,0")
11455 (const_int 8)
11456 (const_int 8)]) 0)
11457 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
11458 (const_int 0)))
11459 (set (zero_extract:SWI248
11460 (match_operand 0 "int248_register_operand" "+Q,Q")
11461 (const_int 8)
11462 (const_int 8))
11463 (subreg:SWI248
11464 (and:QI
11465 (subreg:QI
11466 (match_op_dup 3
11467 [(match_dup 1)
11468 (const_int 8)
11469 (const_int 8)]) 0)
11470 (match_dup 2)) 0))]
11471 "ix86_match_ccmode (insn, CCNOmode)
11472 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11473 && rtx_equal_p (operands[0], operands[1])"
11474 "and{b}\t{%2, %h0|%h0, %2}"
11475 [(set_attr "isa" "*,nox64")
11476 (set_attr "type" "alu")
11477 (set_attr "mode" "QI")])
11478
11479 (define_insn "*andqi_ext<mode>_2"
11480 [(set (zero_extract:SWI248
11481 (match_operand 0 "int248_register_operand" "+Q")
11482 (const_int 8)
11483 (const_int 8))
11484 (subreg:SWI248
11485 (and:QI
11486 (subreg:QI
11487 (match_operator:SWI248 3 "extract_operator"
11488 [(match_operand 1 "int248_register_operand" "%0")
11489 (const_int 8)
11490 (const_int 8)]) 0)
11491 (subreg:QI
11492 (match_operator:SWI248 4 "extract_operator"
11493 [(match_operand 2 "int248_register_operand" "Q")
11494 (const_int 8)
11495 (const_int 8)]) 0)) 0))
11496 (clobber (reg:CC FLAGS_REG))]
11497 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11498 rtx_equal_p (operands[0], operands[1])
11499 || rtx_equal_p (operands[0], operands[2])"
11500 "and{b}\t{%h2, %h0|%h0, %h2}"
11501 [(set_attr "type" "alu")
11502 (set_attr "mode" "QI")])
11503
11504 ;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
11505
11506 ;; Convert wide AND instructions with immediate operand to shorter QImode
11507 ;; equivalents when possible.
11508 ;; Don't do the splitting with memory operands, since it introduces risk
11509 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
11510 ;; for size, but that can (should?) be handled by generic code instead.
11511 (define_split
11512 [(set (match_operand:SWI248 0 "QIreg_operand")
11513 (and:SWI248 (match_operand:SWI248 1 "register_operand")
11514 (match_operand:SWI248 2 "const_int_operand")))
11515 (clobber (reg:CC FLAGS_REG))]
11516 "reload_completed
11517 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11518 && !(~INTVAL (operands[2]) & ~(255 << 8))"
11519 [(parallel
11520 [(set (zero_extract:HI (match_dup 0)
11521 (const_int 8)
11522 (const_int 8))
11523 (subreg:HI
11524 (and:QI
11525 (subreg:QI
11526 (zero_extract:HI (match_dup 1)
11527 (const_int 8)
11528 (const_int 8)) 0)
11529 (match_dup 2)) 0))
11530 (clobber (reg:CC FLAGS_REG))])]
11531 {
11532 operands[0] = gen_lowpart (HImode, operands[0]);
11533 operands[1] = gen_lowpart (HImode, operands[1]);
11534 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11535 })
11536
11537 ;; Since AND can be encoded with sign extended immediate, this is only
11538 ;; profitable when 7th bit is not set.
11539 (define_split
11540 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11541 (and:SWI248 (match_operand:SWI248 1 "general_operand")
11542 (match_operand:SWI248 2 "const_int_operand")))
11543 (clobber (reg:CC FLAGS_REG))]
11544 "reload_completed
11545 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11546 && !(~INTVAL (operands[2]) & ~255)
11547 && !(INTVAL (operands[2]) & 128)"
11548 [(parallel [(set (strict_low_part (match_dup 0))
11549 (and:QI (match_dup 1)
11550 (match_dup 2)))
11551 (clobber (reg:CC FLAGS_REG))])]
11552 {
11553 operands[0] = gen_lowpart (QImode, operands[0]);
11554 operands[1] = gen_lowpart (QImode, operands[1]);
11555 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11556 })
11557
11558 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11559 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11560 (and:<DWI>
11561 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11562 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11563 (clobber (reg:CC FLAGS_REG))]
11564 "TARGET_BMI"
11565 "#"
11566 "&& reload_completed"
11567 [(parallel [(set (match_dup 0)
11568 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11569 (clobber (reg:CC FLAGS_REG))])
11570 (parallel [(set (match_dup 3)
11571 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11572 (clobber (reg:CC FLAGS_REG))])]
11573 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11574
11575 (define_insn_and_split "*andn<mode>3_doubleword"
11576 [(set (match_operand:DWI 0 "register_operand")
11577 (and:DWI
11578 (not:DWI (match_operand:DWI 1 "register_operand"))
11579 (match_operand:DWI 2 "nonimmediate_operand")))
11580 (clobber (reg:CC FLAGS_REG))]
11581 "!TARGET_BMI
11582 && ix86_pre_reload_split ()"
11583 "#"
11584 "&& 1"
11585 [(set (match_dup 3) (not:DWI (match_dup 1)))
11586 (parallel [(set (match_dup 0)
11587 (and:DWI (match_dup 3) (match_dup 2)))
11588 (clobber (reg:CC FLAGS_REG))])]
11589 "operands[3] = gen_reg_rtx (<MODE>mode);")
11590
11591 (define_insn "*andn<mode>_1"
11592 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11593 (and:SWI48
11594 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11595 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11596 (clobber (reg:CC FLAGS_REG))]
11597 "TARGET_BMI || TARGET_AVX512BW"
11598 "@
11599 andn\t{%2, %1, %0|%0, %1, %2}
11600 andn\t{%2, %1, %0|%0, %1, %2}
11601 #"
11602 [(set_attr "isa" "bmi,bmi,avx512bw")
11603 (set_attr "type" "bitmanip,bitmanip,msklog")
11604 (set_attr "btver2_decode" "direct, double,*")
11605 (set_attr "mode" "<MODE>")])
11606
11607 (define_insn "*andn<mode>_1"
11608 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11609 (and:SWI12
11610 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11611 (match_operand:SWI12 2 "register_operand" "r,k")))
11612 (clobber (reg:CC FLAGS_REG))]
11613 "TARGET_BMI || TARGET_AVX512BW"
11614 "@
11615 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
11616 #"
11617 [(set_attr "isa" "bmi,avx512f")
11618 (set_attr "type" "bitmanip,msklog")
11619 (set_attr "btver2_decode" "direct,*")
11620 (set (attr "mode")
11621 (cond [(eq_attr "alternative" "0")
11622 (const_string "SI")
11623 (and (eq_attr "alternative" "1")
11624 (match_test "!TARGET_AVX512DQ"))
11625 (const_string "HI")
11626 ]
11627 (const_string "<MODE>")))])
11628
11629 (define_insn "*andn_<mode>_ccno"
11630 [(set (reg FLAGS_REG)
11631 (compare
11632 (and:SWI48
11633 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
11634 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
11635 (const_int 0)))
11636 (clobber (match_scratch:SWI48 0 "=r,r"))]
11637 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
11638 "andn\t{%2, %1, %0|%0, %1, %2}"
11639 [(set_attr "type" "bitmanip")
11640 (set_attr "btver2_decode" "direct, double")
11641 (set_attr "mode" "<MODE>")])
11642
11643 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
11644 (define_split
11645 [(set (match_operand:SI 0 "register_operand")
11646 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
11647 (match_operand:SI 2 "nonimmediate_operand")))
11648 (clobber (reg:CC FLAGS_REG))]
11649 "reload_completed
11650 && optimize_insn_for_size_p () && optimize_size > 1
11651 && REGNO (operands[0]) == REGNO (operands[1])
11652 && LEGACY_INT_REG_P (operands[0])
11653 && !REX_INT_REG_P (operands[2])
11654 && !reg_overlap_mentioned_p (operands[0], operands[2])"
11655 [(set (match_dup 0) (not:SI (match_dup 1)))
11656 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
11657 (clobber (reg:CC FLAGS_REG))])])
11658
11659 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
11660 (define_split
11661 [(set (match_operand 0 "flags_reg_operand")
11662 (match_operator 1 "compare_operator"
11663 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
11664 (match_operand:SI 3 "nonimmediate_operand"))
11665 (const_int 0)]))
11666 (clobber (match_dup 2))]
11667 "reload_completed
11668 && optimize_insn_for_size_p () && optimize_size > 1
11669 && LEGACY_INT_REG_P (operands[2])
11670 && !REX_INT_REG_P (operands[3])
11671 && !reg_overlap_mentioned_p (operands[2], operands[3])"
11672 [(set (match_dup 2) (not:SI (match_dup 2)))
11673 (set (match_dup 0) (match_op_dup 1
11674 [(and:SI (match_dup 3) (match_dup 2))
11675 (const_int 0)]))])
11676
11677 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
11678 (define_split
11679 [(set (match_operand:SWI48 0 "register_operand")
11680 (xor:SWI48
11681 (xor:SWI48
11682 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11683 (match_operand:SWI48 2 "nonimmediate_operand"))
11684 (match_dup 1))
11685 (match_operand:SWI48 3 "nonimmediate_operand")))
11686 (clobber (reg:CC FLAGS_REG))]
11687 "TARGET_BMI"
11688 [(parallel
11689 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11690 (clobber (reg:CC FLAGS_REG))])
11691 (parallel
11692 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11693 (clobber (reg:CC FLAGS_REG))])]
11694 "operands[4] = gen_reg_rtx (<MODE>mode);")
11695
11696 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
11697 (define_split
11698 [(set (match_operand:SWI48 0 "register_operand")
11699 (xor:SWI48
11700 (xor:SWI48
11701 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11702 (match_operand:SWI48 2 "register_operand"))
11703 (match_dup 2))
11704 (match_operand:SWI48 3 "nonimmediate_operand")))
11705 (clobber (reg:CC FLAGS_REG))]
11706 "TARGET_BMI"
11707 [(parallel
11708 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11709 (clobber (reg:CC FLAGS_REG))])
11710 (parallel
11711 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11712 (clobber (reg:CC FLAGS_REG))])]
11713 "operands[4] = gen_reg_rtx (<MODE>mode);")
11714
11715 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
11716 (define_split
11717 [(set (match_operand:SWI48 0 "register_operand")
11718 (xor:SWI48
11719 (xor:SWI48
11720 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11721 (match_operand:SWI48 2 "nonimmediate_operand"))
11722 (match_operand:SWI48 3 "nonimmediate_operand"))
11723 (match_dup 1)))
11724 (clobber (reg:CC FLAGS_REG))]
11725 "TARGET_BMI"
11726 [(parallel
11727 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11728 (clobber (reg:CC FLAGS_REG))])
11729 (parallel
11730 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11731 (clobber (reg:CC FLAGS_REG))])]
11732 "operands[4] = gen_reg_rtx (<MODE>mode);")
11733
11734 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
11735 (define_split
11736 [(set (match_operand:SWI48 0 "register_operand")
11737 (xor:SWI48
11738 (xor:SWI48
11739 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11740 (match_operand:SWI48 2 "register_operand"))
11741 (match_operand:SWI48 3 "nonimmediate_operand"))
11742 (match_dup 2)))
11743 (clobber (reg:CC FLAGS_REG))]
11744 "TARGET_BMI"
11745 [(parallel
11746 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11747 (clobber (reg:CC FLAGS_REG))])
11748 (parallel
11749 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11750 (clobber (reg:CC FLAGS_REG))])]
11751 "operands[4] = gen_reg_rtx (<MODE>mode);")
11752 \f
11753 ;; Logical inclusive and exclusive OR instructions
11754
11755 ;; %%% This used to optimize known byte-wide and operations to memory.
11756 ;; If this is considered useful, it should be done with splitters.
11757
11758 (define_expand "<code><mode>3"
11759 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11760 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11761 (match_operand:SDWIM 2 "<general_operand>")))]
11762 ""
11763 {
11764 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11765 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11766 operands[2] = force_reg (<MODE>mode, operands[2]);
11767
11768 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
11769 DONE;
11770 })
11771
11772 (define_insn_and_split "*<code><dwi>3_doubleword"
11773 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11774 (any_or:<DWI>
11775 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11776 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11777 (clobber (reg:CC FLAGS_REG))]
11778 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
11779 "#"
11780 "&& reload_completed"
11781 [(const_int:DWIH 0)]
11782 {
11783 /* This insn may disappear completely when operands[2] == const0_rtx
11784 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
11785 bool emit_insn_deleted_note_p = false;
11786
11787 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11788
11789 if (operands[2] == const0_rtx)
11790 emit_insn_deleted_note_p = true;
11791 else if (operands[2] == constm1_rtx)
11792 {
11793 if (<CODE> == IOR)
11794 emit_move_insn (operands[0], constm1_rtx);
11795 else
11796 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
11797 }
11798 else
11799 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
11800
11801 if (operands[5] == const0_rtx)
11802 {
11803 if (emit_insn_deleted_note_p)
11804 emit_note (NOTE_INSN_DELETED);
11805 }
11806 else if (operands[5] == constm1_rtx)
11807 {
11808 if (<CODE> == IOR)
11809 emit_move_insn (operands[3], constm1_rtx);
11810 else
11811 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
11812 }
11813 else
11814 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
11815
11816 DONE;
11817 })
11818
11819 (define_insn "*<code><mode>_1"
11820 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11821 (any_or:SWI248
11822 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11823 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
11824 (clobber (reg:CC FLAGS_REG))]
11825 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11826 "@
11827 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11828 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11829 #"
11830 [(set (attr "isa")
11831 (cond [(eq_attr "alternative" "2")
11832 (if_then_else (eq_attr "mode" "SI,DI")
11833 (const_string "avx512bw")
11834 (const_string "avx512f"))
11835 ]
11836 (const_string "*")))
11837 (set_attr "type" "alu, alu, msklog")
11838 (set_attr "mode" "<MODE>")])
11839
11840 (define_insn_and_split "*notxor<mode>_1"
11841 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11842 (not:SWI248
11843 (xor:SWI248
11844 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11845 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
11846 (clobber (reg:CC FLAGS_REG))]
11847 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
11848 "#"
11849 "&& reload_completed"
11850 [(parallel
11851 [(set (match_dup 0)
11852 (xor:SWI248 (match_dup 1) (match_dup 2)))
11853 (clobber (reg:CC FLAGS_REG))])
11854 (set (match_dup 0)
11855 (not:SWI248 (match_dup 0)))]
11856 {
11857 if (MASK_REG_P (operands[0]))
11858 {
11859 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
11860 DONE;
11861 }
11862 }
11863 [(set (attr "isa")
11864 (cond [(eq_attr "alternative" "2")
11865 (if_then_else (eq_attr "mode" "SI,DI")
11866 (const_string "avx512bw")
11867 (const_string "avx512f"))
11868 ]
11869 (const_string "*")))
11870 (set_attr "type" "alu, alu, msklog")
11871 (set_attr "mode" "<MODE>")])
11872
11873 (define_insn_and_split "*iordi_1_bts"
11874 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11875 (ior:DI
11876 (match_operand:DI 1 "nonimmediate_operand" "%0")
11877 (match_operand:DI 2 "const_int_operand" "n")))
11878 (clobber (reg:CC FLAGS_REG))]
11879 "TARGET_64BIT && TARGET_USE_BT
11880 && ix86_binary_operator_ok (IOR, DImode, operands)
11881 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
11882 "#"
11883 "&& reload_completed"
11884 [(parallel [(set (zero_extract:DI (match_dup 0)
11885 (const_int 1)
11886 (match_dup 3))
11887 (const_int 1))
11888 (clobber (reg:CC FLAGS_REG))])]
11889 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
11890 [(set_attr "type" "alu1")
11891 (set_attr "prefix_0f" "1")
11892 (set_attr "znver1_decode" "double")
11893 (set_attr "mode" "DI")])
11894
11895 (define_insn_and_split "*xordi_1_btc"
11896 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11897 (xor:DI
11898 (match_operand:DI 1 "nonimmediate_operand" "%0")
11899 (match_operand:DI 2 "const_int_operand" "n")))
11900 (clobber (reg:CC FLAGS_REG))]
11901 "TARGET_64BIT && TARGET_USE_BT
11902 && ix86_binary_operator_ok (XOR, DImode, operands)
11903 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
11904 "#"
11905 "&& reload_completed"
11906 [(parallel [(set (zero_extract:DI (match_dup 0)
11907 (const_int 1)
11908 (match_dup 3))
11909 (not:DI (zero_extract:DI (match_dup 0)
11910 (const_int 1)
11911 (match_dup 3))))
11912 (clobber (reg:CC FLAGS_REG))])]
11913 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
11914 [(set_attr "type" "alu1")
11915 (set_attr "prefix_0f" "1")
11916 (set_attr "znver1_decode" "double")
11917 (set_attr "mode" "DI")])
11918
11919 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
11920 (define_insn_and_split "*xor2andn"
11921 [(set (match_operand:SWI248 0 "register_operand")
11922 (xor:SWI248
11923 (and:SWI248
11924 (xor:SWI248
11925 (match_operand:SWI248 1 "nonimmediate_operand")
11926 (match_operand:SWI248 2 "nonimmediate_operand"))
11927 (match_operand:SWI248 3 "nonimmediate_operand"))
11928 (match_dup 1)))
11929 (clobber (reg:CC FLAGS_REG))]
11930 "TARGET_BMI && ix86_pre_reload_split ()"
11931 "#"
11932 "&& 1"
11933 [(parallel [(set (match_dup 4)
11934 (and:SWI248
11935 (not:SWI248
11936 (match_dup 3))
11937 (match_dup 1)))
11938 (clobber (reg:CC FLAGS_REG))])
11939 (parallel [(set (match_dup 5)
11940 (and:SWI248
11941 (match_dup 3)
11942 (match_dup 2)))
11943 (clobber (reg:CC FLAGS_REG))])
11944 (parallel [(set (match_dup 0)
11945 (ior:SWI248
11946 (match_dup 4)
11947 (match_dup 5)))
11948 (clobber (reg:CC FLAGS_REG))])]
11949 {
11950 operands[1] = force_reg (<MODE>mode, operands[1]);
11951 operands[3] = force_reg (<MODE>mode, operands[3]);
11952 operands[4] = gen_reg_rtx (<MODE>mode);
11953 operands[5] = gen_reg_rtx (<MODE>mode);
11954 })
11955
11956 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11957 (define_insn "*<code>si_1_zext"
11958 [(set (match_operand:DI 0 "register_operand" "=r")
11959 (zero_extend:DI
11960 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11961 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11962 (clobber (reg:CC FLAGS_REG))]
11963 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11964 "<logic>{l}\t{%2, %k0|%k0, %2}"
11965 [(set_attr "type" "alu")
11966 (set_attr "mode" "SI")])
11967
11968 (define_insn "*<code>si_1_zext_imm"
11969 [(set (match_operand:DI 0 "register_operand" "=r")
11970 (any_or:DI
11971 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
11972 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
11973 (clobber (reg:CC FLAGS_REG))]
11974 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11975 "<logic>{l}\t{%2, %k0|%k0, %2}"
11976 [(set_attr "type" "alu")
11977 (set_attr "mode" "SI")])
11978
11979 (define_insn "*<code>qi_1"
11980 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11981 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11982 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11983 (clobber (reg:CC FLAGS_REG))]
11984 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
11985 "@
11986 <logic>{b}\t{%2, %0|%0, %2}
11987 <logic>{b}\t{%2, %0|%0, %2}
11988 <logic>{l}\t{%k2, %k0|%k0, %k2}
11989 #"
11990 [(set_attr "isa" "*,*,*,avx512f")
11991 (set_attr "type" "alu,alu,alu,msklog")
11992 (set (attr "mode")
11993 (cond [(eq_attr "alternative" "2")
11994 (const_string "SI")
11995 (and (eq_attr "alternative" "3")
11996 (match_test "!TARGET_AVX512DQ"))
11997 (const_string "HI")
11998 ]
11999 (const_string "QI")))
12000 ;; Potential partial reg stall on alternative 2.
12001 (set (attr "preferred_for_speed")
12002 (cond [(eq_attr "alternative" "2")
12003 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12004 (symbol_ref "true")))])
12005
12006 (define_insn_and_split "*notxorqi_1"
12007 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
12008 (not:QI
12009 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
12010 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
12011 (clobber (reg:CC FLAGS_REG))]
12012 "ix86_binary_operator_ok (XOR, QImode, operands)"
12013 "#"
12014 "&& reload_completed"
12015 [(parallel
12016 [(set (match_dup 0)
12017 (xor:QI (match_dup 1) (match_dup 2)))
12018 (clobber (reg:CC FLAGS_REG))])
12019 (set (match_dup 0)
12020 (not:QI (match_dup 0)))]
12021 {
12022 if (mask_reg_operand (operands[0], QImode))
12023 {
12024 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
12025 DONE;
12026 }
12027 }
12028 [(set_attr "isa" "*,*,*,avx512f")
12029 (set_attr "type" "alu,alu,alu,msklog")
12030 (set (attr "mode")
12031 (cond [(eq_attr "alternative" "2")
12032 (const_string "SI")
12033 (and (eq_attr "alternative" "3")
12034 (match_test "!TARGET_AVX512DQ"))
12035 (const_string "HI")
12036 ]
12037 (const_string "QI")))
12038 ;; Potential partial reg stall on alternative 2.
12039 (set (attr "preferred_for_speed")
12040 (cond [(eq_attr "alternative" "2")
12041 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12042 (symbol_ref "true")))])
12043
12044 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12045 (define_insn_and_split "*<code><mode>_1_slp"
12046 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12047 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
12048 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
12049 (clobber (reg:CC FLAGS_REG))]
12050 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12051 "@
12052 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12053 #"
12054 "&& reload_completed"
12055 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12056 (parallel
12057 [(set (strict_low_part (match_dup 0))
12058 (any_or:SWI12 (match_dup 0) (match_dup 2)))
12059 (clobber (reg:CC FLAGS_REG))])]
12060 ""
12061 [(set_attr "type" "alu")
12062 (set_attr "mode" "<MODE>")])
12063
12064 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12065 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12066 ;; This eliminates sign extension after logic operation.
12067
12068 (define_split
12069 [(set (match_operand:SWI248 0 "register_operand")
12070 (sign_extend:SWI248
12071 (any_logic:QI (match_operand:QI 1 "memory_operand")
12072 (match_operand:QI 2 "const_int_operand"))))]
12073 ""
12074 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12075 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12076 "operands[3] = gen_reg_rtx (<MODE>mode);")
12077
12078 (define_split
12079 [(set (match_operand:SWI48 0 "register_operand")
12080 (sign_extend:SWI48
12081 (any_logic:HI (match_operand:HI 1 "memory_operand")
12082 (match_operand:HI 2 "const_int_operand"))))]
12083 ""
12084 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12085 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12086 "operands[3] = gen_reg_rtx (<MODE>mode);")
12087
12088 (define_split
12089 [(set (match_operand:DI 0 "register_operand")
12090 (sign_extend:DI
12091 (any_logic:SI (match_operand:SI 1 "memory_operand")
12092 (match_operand:SI 2 "const_int_operand"))))]
12093 "TARGET_64BIT"
12094 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12095 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12096 "operands[3] = gen_reg_rtx (DImode);")
12097
12098 (define_insn "*<code><mode>_2"
12099 [(set (reg FLAGS_REG)
12100 (compare (any_or:SWI
12101 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12102 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12103 (const_int 0)))
12104 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12105 (any_or:SWI (match_dup 1) (match_dup 2)))]
12106 "ix86_match_ccmode (insn, CCNOmode)
12107 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12108 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12109 [(set_attr "type" "alu")
12110 (set_attr "mode" "<MODE>")])
12111
12112 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12113 ;; ??? Special case for immediate operand is missing - it is tricky.
12114 (define_insn "*<code>si_2_zext"
12115 [(set (reg FLAGS_REG)
12116 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12117 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12118 (const_int 0)))
12119 (set (match_operand:DI 0 "register_operand" "=r")
12120 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12121 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12122 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12123 "<logic>{l}\t{%2, %k0|%k0, %2}"
12124 [(set_attr "type" "alu")
12125 (set_attr "mode" "SI")])
12126
12127 (define_insn "*<code>si_2_zext_imm"
12128 [(set (reg FLAGS_REG)
12129 (compare (any_or:SI
12130 (match_operand:SI 1 "nonimmediate_operand" "%0")
12131 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12132 (const_int 0)))
12133 (set (match_operand:DI 0 "register_operand" "=r")
12134 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12135 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12136 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12137 "<logic>{l}\t{%2, %k0|%k0, %2}"
12138 [(set_attr "type" "alu")
12139 (set_attr "mode" "SI")])
12140
12141 (define_insn "*<code><mode>_3"
12142 [(set (reg FLAGS_REG)
12143 (compare (any_or:SWI
12144 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12145 (match_operand:SWI 2 "<general_operand>" "<g>"))
12146 (const_int 0)))
12147 (clobber (match_scratch:SWI 0 "=<r>"))]
12148 "ix86_match_ccmode (insn, CCNOmode)
12149 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12150 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12151 [(set_attr "type" "alu")
12152 (set_attr "mode" "<MODE>")])
12153
12154 (define_insn "*<code>qi_ext<mode>_0"
12155 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
12156 (any_or:QI
12157 (subreg:QI
12158 (match_operator:SWI248 3 "extract_operator"
12159 [(match_operand 2 "int248_register_operand" "Q,Q")
12160 (const_int 8)
12161 (const_int 8)]) 0)
12162 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
12163 (clobber (reg:CC FLAGS_REG))]
12164 ""
12165 "<logic>{b}\t{%h2, %0|%0, %h2}"
12166 [(set_attr "isa" "*,nox64")
12167 (set_attr "type" "alu")
12168 (set_attr "mode" "QI")])
12169
12170 (define_insn "*<code>qi_ext<mode>_1"
12171 [(set (zero_extract:SWI248
12172 (match_operand 0 "int248_register_operand" "+Q,Q")
12173 (const_int 8)
12174 (const_int 8))
12175 (subreg:SWI248
12176 (any_or:QI
12177 (subreg:QI
12178 (match_operator:SWI248 3 "extract_operator"
12179 [(match_operand 1 "int248_register_operand" "0,0")
12180 (const_int 8)
12181 (const_int 8)]) 0)
12182 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
12183 (clobber (reg:CC FLAGS_REG))]
12184 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12185 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12186 && rtx_equal_p (operands[0], operands[1])"
12187 "<logic>{b}\t{%2, %h0|%h0, %2}"
12188 [(set_attr "isa" "*,nox64")
12189 (set_attr "type" "alu")
12190 (set_attr "mode" "QI")])
12191
12192 (define_insn "*<code>qi_ext<mode>_2"
12193 [(set (zero_extract:SWI248
12194 (match_operand 0 "int248_register_operand" "+Q")
12195 (const_int 8)
12196 (const_int 8))
12197 (subreg:SWI248
12198 (any_or:QI
12199 (subreg:QI
12200 (match_operator:SWI248 3 "extract_operator"
12201 [(match_operand 1 "int248_register_operand" "%0")
12202 (const_int 8)
12203 (const_int 8)]) 0)
12204 (subreg:QI
12205 (match_operator:SWI248 4 "extract_operator"
12206 [(match_operand 2 "int248_register_operand" "Q")
12207 (const_int 8)
12208 (const_int 8)]) 0)) 0))
12209 (clobber (reg:CC FLAGS_REG))]
12210 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12211 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12212 && (rtx_equal_p (operands[0], operands[1])
12213 || rtx_equal_p (operands[0], operands[2]))"
12214 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12215 [(set_attr "type" "alu")
12216 (set_attr "mode" "QI")])
12217
12218 (define_insn "*<code>qi_ext<mode>_3"
12219 [(set (zero_extract:SWI248
12220 (match_operand 0 "int248_register_operand" "+Q")
12221 (const_int 8)
12222 (const_int 8))
12223 (zero_extract:SWI248
12224 (any_logic:SWI248
12225 (match_operand 1 "int248_register_operand" "%0")
12226 (match_operand 2 "int248_register_operand" "Q"))
12227 (const_int 8)
12228 (const_int 8)))
12229 (clobber (reg:CC FLAGS_REG))]
12230 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12231 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12232 && (rtx_equal_p (operands[0], operands[1])
12233 || rtx_equal_p (operands[0], operands[2]))"
12234 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12235 [(set_attr "type" "alu")
12236 (set_attr "mode" "QI")])
12237
12238 ;; Convert wide OR instructions with immediate operand to shorter QImode
12239 ;; equivalents when possible.
12240 ;; Don't do the splitting with memory operands, since it introduces risk
12241 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12242 ;; for size, but that can (should?) be handled by generic code instead.
12243 (define_split
12244 [(set (match_operand:SWI248 0 "QIreg_operand")
12245 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12246 (match_operand:SWI248 2 "const_int_operand")))
12247 (clobber (reg:CC FLAGS_REG))]
12248 "reload_completed
12249 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12250 && !(INTVAL (operands[2]) & ~(255 << 8))"
12251 [(parallel
12252 [(set (zero_extract:HI (match_dup 0)
12253 (const_int 8)
12254 (const_int 8))
12255 (subreg:HI
12256 (any_or:QI
12257 (subreg:QI
12258 (zero_extract:HI (match_dup 1)
12259 (const_int 8)
12260 (const_int 8)) 0)
12261 (match_dup 2)) 0))
12262 (clobber (reg:CC FLAGS_REG))])]
12263 {
12264 /* Handle the case where INTVAL (operands[2]) == 0. */
12265 if (operands[2] == const0_rtx)
12266 {
12267 if (!rtx_equal_p (operands[0], operands[1]))
12268 emit_move_insn (operands[0], operands[1]);
12269 else
12270 emit_note (NOTE_INSN_DELETED);
12271 DONE;
12272 }
12273 operands[0] = gen_lowpart (HImode, operands[0]);
12274 operands[1] = gen_lowpart (HImode, operands[1]);
12275 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12276 })
12277
12278 ;; Since OR can be encoded with sign extended immediate, this is only
12279 ;; profitable when 7th bit is set.
12280 (define_split
12281 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12282 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12283 (match_operand:SWI248 2 "const_int_operand")))
12284 (clobber (reg:CC FLAGS_REG))]
12285 "reload_completed
12286 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12287 && !(INTVAL (operands[2]) & ~255)
12288 && (INTVAL (operands[2]) & 128)"
12289 [(parallel [(set (strict_low_part (match_dup 0))
12290 (any_or:QI (match_dup 1)
12291 (match_dup 2)))
12292 (clobber (reg:CC FLAGS_REG))])]
12293 {
12294 operands[0] = gen_lowpart (QImode, operands[0]);
12295 operands[1] = gen_lowpart (QImode, operands[1]);
12296 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12297 })
12298
12299 (define_expand "xorqi_ext_1_cc"
12300 [(parallel
12301 [(set (reg:CCNO FLAGS_REG)
12302 (compare:CCNO
12303 (xor:QI
12304 (subreg:QI
12305 (zero_extract:HI (match_operand:HI 1 "register_operand")
12306 (const_int 8)
12307 (const_int 8)) 0)
12308 (match_operand:QI 2 "const_int_operand"))
12309 (const_int 0)))
12310 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12311 (const_int 8)
12312 (const_int 8))
12313 (subreg:HI
12314 (xor:QI
12315 (subreg:QI
12316 (zero_extract:HI (match_dup 1)
12317 (const_int 8)
12318 (const_int 8)) 0)
12319 (match_dup 2)) 0))])])
12320
12321 (define_insn "*xorqi_ext<mode>_1_cc"
12322 [(set (reg FLAGS_REG)
12323 (compare
12324 (xor:QI
12325 (subreg:QI
12326 (match_operator:SWI248 3 "extract_operator"
12327 [(match_operand 1 "int248_register_operand" "0,0")
12328 (const_int 8)
12329 (const_int 8)]) 0)
12330 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
12331 (const_int 0)))
12332 (set (zero_extract:SWI248
12333 (match_operand 0 "int248_register_operand" "+Q,Q")
12334 (const_int 8)
12335 (const_int 8))
12336 (subreg:SWI248
12337 (xor:QI
12338 (subreg:QI
12339 (match_op_dup 3
12340 [(match_dup 1)
12341 (const_int 8)
12342 (const_int 8)]) 0)
12343 (match_dup 2)) 0))]
12344 "ix86_match_ccmode (insn, CCNOmode)
12345 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12346 && rtx_equal_p (operands[0], operands[1])"
12347 "xor{b}\t{%2, %h0|%h0, %2}"
12348 [(set_attr "isa" "*,nox64")
12349 (set_attr "type" "alu")
12350 (set_attr "mode" "QI")])
12351
12352 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12353 (define_peephole2
12354 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12355 (const_int 0))
12356 (clobber (reg:CC FLAGS_REG))])
12357 (parallel [(set (match_dup 0)
12358 (any_or_plus:SWI (match_dup 0)
12359 (match_operand:SWI 1 "<general_operand>")))
12360 (clobber (reg:CC FLAGS_REG))])]
12361 "!reg_mentioned_p (operands[0], operands[1])"
12362 [(set (match_dup 0) (match_dup 1))])
12363
12364 ;; Peephole2 dead instruction in rega = 0; rega op= rega.
12365 (define_peephole2
12366 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12367 (const_int 0))
12368 (clobber (reg:CC FLAGS_REG))])
12369 (parallel [(set (match_dup 0)
12370 (any_or_plus:SWI (match_dup 0) (match_dup 0)))
12371 (clobber (reg:CC FLAGS_REG))])]
12372 ""
12373 [(parallel [(set (match_dup 0) (const_int 0))
12374 (clobber (reg:CC FLAGS_REG))])])
12375
12376 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12377 (define_insn_and_split "*concat<mode><dwi>3_1"
12378 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12379 (any_or_plus:<DWI>
12380 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12381 (match_operand:QI 2 "const_int_operand"))
12382 (zero_extend:<DWI>
12383 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12384 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12385 "#"
12386 "&& reload_completed"
12387 [(const_int 0)]
12388 {
12389 split_double_concat (<DWI>mode, operands[0], operands[3],
12390 gen_lowpart (<MODE>mode, operands[1]));
12391 DONE;
12392 })
12393
12394 (define_insn_and_split "*concat<mode><dwi>3_2"
12395 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12396 (any_or_plus:<DWI>
12397 (zero_extend:<DWI>
12398 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12399 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12400 (match_operand:QI 3 "const_int_operand"))))]
12401 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12402 "#"
12403 "&& reload_completed"
12404 [(const_int 0)]
12405 {
12406 split_double_concat (<DWI>mode, operands[0], operands[1],
12407 gen_lowpart (<MODE>mode, operands[2]));
12408 DONE;
12409 })
12410
12411 (define_insn_and_split "*concatditi3_3"
12412 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r,x")
12413 (any_or_plus:TI
12414 (ashift:TI
12415 (zero_extend:TI
12416 (match_operand:DI 1 "nonimmediate_operand" "r,m,r,m,x"))
12417 (match_operand:QI 2 "const_int_operand"))
12418 (zero_extend:TI
12419 (match_operand:DI 3 "nonimmediate_operand" "r,r,m,m,0"))))]
12420 "TARGET_64BIT
12421 && INTVAL (operands[2]) == 64"
12422 "#"
12423 "&& reload_completed"
12424 [(const_int 0)]
12425 {
12426 if (SSE_REG_P (operands[0]))
12427 {
12428 rtx tmp = gen_rtx_REG (V2DImode, REGNO (operands[0]));
12429 emit_insn (gen_vec_concatv2di (tmp, operands[3], operands[1]));
12430 }
12431 else
12432 split_double_concat (TImode, operands[0], operands[3], operands[1]);
12433 DONE;
12434 })
12435
12436 (define_insn_and_split "*concatsidi3_3"
12437 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro,r,r,&r")
12438 (any_or_plus:DI
12439 (ashift:DI
12440 (zero_extend:DI
12441 (match_operand:SI 1 "nonimmediate_operand" "r,m,r,m"))
12442 (match_operand:QI 2 "const_int_operand"))
12443 (zero_extend:DI
12444 (match_operand:SI 3 "nonimmediate_operand" "r,r,m,m"))))]
12445 "!TARGET_64BIT
12446 && INTVAL (operands[2]) == 32"
12447 "#"
12448 "&& reload_completed"
12449 [(const_int 0)]
12450 {
12451 split_double_concat (DImode, operands[0], operands[3], operands[1]);
12452 DONE;
12453 })
12454
12455 (define_insn_and_split "*concat<mode><dwi>3_4"
12456 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12457 (any_or_plus:<DWI>
12458 (zero_extend:<DWI>
12459 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12460 (ashift:<DWI>
12461 (zero_extend:<DWI>
12462 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12463 (match_operand:QI 3 "const_int_operand"))))]
12464 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12465 "#"
12466 "&& reload_completed"
12467 [(const_int 0)]
12468 {
12469 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12470 DONE;
12471 })
12472
12473 (define_insn_and_split "*concat<half><mode>3_5"
12474 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12475 (any_or_plus:DWI
12476 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12477 (match_operand:QI 2 "const_int_operand"))
12478 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12479 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12480 && (<MODE>mode == DImode
12481 ? CONST_INT_P (operands[3])
12482 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12483 : CONST_INT_P (operands[3])
12484 ? INTVAL (operands[3]) >= 0
12485 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12486 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12487 && !(CONST_INT_P (operands[3])
12488 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12489 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12490 0)),
12491 VOIDmode))"
12492 "#"
12493 "&& reload_completed"
12494 [(const_int 0)]
12495 {
12496 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12497 split_double_concat (<MODE>mode, operands[0], op3,
12498 gen_lowpart (<HALF>mode, operands[1]));
12499 DONE;
12500 }
12501 [(set_attr "isa" "*,nox64,x64")])
12502
12503 (define_insn_and_split "*concat<mode><dwi>3_6"
12504 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12505 (any_or_plus:<DWI>
12506 (ashift:<DWI>
12507 (zero_extend:<DWI>
12508 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12509 (match_operand:QI 2 "const_int_operand"))
12510 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12511 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12512 && (<DWI>mode == DImode
12513 ? CONST_INT_P (operands[3])
12514 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12515 : CONST_INT_P (operands[3])
12516 ? INTVAL (operands[3]) >= 0
12517 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12518 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12519 && !(CONST_INT_P (operands[3])
12520 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12521 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12522 0)),
12523 VOIDmode))"
12524 "#"
12525 "&& reload_completed"
12526 [(const_int 0)]
12527 {
12528 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12529 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12530 DONE;
12531 }
12532 [(set_attr "isa" "*,nox64,x64,*")])
12533
12534 (define_insn_and_split "*concat<mode><dwi>3_7"
12535 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12536 (any_or_plus:<DWI>
12537 (zero_extend:<DWI>
12538 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12539 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12540 "<DWI>mode == DImode
12541 ? CONST_INT_P (operands[2])
12542 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12543 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12544 : CONST_WIDE_INT_P (operands[2])
12545 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12546 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12547 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12548 1)),
12549 VOIDmode)"
12550 "#"
12551 "&& reload_completed"
12552 [(const_int 0)]
12553 {
12554 rtx op2;
12555 if (<DWI>mode == DImode)
12556 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12557 else
12558 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12559 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12560 DONE;
12561 }
12562 [(set_attr "isa" "*,nox64,x64,*")])
12563 \f
12564 ;; Negation instructions
12565
12566 (define_expand "neg<mode>2"
12567 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12568 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12569 ""
12570 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12571
12572 (define_insn_and_split "*neg<dwi>2_doubleword"
12573 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12574 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12575 (clobber (reg:CC FLAGS_REG))]
12576 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12577 "#"
12578 "&& reload_completed"
12579 [(parallel
12580 [(set (reg:CCC FLAGS_REG)
12581 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12582 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12583 (parallel
12584 [(set (match_dup 2)
12585 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12586 (match_dup 3))
12587 (const_int 0)))
12588 (clobber (reg:CC FLAGS_REG))])
12589 (parallel
12590 [(set (match_dup 2)
12591 (neg:DWIH (match_dup 2)))
12592 (clobber (reg:CC FLAGS_REG))])]
12593 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12594
12595 ;; Convert:
12596 ;; mov %esi, %edx
12597 ;; negl %eax
12598 ;; adcl $0, %edx
12599 ;; negl %edx
12600 ;; to:
12601 ;; xorl %edx, %edx
12602 ;; negl %eax
12603 ;; sbbl %esi, %edx
12604
12605 (define_peephole2
12606 [(set (match_operand:SWI48 0 "general_reg_operand")
12607 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12608 (parallel
12609 [(set (reg:CCC FLAGS_REG)
12610 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12611 (const_int 0)] UNSPEC_CC_NE))
12612 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12613 (parallel
12614 [(set (match_dup 0)
12615 (plus:SWI48 (plus:SWI48
12616 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12617 (match_dup 0))
12618 (const_int 0)))
12619 (clobber (reg:CC FLAGS_REG))])
12620 (parallel
12621 [(set (match_dup 0)
12622 (neg:SWI48 (match_dup 0)))
12623 (clobber (reg:CC FLAGS_REG))])]
12624 "REGNO (operands[0]) != REGNO (operands[2])
12625 && !reg_mentioned_p (operands[0], operands[1])
12626 && !reg_mentioned_p (operands[2], operands[1])"
12627 [(parallel
12628 [(set (reg:CCC FLAGS_REG)
12629 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12630 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12631 (parallel
12632 [(set (match_dup 0)
12633 (minus:SWI48 (minus:SWI48
12634 (match_dup 0)
12635 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12636 (match_dup 1)))
12637 (clobber (reg:CC FLAGS_REG))])]
12638 "ix86_expand_clear (operands[0]);")
12639
12640 ;; Convert:
12641 ;; xorl %edx, %edx
12642 ;; negl %eax
12643 ;; adcl $0, %edx
12644 ;; negl %edx
12645 ;; to:
12646 ;; negl %eax
12647 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12648
12649 (define_peephole2
12650 [(parallel
12651 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12652 (clobber (reg:CC FLAGS_REG))])
12653 (parallel
12654 [(set (reg:CCC FLAGS_REG)
12655 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12656 (const_int 0)] UNSPEC_CC_NE))
12657 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12658 (parallel
12659 [(set (match_dup 0)
12660 (plus:SWI48 (plus:SWI48
12661 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12662 (match_dup 0))
12663 (const_int 0)))
12664 (clobber (reg:CC FLAGS_REG))])
12665 (parallel
12666 [(set (match_dup 0)
12667 (neg:SWI48 (match_dup 0)))
12668 (clobber (reg:CC FLAGS_REG))])]
12669 "REGNO (operands[0]) != REGNO (operands[1])"
12670 [(parallel
12671 [(set (reg:CCC FLAGS_REG)
12672 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12673 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12674 (parallel
12675 [(set (match_dup 0)
12676 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12677 (const_int -1)
12678 (const_int 0)))
12679 (clobber (reg:CC FLAGS_REG))])])
12680
12681 (define_insn "*neg<mode>_1"
12682 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12683 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12684 (clobber (reg:CC FLAGS_REG))]
12685 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12686 "neg{<imodesuffix>}\t%0"
12687 [(set_attr "type" "negnot")
12688 (set_attr "mode" "<MODE>")])
12689
12690 (define_insn "*negsi_1_zext"
12691 [(set (match_operand:DI 0 "register_operand" "=r")
12692 (zero_extend:DI
12693 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12694 (clobber (reg:CC FLAGS_REG))]
12695 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12696 "neg{l}\t%k0"
12697 [(set_attr "type" "negnot")
12698 (set_attr "mode" "SI")])
12699
12700 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12701 (define_insn_and_split "*neg<mode>_1_slp"
12702 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12703 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12704 (clobber (reg:CC FLAGS_REG))]
12705 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12706 "@
12707 neg{<imodesuffix>}\t%0
12708 #"
12709 "&& reload_completed"
12710 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12711 (parallel
12712 [(set (strict_low_part (match_dup 0))
12713 (neg:SWI12 (match_dup 0)))
12714 (clobber (reg:CC FLAGS_REG))])]
12715 ""
12716 [(set_attr "type" "negnot")
12717 (set_attr "mode" "<MODE>")])
12718
12719 (define_insn "*neg<mode>_2"
12720 [(set (reg FLAGS_REG)
12721 (compare
12722 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12723 (const_int 0)))
12724 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12725 (neg:SWI (match_dup 1)))]
12726 "ix86_match_ccmode (insn, CCGOCmode)
12727 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12728 "neg{<imodesuffix>}\t%0"
12729 [(set_attr "type" "negnot")
12730 (set_attr "mode" "<MODE>")])
12731
12732 (define_insn "*negsi_2_zext"
12733 [(set (reg FLAGS_REG)
12734 (compare
12735 (neg:SI (match_operand:SI 1 "register_operand" "0"))
12736 (const_int 0)))
12737 (set (match_operand:DI 0 "register_operand" "=r")
12738 (zero_extend:DI
12739 (neg:SI (match_dup 1))))]
12740 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12741 && ix86_unary_operator_ok (NEG, SImode, operands)"
12742 "neg{l}\t%k0"
12743 [(set_attr "type" "negnot")
12744 (set_attr "mode" "SI")])
12745
12746 (define_insn "*neg<mode>_ccc_1"
12747 [(set (reg:CCC FLAGS_REG)
12748 (unspec:CCC
12749 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12750 (const_int 0)] UNSPEC_CC_NE))
12751 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12752 (neg:SWI (match_dup 1)))]
12753 ""
12754 "neg{<imodesuffix>}\t%0"
12755 [(set_attr "type" "negnot")
12756 (set_attr "mode" "<MODE>")])
12757
12758 (define_insn "*neg<mode>_ccc_2"
12759 [(set (reg:CCC FLAGS_REG)
12760 (unspec:CCC
12761 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12762 (const_int 0)] UNSPEC_CC_NE))
12763 (clobber (match_scratch:SWI 0 "=<r>"))]
12764 ""
12765 "neg{<imodesuffix>}\t%0"
12766 [(set_attr "type" "negnot")
12767 (set_attr "mode" "<MODE>")])
12768
12769 (define_expand "x86_neg<mode>_ccc"
12770 [(parallel
12771 [(set (reg:CCC FLAGS_REG)
12772 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12773 (const_int 0)] UNSPEC_CC_NE))
12774 (set (match_operand:SWI48 0 "register_operand")
12775 (neg:SWI48 (match_dup 1)))])])
12776
12777 (define_insn "*negqi_ext<mode>_2"
12778 [(set (zero_extract:SWI248
12779 (match_operand 0 "int248_register_operand" "+Q")
12780 (const_int 8)
12781 (const_int 8))
12782 (subreg:SWI248
12783 (neg:QI
12784 (subreg:QI
12785 (match_operator:SWI248 2 "extract_operator"
12786 [(match_operand 1 "int248_register_operand" "0")
12787 (const_int 8)
12788 (const_int 8)]) 0)) 0))
12789 (clobber (reg:CC FLAGS_REG))]
12790 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
12791 rtx_equal_p (operands[0], operands[1])"
12792 "neg{b}\t%h0"
12793 [(set_attr "type" "negnot")
12794 (set_attr "mode" "QI")])
12795
12796 ;; Negate with jump on overflow.
12797 (define_expand "negv<mode>3"
12798 [(parallel [(set (reg:CCO FLAGS_REG)
12799 (unspec:CCO
12800 [(match_operand:SWI 1 "register_operand")
12801 (match_dup 3)] UNSPEC_CC_NE))
12802 (set (match_operand:SWI 0 "register_operand")
12803 (neg:SWI (match_dup 1)))])
12804 (set (pc) (if_then_else
12805 (eq (reg:CCO FLAGS_REG) (const_int 0))
12806 (label_ref (match_operand 2))
12807 (pc)))]
12808 ""
12809 {
12810 operands[3]
12811 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
12812 <MODE>mode);
12813 })
12814
12815 (define_insn "*negv<mode>3"
12816 [(set (reg:CCO FLAGS_REG)
12817 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
12818 (match_operand:SWI 2 "const_int_operand")]
12819 UNSPEC_CC_NE))
12820 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12821 (neg:SWI (match_dup 1)))]
12822 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
12823 && mode_signbit_p (<MODE>mode, operands[2])"
12824 "neg{<imodesuffix>}\t%0"
12825 [(set_attr "type" "negnot")
12826 (set_attr "mode" "<MODE>")])
12827
12828 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
12829 (define_peephole2
12830 [(set (match_operand:SWI 0 "general_reg_operand")
12831 (match_operand:SWI 1 "general_reg_operand"))
12832 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
12833 (clobber (reg:CC FLAGS_REG))])
12834 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
12835 ""
12836 [(set (match_dup 0) (match_dup 1))
12837 (parallel [(set (reg:CCZ FLAGS_REG)
12838 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
12839 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
12840
12841 ;; Special expand pattern to handle integer mode abs
12842
12843 (define_expand "abs<mode>2"
12844 [(parallel
12845 [(set (match_operand:SDWIM 0 "register_operand")
12846 (abs:SDWIM
12847 (match_operand:SDWIM 1 "general_operand")))
12848 (clobber (reg:CC FLAGS_REG))])]
12849 "TARGET_CMOVE
12850 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
12851 {
12852 if (TARGET_EXPAND_ABS)
12853 {
12854 machine_mode mode = <MODE>mode;
12855 operands[1] = force_reg (mode, operands[1]);
12856
12857 /* Generate rtx abs using:
12858 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
12859
12860 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
12861 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
12862 shift_amount, NULL_RTX,
12863 0, OPTAB_DIRECT);
12864 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
12865 operands[0], 0, OPTAB_DIRECT);
12866 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
12867 operands[0], 0, OPTAB_DIRECT);
12868 if (!rtx_equal_p (minus_dst, operands[0]))
12869 emit_move_insn (operands[0], minus_dst);
12870 DONE;
12871 }
12872 })
12873
12874 (define_insn_and_split "*abs<dwi>2_doubleword"
12875 [(set (match_operand:<DWI> 0 "register_operand")
12876 (abs:<DWI>
12877 (match_operand:<DWI> 1 "general_operand")))
12878 (clobber (reg:CC FLAGS_REG))]
12879 "TARGET_CMOVE
12880 && ix86_pre_reload_split ()"
12881 "#"
12882 "&& 1"
12883 [(parallel
12884 [(set (reg:CCC FLAGS_REG)
12885 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12886 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12887 (parallel
12888 [(set (match_dup 5)
12889 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12890 (match_dup 4))
12891 (const_int 0)))
12892 (clobber (reg:CC FLAGS_REG))])
12893 (parallel
12894 [(set (reg:CCGOC FLAGS_REG)
12895 (compare:CCGOC
12896 (neg:DWIH (match_dup 5))
12897 (const_int 0)))
12898 (set (match_dup 5)
12899 (neg:DWIH (match_dup 5)))])
12900 (set (match_dup 0)
12901 (if_then_else:DWIH
12902 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12903 (match_dup 2)
12904 (match_dup 1)))
12905 (set (match_dup 3)
12906 (if_then_else:DWIH
12907 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12908 (match_dup 5)
12909 (match_dup 4)))]
12910 {
12911 operands[1] = force_reg (<DWI>mode, operands[1]);
12912 operands[2] = gen_reg_rtx (<DWI>mode);
12913
12914 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12915 })
12916
12917 (define_insn_and_split "*nabs<dwi>2_doubleword"
12918 [(set (match_operand:<DWI> 0 "register_operand")
12919 (neg:<DWI>
12920 (abs:<DWI>
12921 (match_operand:<DWI> 1 "general_operand"))))
12922 (clobber (reg:CC FLAGS_REG))]
12923 "TARGET_CMOVE
12924 && ix86_pre_reload_split ()"
12925 "#"
12926 "&& 1"
12927 [(parallel
12928 [(set (reg:CCC FLAGS_REG)
12929 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12930 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12931 (parallel
12932 [(set (match_dup 5)
12933 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12934 (match_dup 4))
12935 (const_int 0)))
12936 (clobber (reg:CC FLAGS_REG))])
12937 (parallel
12938 [(set (reg:CCGOC FLAGS_REG)
12939 (compare:CCGOC
12940 (neg:DWIH (match_dup 5))
12941 (const_int 0)))
12942 (set (match_dup 5)
12943 (neg:DWIH (match_dup 5)))])
12944 (set (match_dup 0)
12945 (if_then_else:DWIH
12946 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12947 (match_dup 2)
12948 (match_dup 1)))
12949 (set (match_dup 3)
12950 (if_then_else:DWIH
12951 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12952 (match_dup 5)
12953 (match_dup 4)))]
12954 {
12955 operands[1] = force_reg (<DWI>mode, operands[1]);
12956 operands[2] = gen_reg_rtx (<DWI>mode);
12957
12958 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12959 })
12960
12961 (define_insn_and_split "*abs<mode>2_1"
12962 [(set (match_operand:SWI 0 "register_operand")
12963 (abs:SWI
12964 (match_operand:SWI 1 "general_operand")))
12965 (clobber (reg:CC FLAGS_REG))]
12966 "TARGET_CMOVE
12967 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
12968 && ix86_pre_reload_split ()"
12969 "#"
12970 "&& 1"
12971 [(parallel
12972 [(set (reg:CCGOC FLAGS_REG)
12973 (compare:CCGOC
12974 (neg:SWI (match_dup 1))
12975 (const_int 0)))
12976 (set (match_dup 2)
12977 (neg:SWI (match_dup 1)))])
12978 (set (match_dup 0)
12979 (if_then_else:SWI
12980 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12981 (match_dup 2)
12982 (match_dup 1)))]
12983 {
12984 operands[1] = force_reg (<MODE>mode, operands[1]);
12985 operands[2] = gen_reg_rtx (<MODE>mode);
12986 })
12987
12988 (define_insn_and_split "*nabs<mode>2_1"
12989 [(set (match_operand:SWI 0 "register_operand")
12990 (neg:SWI
12991 (abs:SWI
12992 (match_operand:SWI 1 "general_operand"))))
12993 (clobber (reg:CC FLAGS_REG))]
12994 "TARGET_CMOVE
12995 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
12996 && ix86_pre_reload_split ()"
12997 "#"
12998 "&& 1"
12999 [(parallel
13000 [(set (reg:CCGOC FLAGS_REG)
13001 (compare:CCGOC
13002 (neg:SWI (match_dup 1))
13003 (const_int 0)))
13004 (set (match_dup 2)
13005 (neg:SWI (match_dup 1)))])
13006 (set (match_dup 0)
13007 (if_then_else:SWI
13008 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
13009 (match_dup 2)
13010 (match_dup 1)))]
13011 {
13012 operands[1] = force_reg (<MODE>mode, operands[1]);
13013 operands[2] = gen_reg_rtx (<MODE>mode);
13014 })
13015
13016 (define_expand "<code>tf2"
13017 [(set (match_operand:TF 0 "register_operand")
13018 (absneg:TF (match_operand:TF 1 "register_operand")))]
13019 "TARGET_SSE"
13020 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
13021
13022 (define_insn_and_split "*<code>tf2_1"
13023 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13024 (absneg:TF
13025 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
13026 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13027 "TARGET_SSE"
13028 "#"
13029 "&& reload_completed"
13030 [(set (match_dup 0)
13031 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
13032 {
13033 if (TARGET_AVX)
13034 {
13035 if (MEM_P (operands[1]))
13036 std::swap (operands[1], operands[2]);
13037 }
13038 else
13039 {
13040 if (operands_match_p (operands[0], operands[2]))
13041 std::swap (operands[1], operands[2]);
13042 }
13043 }
13044 [(set_attr "isa" "noavx,noavx,avx,avx")])
13045
13046 (define_insn_and_split "*nabstf2_1"
13047 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
13048 (neg:TF
13049 (abs:TF
13050 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
13051 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
13052 "TARGET_SSE"
13053 "#"
13054 "&& reload_completed"
13055 [(set (match_dup 0)
13056 (ior:TF (match_dup 1) (match_dup 2)))]
13057 {
13058 if (TARGET_AVX)
13059 {
13060 if (MEM_P (operands[1]))
13061 std::swap (operands[1], operands[2]);
13062 }
13063 else
13064 {
13065 if (operands_match_p (operands[0], operands[2]))
13066 std::swap (operands[1], operands[2]);
13067 }
13068 }
13069 [(set_attr "isa" "noavx,noavx,avx,avx")])
13070
13071 (define_expand "<code>hf2"
13072 [(set (match_operand:HF 0 "register_operand")
13073 (absneg:HF (match_operand:HF 1 "register_operand")))]
13074 "TARGET_AVX512FP16"
13075 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13076
13077 (define_expand "<code><mode>2"
13078 [(set (match_operand:X87MODEF 0 "register_operand")
13079 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13080 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13081 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13082
13083 ;; Changing of sign for FP values is doable using integer unit too.
13084 (define_insn "*<code><mode>2_i387_1"
13085 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13086 (absneg:X87MODEF
13087 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13088 (clobber (reg:CC FLAGS_REG))]
13089 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13090 "#")
13091
13092 (define_split
13093 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13094 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13095 (clobber (reg:CC FLAGS_REG))]
13096 "TARGET_80387 && reload_completed"
13097 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13098
13099 (define_split
13100 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13101 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13102 (clobber (reg:CC FLAGS_REG))]
13103 "TARGET_80387 && reload_completed"
13104 [(const_int 0)]
13105 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13106
13107 (define_insn_and_split "*<code>hf2_1"
13108 [(set (match_operand:HF 0 "register_operand" "=Yv")
13109 (absneg:HF
13110 (match_operand:HF 1 "register_operand" "Yv")))
13111 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13112 (clobber (reg:CC FLAGS_REG))]
13113 "TARGET_AVX512FP16"
13114 "#"
13115 "&& reload_completed"
13116 [(set (match_dup 0)
13117 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13118 {
13119 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13120 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13121 })
13122
13123 (define_insn "*<code><mode>2_1"
13124 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13125 (absneg:MODEF
13126 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13127 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13128 (clobber (reg:CC FLAGS_REG))]
13129 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13130 "#"
13131 [(set_attr "isa" "noavx,noavx,avx,*,*")
13132 (set (attr "enabled")
13133 (if_then_else
13134 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13135 (if_then_else
13136 (eq_attr "alternative" "3,4")
13137 (symbol_ref "TARGET_MIX_SSE_I387")
13138 (const_string "*"))
13139 (if_then_else
13140 (eq_attr "alternative" "3,4")
13141 (symbol_ref "true")
13142 (symbol_ref "false"))))])
13143
13144 (define_split
13145 [(set (match_operand:MODEF 0 "sse_reg_operand")
13146 (absneg:MODEF
13147 (match_operand:MODEF 1 "sse_reg_operand")))
13148 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13149 (clobber (reg:CC FLAGS_REG))]
13150 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13151 && reload_completed"
13152 [(set (match_dup 0)
13153 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13154 {
13155 machine_mode mode = <MODE>mode;
13156 machine_mode vmode = <ssevecmodef>mode;
13157
13158 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13159 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13160
13161 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13162 std::swap (operands[1], operands[2]);
13163 })
13164
13165 (define_split
13166 [(set (match_operand:MODEF 0 "fp_register_operand")
13167 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13168 (use (match_operand 2))
13169 (clobber (reg:CC FLAGS_REG))]
13170 "TARGET_80387 && reload_completed"
13171 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13172
13173 (define_split
13174 [(set (match_operand:MODEF 0 "general_reg_operand")
13175 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13176 (use (match_operand 2))
13177 (clobber (reg:CC FLAGS_REG))]
13178 "TARGET_80387 && reload_completed"
13179 [(const_int 0)]
13180 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13181
13182 (define_insn_and_split "*nabs<mode>2_1"
13183 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13184 (neg:MODEF
13185 (abs:MODEF
13186 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13187 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13188 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13189 "#"
13190 "&& reload_completed"
13191 [(set (match_dup 0)
13192 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13193 {
13194 machine_mode mode = <MODE>mode;
13195 machine_mode vmode = <ssevecmodef>mode;
13196
13197 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13198 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13199
13200 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13201 std::swap (operands[1], operands[2]);
13202 }
13203 [(set_attr "isa" "noavx,noavx,avx")])
13204
13205 ;; Conditionalize these after reload. If they match before reload, we
13206 ;; lose the clobber and ability to use integer instructions.
13207
13208 (define_insn "*<code><mode>2_i387"
13209 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13210 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13211 "TARGET_80387 && reload_completed"
13212 "<absneg_mnemonic>"
13213 [(set_attr "type" "fsgn")
13214 (set_attr "mode" "<MODE>")])
13215
13216 ;; Copysign instructions
13217
13218 (define_expand "copysign<mode>3"
13219 [(match_operand:SSEMODEF 0 "register_operand")
13220 (match_operand:SSEMODEF 1 "nonmemory_operand")
13221 (match_operand:SSEMODEF 2 "register_operand")]
13222 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13223 || (TARGET_SSE && (<MODE>mode == TFmode))
13224 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13225 "ix86_expand_copysign (operands); DONE;")
13226
13227 (define_expand "xorsign<mode>3"
13228 [(match_operand:MODEFH 0 "register_operand")
13229 (match_operand:MODEFH 1 "register_operand")
13230 (match_operand:MODEFH 2 "register_operand")]
13231 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13232 || <MODE>mode == HFmode"
13233 {
13234 if (rtx_equal_p (operands[1], operands[2]))
13235 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13236 else
13237 ix86_expand_xorsign (operands);
13238 DONE;
13239 })
13240 \f
13241 ;; One complement instructions
13242
13243 (define_expand "one_cmpl<mode>2"
13244 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13245 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13246 ""
13247 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13248
13249 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13250 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13251 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13252 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13253 "#"
13254 "&& reload_completed"
13255 [(set (match_dup 0)
13256 (not:DWIH (match_dup 1)))
13257 (set (match_dup 2)
13258 (not:DWIH (match_dup 3)))]
13259 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13260
13261 (define_insn "*one_cmpl<mode>2_1"
13262 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13263 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13264 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13265 "@
13266 not{<imodesuffix>}\t%0
13267 #"
13268 [(set (attr "isa")
13269 (cond [(eq_attr "alternative" "1")
13270 (if_then_else (eq_attr "mode" "SI,DI")
13271 (const_string "avx512bw")
13272 (const_string "avx512f"))
13273 ]
13274 (const_string "*")))
13275 (set_attr "type" "negnot,msklog")
13276 (set_attr "mode" "<MODE>")])
13277
13278 (define_insn "*one_cmplsi2_1_zext"
13279 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13280 (zero_extend:DI
13281 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13282 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13283 "@
13284 not{l}\t%k0
13285 #"
13286 [(set_attr "isa" "x64,avx512bw")
13287 (set_attr "type" "negnot,msklog")
13288 (set_attr "mode" "SI,SI")])
13289
13290 (define_insn "*one_cmplqi2_1"
13291 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13292 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13293 "ix86_unary_operator_ok (NOT, QImode, operands)"
13294 "@
13295 not{b}\t%0
13296 not{l}\t%k0
13297 #"
13298 [(set_attr "isa" "*,*,avx512f")
13299 (set_attr "type" "negnot,negnot,msklog")
13300 (set (attr "mode")
13301 (cond [(eq_attr "alternative" "1")
13302 (const_string "SI")
13303 (and (eq_attr "alternative" "2")
13304 (match_test "!TARGET_AVX512DQ"))
13305 (const_string "HI")
13306 ]
13307 (const_string "QI")))
13308 ;; Potential partial reg stall on alternative 1.
13309 (set (attr "preferred_for_speed")
13310 (cond [(eq_attr "alternative" "1")
13311 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13312 (symbol_ref "true")))])
13313
13314 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13315 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13316 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13317 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13318 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13319 "@
13320 not{<imodesuffix>}\t%0
13321 #"
13322 "&& reload_completed"
13323 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13324 (set (strict_low_part (match_dup 0))
13325 (not:SWI12 (match_dup 0)))]
13326 ""
13327 [(set_attr "type" "negnot")
13328 (set_attr "mode" "<MODE>")])
13329
13330 (define_insn "*one_cmpl<mode>2_2"
13331 [(set (reg FLAGS_REG)
13332 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13333 (const_int 0)))
13334 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13335 (not:SWI (match_dup 1)))]
13336 "ix86_match_ccmode (insn, CCNOmode)
13337 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13338 "#"
13339 [(set_attr "type" "alu1")
13340 (set_attr "mode" "<MODE>")])
13341
13342 (define_split
13343 [(set (match_operand 0 "flags_reg_operand")
13344 (match_operator 2 "compare_operator"
13345 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13346 (const_int 0)]))
13347 (set (match_operand:SWI 1 "nonimmediate_operand")
13348 (not:SWI (match_dup 3)))]
13349 "ix86_match_ccmode (insn, CCNOmode)"
13350 [(parallel [(set (match_dup 0)
13351 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13352 (const_int 0)]))
13353 (set (match_dup 1)
13354 (xor:SWI (match_dup 3) (const_int -1)))])])
13355
13356 (define_insn "*one_cmplsi2_2_zext"
13357 [(set (reg FLAGS_REG)
13358 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13359 (const_int 0)))
13360 (set (match_operand:DI 0 "register_operand" "=r")
13361 (zero_extend:DI (not:SI (match_dup 1))))]
13362 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13363 && ix86_unary_operator_ok (NOT, SImode, operands)"
13364 "#"
13365 [(set_attr "type" "alu1")
13366 (set_attr "mode" "SI")])
13367
13368 (define_split
13369 [(set (match_operand 0 "flags_reg_operand")
13370 (match_operator 2 "compare_operator"
13371 [(not:SI (match_operand:SI 3 "register_operand"))
13372 (const_int 0)]))
13373 (set (match_operand:DI 1 "register_operand")
13374 (zero_extend:DI (not:SI (match_dup 3))))]
13375 "ix86_match_ccmode (insn, CCNOmode)"
13376 [(parallel [(set (match_dup 0)
13377 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13378 (const_int 0)]))
13379 (set (match_dup 1)
13380 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13381 \f
13382 ;; Shift instructions
13383
13384 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13385 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13386 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13387 ;; from the assembler input.
13388 ;;
13389 ;; This instruction shifts the target reg/mem as usual, but instead of
13390 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13391 ;; is a left shift double, bits are taken from the high order bits of
13392 ;; reg, else if the insn is a shift right double, bits are taken from the
13393 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13394 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13395 ;;
13396 ;; Since sh[lr]d does not change the `reg' operand, that is done
13397 ;; separately, making all shifts emit pairs of shift double and normal
13398 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13399 ;; support a 63 bit shift, each shift where the count is in a reg expands
13400 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13401 ;;
13402 ;; If the shift count is a constant, we need never emit more than one
13403 ;; shift pair, instead using moves and sign extension for counts greater
13404 ;; than 31.
13405
13406 (define_expand "ashl<mode>3"
13407 [(set (match_operand:SDWIM 0 "<shift_operand>")
13408 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13409 (match_operand:QI 2 "nonmemory_operand")))]
13410 ""
13411 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13412
13413 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13414 [(set (match_operand:<DWI> 0 "register_operand")
13415 (ashift:<DWI>
13416 (match_operand:<DWI> 1 "register_operand")
13417 (subreg:QI
13418 (and
13419 (match_operand 2 "int248_register_operand" "c")
13420 (match_operand 3 "const_int_operand")) 0)))
13421 (clobber (reg:CC FLAGS_REG))]
13422 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13423 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13424 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13425 && ix86_pre_reload_split ()"
13426 "#"
13427 "&& 1"
13428 [(parallel
13429 [(set (match_dup 6)
13430 (ior:DWIH (ashift:DWIH (match_dup 6)
13431 (and:QI (match_dup 2) (match_dup 8)))
13432 (subreg:DWIH
13433 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13434 (minus:QI (match_dup 9)
13435 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13436 (clobber (reg:CC FLAGS_REG))])
13437 (parallel
13438 [(set (match_dup 4)
13439 (ashift:DWIH (match_dup 5) (match_dup 2)))
13440 (clobber (reg:CC FLAGS_REG))])]
13441 {
13442 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13443 {
13444 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13445 operands[2] = gen_lowpart (QImode, operands[2]);
13446 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13447 operands[2]));
13448 DONE;
13449 }
13450
13451 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13452
13453 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13454 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13455
13456 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13457 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13458 {
13459 rtx xops[3];
13460 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13461 xops[1] = operands[2];
13462 xops[2] = GEN_INT (INTVAL (operands[3])
13463 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13464 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13465 operands[2] = xops[0];
13466 }
13467
13468 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13469 operands[2] = gen_lowpart (QImode, operands[2]);
13470
13471 if (!rtx_equal_p (operands[6], operands[7]))
13472 emit_move_insn (operands[6], operands[7]);
13473 })
13474
13475 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13476 [(set (match_operand:<DWI> 0 "register_operand")
13477 (ashift:<DWI>
13478 (match_operand:<DWI> 1 "register_operand")
13479 (and:QI
13480 (match_operand:QI 2 "register_operand" "c")
13481 (match_operand:QI 3 "const_int_operand"))))
13482 (clobber (reg:CC FLAGS_REG))]
13483 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13484 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13485 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13486 && ix86_pre_reload_split ()"
13487 "#"
13488 "&& 1"
13489 [(parallel
13490 [(set (match_dup 6)
13491 (ior:DWIH (ashift:DWIH (match_dup 6)
13492 (and:QI (match_dup 2) (match_dup 8)))
13493 (subreg:DWIH
13494 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13495 (minus:QI (match_dup 9)
13496 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13497 (clobber (reg:CC FLAGS_REG))])
13498 (parallel
13499 [(set (match_dup 4)
13500 (ashift:DWIH (match_dup 5) (match_dup 2)))
13501 (clobber (reg:CC FLAGS_REG))])]
13502 {
13503 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13504 {
13505 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13506 operands[2]));
13507 DONE;
13508 }
13509
13510 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13511
13512 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13513 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13514
13515 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13516 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13517 {
13518 rtx tem = gen_reg_rtx (QImode);
13519 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13520 operands[2] = tem;
13521 }
13522
13523 if (!rtx_equal_p (operands[6], operands[7]))
13524 emit_move_insn (operands[6], operands[7]);
13525 })
13526
13527 (define_insn "ashl<mode>3_doubleword"
13528 [(set (match_operand:DWI 0 "register_operand" "=&r")
13529 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13530 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13531 (clobber (reg:CC FLAGS_REG))]
13532 ""
13533 "#"
13534 [(set_attr "type" "multi")])
13535
13536 (define_split
13537 [(set (match_operand:DWI 0 "register_operand")
13538 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13539 (match_operand:QI 2 "nonmemory_operand")))
13540 (clobber (reg:CC FLAGS_REG))]
13541 "epilogue_completed"
13542 [(const_int 0)]
13543 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13544
13545 ;; By default we don't ask for a scratch register, because when DWImode
13546 ;; values are manipulated, registers are already at a premium. But if
13547 ;; we have one handy, we won't turn it away.
13548
13549 (define_peephole2
13550 [(match_scratch:DWIH 3 "r")
13551 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13552 (ashift:<DWI>
13553 (match_operand:<DWI> 1 "nonmemory_operand")
13554 (match_operand:QI 2 "nonmemory_operand")))
13555 (clobber (reg:CC FLAGS_REG))])
13556 (match_dup 3)]
13557 "TARGET_CMOVE"
13558 [(const_int 0)]
13559 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13560
13561 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13562 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13563 (ashift:<DWI>
13564 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13565 (match_operand:QI 2 "const_int_operand")))
13566 (clobber (reg:CC FLAGS_REG))]
13567 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13568 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13569 "#"
13570 "&& reload_completed"
13571 [(const_int 0)]
13572 {
13573 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13574 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13575 if (!rtx_equal_p (operands[3], operands[1]))
13576 emit_move_insn (operands[3], operands[1]);
13577 if (bits > 0)
13578 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13579 ix86_expand_clear (operands[0]);
13580 DONE;
13581 })
13582
13583 (define_insn "x86_64_shld"
13584 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13585 (ior:DI (ashift:DI (match_dup 0)
13586 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13587 (const_int 63)))
13588 (subreg:DI
13589 (lshiftrt:TI
13590 (zero_extend:TI
13591 (match_operand:DI 1 "register_operand" "r"))
13592 (minus:QI (const_int 64)
13593 (and:QI (match_dup 2) (const_int 63)))) 0)))
13594 (clobber (reg:CC FLAGS_REG))]
13595 "TARGET_64BIT"
13596 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13597 [(set_attr "type" "ishift")
13598 (set_attr "prefix_0f" "1")
13599 (set_attr "mode" "DI")
13600 (set_attr "athlon_decode" "vector")
13601 (set_attr "amdfam10_decode" "vector")
13602 (set_attr "bdver1_decode" "vector")])
13603
13604 (define_insn "x86_64_shld_1"
13605 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13606 (ior:DI (ashift:DI (match_dup 0)
13607 (match_operand:QI 2 "const_0_to_63_operand"))
13608 (subreg:DI
13609 (lshiftrt:TI
13610 (zero_extend:TI
13611 (match_operand:DI 1 "register_operand" "r"))
13612 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13613 (clobber (reg:CC FLAGS_REG))]
13614 "TARGET_64BIT
13615 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13616 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13617 [(set_attr "type" "ishift")
13618 (set_attr "prefix_0f" "1")
13619 (set_attr "mode" "DI")
13620 (set_attr "length_immediate" "1")
13621 (set_attr "athlon_decode" "vector")
13622 (set_attr "amdfam10_decode" "vector")
13623 (set_attr "bdver1_decode" "vector")])
13624
13625 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13626 [(set (match_operand:DI 0 "nonimmediate_operand")
13627 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13628 (match_operand:QI 2 "const_0_to_63_operand"))
13629 (lshiftrt:DI
13630 (match_operand:DI 1 "nonimmediate_operand")
13631 (match_operand:QI 3 "const_0_to_63_operand"))))
13632 (clobber (reg:CC FLAGS_REG))]
13633 "TARGET_64BIT
13634 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13635 && ix86_pre_reload_split ()"
13636 "#"
13637 "&& 1"
13638 [(const_int 0)]
13639 {
13640 if (rtx_equal_p (operands[4], operands[0]))
13641 {
13642 operands[1] = force_reg (DImode, operands[1]);
13643 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13644 }
13645 else if (rtx_equal_p (operands[1], operands[0]))
13646 {
13647 operands[4] = force_reg (DImode, operands[4]);
13648 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13649 }
13650 else
13651 {
13652 operands[1] = force_reg (DImode, operands[1]);
13653 rtx tmp = gen_reg_rtx (DImode);
13654 emit_move_insn (tmp, operands[4]);
13655 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13656 emit_move_insn (operands[0], tmp);
13657 }
13658 DONE;
13659 })
13660
13661 (define_insn_and_split "*x86_64_shld_2"
13662 [(set (match_operand:DI 0 "nonimmediate_operand")
13663 (ior:DI (ashift:DI (match_dup 0)
13664 (match_operand:QI 2 "nonmemory_operand"))
13665 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13666 (minus:QI (const_int 64) (match_dup 2)))))
13667 (clobber (reg:CC FLAGS_REG))]
13668 "TARGET_64BIT && ix86_pre_reload_split ()"
13669 "#"
13670 "&& 1"
13671 [(parallel [(set (match_dup 0)
13672 (ior:DI (ashift:DI (match_dup 0)
13673 (and:QI (match_dup 2) (const_int 63)))
13674 (subreg:DI
13675 (lshiftrt:TI
13676 (zero_extend:TI (match_dup 1))
13677 (minus:QI (const_int 64)
13678 (and:QI (match_dup 2)
13679 (const_int 63)))) 0)))
13680 (clobber (reg:CC FLAGS_REG))])])
13681
13682 (define_insn "x86_shld"
13683 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13684 (ior:SI (ashift:SI (match_dup 0)
13685 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13686 (const_int 31)))
13687 (subreg:SI
13688 (lshiftrt:DI
13689 (zero_extend:DI
13690 (match_operand:SI 1 "register_operand" "r"))
13691 (minus:QI (const_int 32)
13692 (and:QI (match_dup 2) (const_int 31)))) 0)))
13693 (clobber (reg:CC FLAGS_REG))]
13694 ""
13695 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13696 [(set_attr "type" "ishift")
13697 (set_attr "prefix_0f" "1")
13698 (set_attr "mode" "SI")
13699 (set_attr "pent_pair" "np")
13700 (set_attr "athlon_decode" "vector")
13701 (set_attr "amdfam10_decode" "vector")
13702 (set_attr "bdver1_decode" "vector")])
13703
13704 (define_insn "x86_shld_1"
13705 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13706 (ior:SI (ashift:SI (match_dup 0)
13707 (match_operand:QI 2 "const_0_to_31_operand"))
13708 (subreg:SI
13709 (lshiftrt:DI
13710 (zero_extend:DI
13711 (match_operand:SI 1 "register_operand" "r"))
13712 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13713 (clobber (reg:CC FLAGS_REG))]
13714 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13715 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13716 [(set_attr "type" "ishift")
13717 (set_attr "prefix_0f" "1")
13718 (set_attr "length_immediate" "1")
13719 (set_attr "mode" "SI")
13720 (set_attr "pent_pair" "np")
13721 (set_attr "athlon_decode" "vector")
13722 (set_attr "amdfam10_decode" "vector")
13723 (set_attr "bdver1_decode" "vector")])
13724
13725 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13726 [(set (match_operand:SI 0 "nonimmediate_operand")
13727 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13728 (match_operand:QI 2 "const_0_to_31_operand"))
13729 (lshiftrt:SI
13730 (match_operand:SI 1 "nonimmediate_operand")
13731 (match_operand:QI 3 "const_0_to_31_operand"))))
13732 (clobber (reg:CC FLAGS_REG))]
13733 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
13734 && ix86_pre_reload_split ()"
13735 "#"
13736 "&& 1"
13737 [(const_int 0)]
13738 {
13739 if (rtx_equal_p (operands[4], operands[0]))
13740 {
13741 operands[1] = force_reg (SImode, operands[1]);
13742 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13743 }
13744 else if (rtx_equal_p (operands[1], operands[0]))
13745 {
13746 operands[4] = force_reg (SImode, operands[4]);
13747 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13748 }
13749 else
13750 {
13751 operands[1] = force_reg (SImode, operands[1]);
13752 rtx tmp = gen_reg_rtx (SImode);
13753 emit_move_insn (tmp, operands[4]);
13754 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
13755 emit_move_insn (operands[0], tmp);
13756 }
13757 DONE;
13758 })
13759
13760 (define_insn_and_split "*x86_shld_2"
13761 [(set (match_operand:SI 0 "nonimmediate_operand")
13762 (ior:SI (ashift:SI (match_dup 0)
13763 (match_operand:QI 2 "nonmemory_operand"))
13764 (lshiftrt:SI (match_operand:SI 1 "register_operand")
13765 (minus:QI (const_int 32) (match_dup 2)))))
13766 (clobber (reg:CC FLAGS_REG))]
13767 "TARGET_64BIT && ix86_pre_reload_split ()"
13768 "#"
13769 "&& 1"
13770 [(parallel [(set (match_dup 0)
13771 (ior:SI (ashift:SI (match_dup 0)
13772 (and:QI (match_dup 2) (const_int 31)))
13773 (subreg:SI
13774 (lshiftrt:DI
13775 (zero_extend:DI (match_dup 1))
13776 (minus:QI (const_int 32)
13777 (and:QI (match_dup 2)
13778 (const_int 31)))) 0)))
13779 (clobber (reg:CC FLAGS_REG))])])
13780
13781 (define_expand "@x86_shift<mode>_adj_1"
13782 [(set (reg:CCZ FLAGS_REG)
13783 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
13784 (match_dup 4))
13785 (const_int 0)))
13786 (set (match_operand:SWI48 0 "register_operand")
13787 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13788 (match_operand:SWI48 1 "register_operand")
13789 (match_dup 0)))
13790 (set (match_dup 1)
13791 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13792 (match_operand:SWI48 3 "register_operand")
13793 (match_dup 1)))]
13794 "TARGET_CMOVE"
13795 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
13796
13797 (define_expand "@x86_shift<mode>_adj_2"
13798 [(use (match_operand:SWI48 0 "register_operand"))
13799 (use (match_operand:SWI48 1 "register_operand"))
13800 (use (match_operand:QI 2 "register_operand"))]
13801 ""
13802 {
13803 rtx_code_label *label = gen_label_rtx ();
13804 rtx tmp;
13805
13806 emit_insn (gen_testqi_ccz_1 (operands[2],
13807 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
13808
13809 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13810 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13811 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13812 gen_rtx_LABEL_REF (VOIDmode, label),
13813 pc_rtx);
13814 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
13815 JUMP_LABEL (tmp) = label;
13816
13817 emit_move_insn (operands[0], operands[1]);
13818 ix86_expand_clear (operands[1]);
13819
13820 emit_label (label);
13821 LABEL_NUSES (label) = 1;
13822
13823 DONE;
13824 })
13825
13826 ;; Avoid useless masking of count operand.
13827 (define_insn_and_split "*ashl<mode>3_mask"
13828 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13829 (ashift:SWI48
13830 (match_operand:SWI48 1 "nonimmediate_operand")
13831 (subreg:QI
13832 (and
13833 (match_operand 2 "int248_register_operand" "c,r")
13834 (match_operand 3 "const_int_operand")) 0)))
13835 (clobber (reg:CC FLAGS_REG))]
13836 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13837 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13838 == GET_MODE_BITSIZE (<MODE>mode)-1
13839 && ix86_pre_reload_split ()"
13840 "#"
13841 "&& 1"
13842 [(parallel
13843 [(set (match_dup 0)
13844 (ashift:SWI48 (match_dup 1)
13845 (match_dup 2)))
13846 (clobber (reg:CC FLAGS_REG))])]
13847 {
13848 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13849 operands[2] = gen_lowpart (QImode, operands[2]);
13850 }
13851 [(set_attr "isa" "*,bmi2")])
13852
13853 (define_insn_and_split "*ashl<mode>3_mask_1"
13854 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13855 (ashift:SWI48
13856 (match_operand:SWI48 1 "nonimmediate_operand")
13857 (and:QI
13858 (match_operand:QI 2 "register_operand" "c,r")
13859 (match_operand:QI 3 "const_int_operand"))))
13860 (clobber (reg:CC FLAGS_REG))]
13861 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13862 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13863 == GET_MODE_BITSIZE (<MODE>mode)-1
13864 && ix86_pre_reload_split ()"
13865 "#"
13866 "&& 1"
13867 [(parallel
13868 [(set (match_dup 0)
13869 (ashift:SWI48 (match_dup 1)
13870 (match_dup 2)))
13871 (clobber (reg:CC FLAGS_REG))])]
13872 ""
13873 [(set_attr "isa" "*,bmi2")])
13874
13875 (define_insn "*bmi2_ashl<mode>3_1"
13876 [(set (match_operand:SWI48 0 "register_operand" "=r")
13877 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13878 (match_operand:SWI48 2 "register_operand" "r")))]
13879 "TARGET_BMI2"
13880 "shlx\t{%2, %1, %0|%0, %1, %2}"
13881 [(set_attr "type" "ishiftx")
13882 (set_attr "mode" "<MODE>")])
13883
13884 (define_insn "*ashl<mode>3_1"
13885 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
13886 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
13887 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
13888 (clobber (reg:CC FLAGS_REG))]
13889 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
13890 {
13891 switch (get_attr_type (insn))
13892 {
13893 case TYPE_LEA:
13894 case TYPE_ISHIFTX:
13895 case TYPE_MSKLOG:
13896 return "#";
13897
13898 case TYPE_ALU:
13899 gcc_assert (operands[2] == const1_rtx);
13900 gcc_assert (rtx_equal_p (operands[0], operands[1]));
13901 return "add{<imodesuffix>}\t%0, %0";
13902
13903 default:
13904 if (operands[2] == const1_rtx
13905 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13906 return "sal{<imodesuffix>}\t%0";
13907 else
13908 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
13909 }
13910 }
13911 [(set_attr "isa" "*,*,bmi2,avx512bw")
13912 (set (attr "type")
13913 (cond [(eq_attr "alternative" "1")
13914 (const_string "lea")
13915 (eq_attr "alternative" "2")
13916 (const_string "ishiftx")
13917 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
13918 (match_operand 0 "register_operand"))
13919 (match_operand 2 "const1_operand"))
13920 (const_string "alu")
13921 (eq_attr "alternative" "3")
13922 (const_string "msklog")
13923 ]
13924 (const_string "ishift")))
13925 (set (attr "length_immediate")
13926 (if_then_else
13927 (ior (eq_attr "type" "alu")
13928 (and (eq_attr "type" "ishift")
13929 (and (match_operand 2 "const1_operand")
13930 (ior (match_test "TARGET_SHIFT1")
13931 (match_test "optimize_function_for_size_p (cfun)")))))
13932 (const_string "0")
13933 (const_string "*")))
13934 (set_attr "mode" "<MODE>")])
13935
13936 ;; Convert shift to the shiftx pattern to avoid flags dependency.
13937 (define_split
13938 [(set (match_operand:SWI48 0 "register_operand")
13939 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
13940 (match_operand:QI 2 "register_operand")))
13941 (clobber (reg:CC FLAGS_REG))]
13942 "TARGET_BMI2 && reload_completed"
13943 [(set (match_dup 0)
13944 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
13945 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
13946
13947 (define_insn "*bmi2_ashlsi3_1_zext"
13948 [(set (match_operand:DI 0 "register_operand" "=r")
13949 (zero_extend:DI
13950 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
13951 (match_operand:SI 2 "register_operand" "r"))))]
13952 "TARGET_64BIT && TARGET_BMI2"
13953 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
13954 [(set_attr "type" "ishiftx")
13955 (set_attr "mode" "SI")])
13956
13957 (define_insn "*ashlsi3_1_zext"
13958 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
13959 (zero_extend:DI
13960 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
13961 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
13962 (clobber (reg:CC FLAGS_REG))]
13963 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
13964 {
13965 switch (get_attr_type (insn))
13966 {
13967 case TYPE_LEA:
13968 case TYPE_ISHIFTX:
13969 return "#";
13970
13971 case TYPE_ALU:
13972 gcc_assert (operands[2] == const1_rtx);
13973 return "add{l}\t%k0, %k0";
13974
13975 default:
13976 if (operands[2] == const1_rtx
13977 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13978 return "sal{l}\t%k0";
13979 else
13980 return "sal{l}\t{%2, %k0|%k0, %2}";
13981 }
13982 }
13983 [(set_attr "isa" "*,*,bmi2")
13984 (set (attr "type")
13985 (cond [(eq_attr "alternative" "1")
13986 (const_string "lea")
13987 (eq_attr "alternative" "2")
13988 (const_string "ishiftx")
13989 (and (match_test "TARGET_DOUBLE_WITH_ADD")
13990 (match_operand 2 "const1_operand"))
13991 (const_string "alu")
13992 ]
13993 (const_string "ishift")))
13994 (set (attr "length_immediate")
13995 (if_then_else
13996 (ior (eq_attr "type" "alu")
13997 (and (eq_attr "type" "ishift")
13998 (and (match_operand 2 "const1_operand")
13999 (ior (match_test "TARGET_SHIFT1")
14000 (match_test "optimize_function_for_size_p (cfun)")))))
14001 (const_string "0")
14002 (const_string "*")))
14003 (set_attr "mode" "SI")])
14004
14005 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14006 (define_split
14007 [(set (match_operand:DI 0 "register_operand")
14008 (zero_extend:DI
14009 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
14010 (match_operand:QI 2 "register_operand"))))
14011 (clobber (reg:CC FLAGS_REG))]
14012 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14013 [(set (match_dup 0)
14014 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14015 "operands[2] = gen_lowpart (SImode, operands[2]);")
14016
14017 (define_insn "*ashlhi3_1"
14018 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
14019 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
14020 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
14021 (clobber (reg:CC FLAGS_REG))]
14022 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
14023 {
14024 switch (get_attr_type (insn))
14025 {
14026 case TYPE_LEA:
14027 case TYPE_MSKLOG:
14028 return "#";
14029
14030 case TYPE_ALU:
14031 gcc_assert (operands[2] == const1_rtx);
14032 return "add{w}\t%0, %0";
14033
14034 default:
14035 if (operands[2] == const1_rtx
14036 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14037 return "sal{w}\t%0";
14038 else
14039 return "sal{w}\t{%2, %0|%0, %2}";
14040 }
14041 }
14042 [(set_attr "isa" "*,*,avx512f")
14043 (set (attr "type")
14044 (cond [(eq_attr "alternative" "1")
14045 (const_string "lea")
14046 (eq_attr "alternative" "2")
14047 (const_string "msklog")
14048 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14049 (match_operand 0 "register_operand"))
14050 (match_operand 2 "const1_operand"))
14051 (const_string "alu")
14052 ]
14053 (const_string "ishift")))
14054 (set (attr "length_immediate")
14055 (if_then_else
14056 (ior (eq_attr "type" "alu")
14057 (and (eq_attr "type" "ishift")
14058 (and (match_operand 2 "const1_operand")
14059 (ior (match_test "TARGET_SHIFT1")
14060 (match_test "optimize_function_for_size_p (cfun)")))))
14061 (const_string "0")
14062 (const_string "*")))
14063 (set_attr "mode" "HI,SI,HI")])
14064
14065 (define_insn "*ashlqi3_1"
14066 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
14067 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
14068 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
14069 (clobber (reg:CC FLAGS_REG))]
14070 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14071 {
14072 switch (get_attr_type (insn))
14073 {
14074 case TYPE_LEA:
14075 case TYPE_MSKLOG:
14076 return "#";
14077
14078 case TYPE_ALU:
14079 gcc_assert (operands[2] == const1_rtx);
14080 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14081 return "add{l}\t%k0, %k0";
14082 else
14083 return "add{b}\t%0, %0";
14084
14085 default:
14086 if (operands[2] == const1_rtx
14087 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14088 {
14089 if (get_attr_mode (insn) == MODE_SI)
14090 return "sal{l}\t%k0";
14091 else
14092 return "sal{b}\t%0";
14093 }
14094 else
14095 {
14096 if (get_attr_mode (insn) == MODE_SI)
14097 return "sal{l}\t{%2, %k0|%k0, %2}";
14098 else
14099 return "sal{b}\t{%2, %0|%0, %2}";
14100 }
14101 }
14102 }
14103 [(set_attr "isa" "*,*,*,avx512dq")
14104 (set (attr "type")
14105 (cond [(eq_attr "alternative" "2")
14106 (const_string "lea")
14107 (eq_attr "alternative" "3")
14108 (const_string "msklog")
14109 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14110 (match_operand 0 "register_operand"))
14111 (match_operand 2 "const1_operand"))
14112 (const_string "alu")
14113 ]
14114 (const_string "ishift")))
14115 (set (attr "length_immediate")
14116 (if_then_else
14117 (ior (eq_attr "type" "alu")
14118 (and (eq_attr "type" "ishift")
14119 (and (match_operand 2 "const1_operand")
14120 (ior (match_test "TARGET_SHIFT1")
14121 (match_test "optimize_function_for_size_p (cfun)")))))
14122 (const_string "0")
14123 (const_string "*")))
14124 (set_attr "mode" "QI,SI,SI,QI")
14125 ;; Potential partial reg stall on alternative 1.
14126 (set (attr "preferred_for_speed")
14127 (cond [(eq_attr "alternative" "1")
14128 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14129 (symbol_ref "true")))])
14130
14131 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14132 (define_insn_and_split "*ashl<mode>3_1_slp"
14133 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14134 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14135 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14136 (clobber (reg:CC FLAGS_REG))]
14137 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14138 {
14139 if (which_alternative)
14140 return "#";
14141
14142 switch (get_attr_type (insn))
14143 {
14144 case TYPE_ALU:
14145 gcc_assert (operands[2] == const1_rtx);
14146 return "add{<imodesuffix>}\t%0, %0";
14147
14148 default:
14149 if (operands[2] == const1_rtx
14150 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14151 return "sal{<imodesuffix>}\t%0";
14152 else
14153 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14154 }
14155 }
14156 "&& reload_completed"
14157 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14158 (parallel
14159 [(set (strict_low_part (match_dup 0))
14160 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14161 (clobber (reg:CC FLAGS_REG))])]
14162 ""
14163 [(set (attr "type")
14164 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14165 (match_operand 2 "const1_operand"))
14166 (const_string "alu")
14167 ]
14168 (const_string "ishift")))
14169 (set (attr "length_immediate")
14170 (if_then_else
14171 (ior (eq_attr "type" "alu")
14172 (and (eq_attr "type" "ishift")
14173 (and (match_operand 2 "const1_operand")
14174 (ior (match_test "TARGET_SHIFT1")
14175 (match_test "optimize_function_for_size_p (cfun)")))))
14176 (const_string "0")
14177 (const_string "*")))
14178 (set_attr "mode" "<MODE>")])
14179
14180 ;; Convert ashift to the lea pattern to avoid flags dependency.
14181 (define_split
14182 [(set (match_operand:SWI 0 "general_reg_operand")
14183 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14184 (match_operand 2 "const_0_to_3_operand")))
14185 (clobber (reg:CC FLAGS_REG))]
14186 "reload_completed
14187 && REGNO (operands[0]) != REGNO (operands[1])"
14188 [(set (match_dup 0)
14189 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14190 {
14191 if (<MODE>mode != <LEAMODE>mode)
14192 {
14193 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14194 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14195 }
14196 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14197 })
14198
14199 ;; Convert ashift to the lea pattern to avoid flags dependency.
14200 (define_split
14201 [(set (match_operand:DI 0 "general_reg_operand")
14202 (zero_extend:DI
14203 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14204 (match_operand 2 "const_0_to_3_operand"))))
14205 (clobber (reg:CC FLAGS_REG))]
14206 "TARGET_64BIT && reload_completed
14207 && REGNO (operands[0]) != REGNO (operands[1])"
14208 [(set (match_dup 0)
14209 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14210 {
14211 operands[1] = gen_lowpart (SImode, operands[1]);
14212 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14213 })
14214
14215 ;; This pattern can't accept a variable shift count, since shifts by
14216 ;; zero don't affect the flags. We assume that shifts by constant
14217 ;; zero are optimized away.
14218 (define_insn "*ashl<mode>3_cmp"
14219 [(set (reg FLAGS_REG)
14220 (compare
14221 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14222 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14223 (const_int 0)))
14224 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14225 (ashift:SWI (match_dup 1) (match_dup 2)))]
14226 "(optimize_function_for_size_p (cfun)
14227 || !TARGET_PARTIAL_FLAG_REG_STALL
14228 || (operands[2] == const1_rtx
14229 && (TARGET_SHIFT1
14230 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14231 && ix86_match_ccmode (insn, CCGOCmode)
14232 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14233 {
14234 switch (get_attr_type (insn))
14235 {
14236 case TYPE_ALU:
14237 gcc_assert (operands[2] == const1_rtx);
14238 return "add{<imodesuffix>}\t%0, %0";
14239
14240 default:
14241 if (operands[2] == const1_rtx
14242 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14243 return "sal{<imodesuffix>}\t%0";
14244 else
14245 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14246 }
14247 }
14248 [(set (attr "type")
14249 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14250 (match_operand 0 "register_operand"))
14251 (match_operand 2 "const1_operand"))
14252 (const_string "alu")
14253 ]
14254 (const_string "ishift")))
14255 (set (attr "length_immediate")
14256 (if_then_else
14257 (ior (eq_attr "type" "alu")
14258 (and (eq_attr "type" "ishift")
14259 (and (match_operand 2 "const1_operand")
14260 (ior (match_test "TARGET_SHIFT1")
14261 (match_test "optimize_function_for_size_p (cfun)")))))
14262 (const_string "0")
14263 (const_string "*")))
14264 (set_attr "mode" "<MODE>")])
14265
14266 (define_insn "*ashlsi3_cmp_zext"
14267 [(set (reg FLAGS_REG)
14268 (compare
14269 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14270 (match_operand:QI 2 "const_1_to_31_operand"))
14271 (const_int 0)))
14272 (set (match_operand:DI 0 "register_operand" "=r")
14273 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14274 "TARGET_64BIT
14275 && (optimize_function_for_size_p (cfun)
14276 || !TARGET_PARTIAL_FLAG_REG_STALL
14277 || (operands[2] == const1_rtx
14278 && (TARGET_SHIFT1
14279 || TARGET_DOUBLE_WITH_ADD)))
14280 && ix86_match_ccmode (insn, CCGOCmode)
14281 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14282 {
14283 switch (get_attr_type (insn))
14284 {
14285 case TYPE_ALU:
14286 gcc_assert (operands[2] == const1_rtx);
14287 return "add{l}\t%k0, %k0";
14288
14289 default:
14290 if (operands[2] == const1_rtx
14291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14292 return "sal{l}\t%k0";
14293 else
14294 return "sal{l}\t{%2, %k0|%k0, %2}";
14295 }
14296 }
14297 [(set (attr "type")
14298 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14299 (match_operand 2 "const1_operand"))
14300 (const_string "alu")
14301 ]
14302 (const_string "ishift")))
14303 (set (attr "length_immediate")
14304 (if_then_else
14305 (ior (eq_attr "type" "alu")
14306 (and (eq_attr "type" "ishift")
14307 (and (match_operand 2 "const1_operand")
14308 (ior (match_test "TARGET_SHIFT1")
14309 (match_test "optimize_function_for_size_p (cfun)")))))
14310 (const_string "0")
14311 (const_string "*")))
14312 (set_attr "mode" "SI")])
14313
14314 (define_insn "*ashl<mode>3_cconly"
14315 [(set (reg FLAGS_REG)
14316 (compare
14317 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14318 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14319 (const_int 0)))
14320 (clobber (match_scratch:SWI 0 "=<r>"))]
14321 "(optimize_function_for_size_p (cfun)
14322 || !TARGET_PARTIAL_FLAG_REG_STALL
14323 || (operands[2] == const1_rtx
14324 && (TARGET_SHIFT1
14325 || TARGET_DOUBLE_WITH_ADD)))
14326 && ix86_match_ccmode (insn, CCGOCmode)"
14327 {
14328 switch (get_attr_type (insn))
14329 {
14330 case TYPE_ALU:
14331 gcc_assert (operands[2] == const1_rtx);
14332 return "add{<imodesuffix>}\t%0, %0";
14333
14334 default:
14335 if (operands[2] == const1_rtx
14336 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14337 return "sal{<imodesuffix>}\t%0";
14338 else
14339 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14340 }
14341 }
14342 [(set (attr "type")
14343 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14344 (match_operand 0 "register_operand"))
14345 (match_operand 2 "const1_operand"))
14346 (const_string "alu")
14347 ]
14348 (const_string "ishift")))
14349 (set (attr "length_immediate")
14350 (if_then_else
14351 (ior (eq_attr "type" "alu")
14352 (and (eq_attr "type" "ishift")
14353 (and (match_operand 2 "const1_operand")
14354 (ior (match_test "TARGET_SHIFT1")
14355 (match_test "optimize_function_for_size_p (cfun)")))))
14356 (const_string "0")
14357 (const_string "*")))
14358 (set_attr "mode" "<MODE>")])
14359
14360 (define_insn "*ashlqi_ext<mode>_2"
14361 [(set (zero_extract:SWI248
14362 (match_operand 0 "int248_register_operand" "+Q")
14363 (const_int 8)
14364 (const_int 8))
14365 (subreg:SWI248
14366 (ashift:QI
14367 (subreg:QI
14368 (match_operator:SWI248 3 "extract_operator"
14369 [(match_operand 1 "int248_register_operand" "0")
14370 (const_int 8)
14371 (const_int 8)]) 0)
14372 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
14373 (clobber (reg:CC FLAGS_REG))]
14374 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
14375 rtx_equal_p (operands[0], operands[1])"
14376 {
14377 switch (get_attr_type (insn))
14378 {
14379 case TYPE_ALU:
14380 gcc_assert (operands[2] == const1_rtx);
14381 return "add{b}\t%h0, %h0";
14382
14383 default:
14384 if (operands[2] == const1_rtx
14385 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14386 return "sal{b}\t%h0";
14387 else
14388 return "sal{b}\t{%2, %h0|%h0, %2}";
14389 }
14390 }
14391 [(set (attr "type")
14392 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14393 (match_operand 2 "const1_operand"))
14394 (const_string "alu")
14395 ]
14396 (const_string "ishift")))
14397 (set (attr "length_immediate")
14398 (if_then_else
14399 (ior (eq_attr "type" "alu")
14400 (and (eq_attr "type" "ishift")
14401 (and (match_operand 2 "const1_operand")
14402 (ior (match_test "TARGET_SHIFT1")
14403 (match_test "optimize_function_for_size_p (cfun)")))))
14404 (const_string "0")
14405 (const_string "*")))
14406 (set_attr "mode" "QI")])
14407
14408 ;; See comment above `ashl<mode>3' about how this works.
14409
14410 (define_expand "<insn><mode>3"
14411 [(set (match_operand:SDWIM 0 "<shift_operand>")
14412 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14413 (match_operand:QI 2 "nonmemory_operand")))]
14414 ""
14415 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14416
14417 ;; Avoid useless masking of count operand.
14418 (define_insn_and_split "*<insn><mode>3_mask"
14419 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14420 (any_shiftrt:SWI48
14421 (match_operand:SWI48 1 "nonimmediate_operand")
14422 (subreg:QI
14423 (and
14424 (match_operand 2 "int248_register_operand" "c,r")
14425 (match_operand 3 "const_int_operand")) 0)))
14426 (clobber (reg:CC FLAGS_REG))]
14427 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14428 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14429 == GET_MODE_BITSIZE (<MODE>mode)-1
14430 && ix86_pre_reload_split ()"
14431 "#"
14432 "&& 1"
14433 [(parallel
14434 [(set (match_dup 0)
14435 (any_shiftrt:SWI48 (match_dup 1)
14436 (match_dup 2)))
14437 (clobber (reg:CC FLAGS_REG))])]
14438 {
14439 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14440 operands[2] = gen_lowpart (QImode, operands[2]);
14441 }
14442 [(set_attr "isa" "*,bmi2")])
14443
14444 (define_insn_and_split "*<insn><mode>3_mask_1"
14445 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14446 (any_shiftrt:SWI48
14447 (match_operand:SWI48 1 "nonimmediate_operand")
14448 (and:QI
14449 (match_operand:QI 2 "register_operand" "c,r")
14450 (match_operand:QI 3 "const_int_operand"))))
14451 (clobber (reg:CC FLAGS_REG))]
14452 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14453 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14454 == GET_MODE_BITSIZE (<MODE>mode)-1
14455 && ix86_pre_reload_split ()"
14456 "#"
14457 "&& 1"
14458 [(parallel
14459 [(set (match_dup 0)
14460 (any_shiftrt:SWI48 (match_dup 1)
14461 (match_dup 2)))
14462 (clobber (reg:CC FLAGS_REG))])]
14463 ""
14464 [(set_attr "isa" "*,bmi2")])
14465
14466 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14467 [(set (match_operand:<DWI> 0 "register_operand")
14468 (any_shiftrt:<DWI>
14469 (match_operand:<DWI> 1 "register_operand")
14470 (subreg:QI
14471 (and
14472 (match_operand 2 "int248_register_operand" "c")
14473 (match_operand 3 "const_int_operand")) 0)))
14474 (clobber (reg:CC FLAGS_REG))]
14475 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14476 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14477 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14478 && ix86_pre_reload_split ()"
14479 "#"
14480 "&& 1"
14481 [(parallel
14482 [(set (match_dup 4)
14483 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14484 (and:QI (match_dup 2) (match_dup 8)))
14485 (subreg:DWIH
14486 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14487 (minus:QI (match_dup 9)
14488 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14489 (clobber (reg:CC FLAGS_REG))])
14490 (parallel
14491 [(set (match_dup 6)
14492 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14493 (clobber (reg:CC FLAGS_REG))])]
14494 {
14495 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14496 {
14497 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14498 operands[2] = gen_lowpart (QImode, operands[2]);
14499 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14500 operands[2]));
14501 DONE;
14502 }
14503
14504 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14505
14506 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14507 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14508
14509 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14510 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14511 {
14512 rtx xops[3];
14513 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14514 xops[1] = operands[2];
14515 xops[2] = GEN_INT (INTVAL (operands[3])
14516 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14517 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14518 operands[2] = xops[0];
14519 }
14520
14521 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14522 operands[2] = gen_lowpart (QImode, operands[2]);
14523
14524 if (!rtx_equal_p (operands[4], operands[5]))
14525 emit_move_insn (operands[4], operands[5]);
14526 })
14527
14528 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14529 [(set (match_operand:<DWI> 0 "register_operand")
14530 (any_shiftrt:<DWI>
14531 (match_operand:<DWI> 1 "register_operand")
14532 (and:QI
14533 (match_operand:QI 2 "register_operand" "c")
14534 (match_operand:QI 3 "const_int_operand"))))
14535 (clobber (reg:CC FLAGS_REG))]
14536 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14537 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14538 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14539 && ix86_pre_reload_split ()"
14540 "#"
14541 "&& 1"
14542 [(parallel
14543 [(set (match_dup 4)
14544 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14545 (and:QI (match_dup 2) (match_dup 8)))
14546 (subreg:DWIH
14547 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14548 (minus:QI (match_dup 9)
14549 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14550 (clobber (reg:CC FLAGS_REG))])
14551 (parallel
14552 [(set (match_dup 6)
14553 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14554 (clobber (reg:CC FLAGS_REG))])]
14555 {
14556 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14557 {
14558 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14559 operands[2]));
14560 DONE;
14561 }
14562
14563 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14564
14565 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14566 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14567
14568 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14569 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14570 {
14571 rtx tem = gen_reg_rtx (QImode);
14572 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14573 operands[2] = tem;
14574 }
14575
14576 if (!rtx_equal_p (operands[4], operands[5]))
14577 emit_move_insn (operands[4], operands[5]);
14578 })
14579
14580 (define_insn_and_split "<insn><mode>3_doubleword"
14581 [(set (match_operand:DWI 0 "register_operand" "=&r")
14582 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14583 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14584 (clobber (reg:CC FLAGS_REG))]
14585 ""
14586 "#"
14587 "epilogue_completed"
14588 [(const_int 0)]
14589 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14590 [(set_attr "type" "multi")])
14591
14592 ;; By default we don't ask for a scratch register, because when DWImode
14593 ;; values are manipulated, registers are already at a premium. But if
14594 ;; we have one handy, we won't turn it away.
14595
14596 (define_peephole2
14597 [(match_scratch:DWIH 3 "r")
14598 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14599 (any_shiftrt:<DWI>
14600 (match_operand:<DWI> 1 "register_operand")
14601 (match_operand:QI 2 "nonmemory_operand")))
14602 (clobber (reg:CC FLAGS_REG))])
14603 (match_dup 3)]
14604 "TARGET_CMOVE"
14605 [(const_int 0)]
14606 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14607
14608 (define_insn "x86_64_shrd"
14609 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14610 (ior:DI (lshiftrt:DI (match_dup 0)
14611 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14612 (const_int 63)))
14613 (subreg:DI
14614 (ashift:TI
14615 (zero_extend:TI
14616 (match_operand:DI 1 "register_operand" "r"))
14617 (minus:QI (const_int 64)
14618 (and:QI (match_dup 2) (const_int 63)))) 0)))
14619 (clobber (reg:CC FLAGS_REG))]
14620 "TARGET_64BIT"
14621 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14622 [(set_attr "type" "ishift")
14623 (set_attr "prefix_0f" "1")
14624 (set_attr "mode" "DI")
14625 (set_attr "athlon_decode" "vector")
14626 (set_attr "amdfam10_decode" "vector")
14627 (set_attr "bdver1_decode" "vector")])
14628
14629 (define_insn "x86_64_shrd_1"
14630 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14631 (ior:DI (lshiftrt:DI (match_dup 0)
14632 (match_operand:QI 2 "const_0_to_63_operand"))
14633 (subreg:DI
14634 (ashift:TI
14635 (zero_extend:TI
14636 (match_operand:DI 1 "register_operand" "r"))
14637 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14638 (clobber (reg:CC FLAGS_REG))]
14639 "TARGET_64BIT
14640 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14641 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14642 [(set_attr "type" "ishift")
14643 (set_attr "prefix_0f" "1")
14644 (set_attr "length_immediate" "1")
14645 (set_attr "mode" "DI")
14646 (set_attr "athlon_decode" "vector")
14647 (set_attr "amdfam10_decode" "vector")
14648 (set_attr "bdver1_decode" "vector")])
14649
14650 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14651 [(set (match_operand:DI 0 "nonimmediate_operand")
14652 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14653 (match_operand:QI 2 "const_0_to_63_operand"))
14654 (ashift:DI
14655 (match_operand:DI 1 "nonimmediate_operand")
14656 (match_operand:QI 3 "const_0_to_63_operand"))))
14657 (clobber (reg:CC FLAGS_REG))]
14658 "TARGET_64BIT
14659 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14660 && ix86_pre_reload_split ()"
14661 "#"
14662 "&& 1"
14663 [(const_int 0)]
14664 {
14665 if (rtx_equal_p (operands[4], operands[0]))
14666 {
14667 operands[1] = force_reg (DImode, operands[1]);
14668 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14669 }
14670 else if (rtx_equal_p (operands[1], operands[0]))
14671 {
14672 operands[4] = force_reg (DImode, operands[4]);
14673 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14674 }
14675 else
14676 {
14677 operands[1] = force_reg (DImode, operands[1]);
14678 rtx tmp = gen_reg_rtx (DImode);
14679 emit_move_insn (tmp, operands[4]);
14680 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14681 emit_move_insn (operands[0], tmp);
14682 }
14683 DONE;
14684 })
14685
14686 (define_insn_and_split "*x86_64_shrd_2"
14687 [(set (match_operand:DI 0 "nonimmediate_operand")
14688 (ior:DI (lshiftrt:DI (match_dup 0)
14689 (match_operand:QI 2 "nonmemory_operand"))
14690 (ashift:DI (match_operand:DI 1 "register_operand")
14691 (minus:QI (const_int 64) (match_dup 2)))))
14692 (clobber (reg:CC FLAGS_REG))]
14693 "TARGET_64BIT && ix86_pre_reload_split ()"
14694 "#"
14695 "&& 1"
14696 [(parallel [(set (match_dup 0)
14697 (ior:DI (lshiftrt:DI (match_dup 0)
14698 (and:QI (match_dup 2) (const_int 63)))
14699 (subreg:DI
14700 (ashift:TI
14701 (zero_extend:TI (match_dup 1))
14702 (minus:QI (const_int 64)
14703 (and:QI (match_dup 2)
14704 (const_int 63)))) 0)))
14705 (clobber (reg:CC FLAGS_REG))])])
14706
14707 (define_insn "x86_shrd"
14708 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14709 (ior:SI (lshiftrt:SI (match_dup 0)
14710 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14711 (const_int 31)))
14712 (subreg:SI
14713 (ashift:DI
14714 (zero_extend:DI
14715 (match_operand:SI 1 "register_operand" "r"))
14716 (minus:QI (const_int 32)
14717 (and:QI (match_dup 2) (const_int 31)))) 0)))
14718 (clobber (reg:CC FLAGS_REG))]
14719 ""
14720 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
14721 [(set_attr "type" "ishift")
14722 (set_attr "prefix_0f" "1")
14723 (set_attr "mode" "SI")
14724 (set_attr "pent_pair" "np")
14725 (set_attr "athlon_decode" "vector")
14726 (set_attr "amdfam10_decode" "vector")
14727 (set_attr "bdver1_decode" "vector")])
14728
14729 (define_insn "x86_shrd_1"
14730 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14731 (ior:SI (lshiftrt:SI (match_dup 0)
14732 (match_operand:QI 2 "const_0_to_31_operand"))
14733 (subreg:SI
14734 (ashift:DI
14735 (zero_extend:DI
14736 (match_operand:SI 1 "register_operand" "r"))
14737 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14738 (clobber (reg:CC FLAGS_REG))]
14739 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14740 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
14741 [(set_attr "type" "ishift")
14742 (set_attr "prefix_0f" "1")
14743 (set_attr "length_immediate" "1")
14744 (set_attr "mode" "SI")
14745 (set_attr "pent_pair" "np")
14746 (set_attr "athlon_decode" "vector")
14747 (set_attr "amdfam10_decode" "vector")
14748 (set_attr "bdver1_decode" "vector")])
14749
14750 (define_insn_and_split "*x86_shrd_shld_1_nozext"
14751 [(set (match_operand:SI 0 "nonimmediate_operand")
14752 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
14753 (match_operand:QI 2 "const_0_to_31_operand"))
14754 (ashift:SI
14755 (match_operand:SI 1 "nonimmediate_operand")
14756 (match_operand:QI 3 "const_0_to_31_operand"))))
14757 (clobber (reg:CC FLAGS_REG))]
14758 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14759 && ix86_pre_reload_split ()"
14760 "#"
14761 "&& 1"
14762 [(const_int 0)]
14763 {
14764 if (rtx_equal_p (operands[4], operands[0]))
14765 {
14766 operands[1] = force_reg (SImode, operands[1]);
14767 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14768 }
14769 else if (rtx_equal_p (operands[1], operands[0]))
14770 {
14771 operands[4] = force_reg (SImode, operands[4]);
14772 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14773 }
14774 else
14775 {
14776 operands[1] = force_reg (SImode, operands[1]);
14777 rtx tmp = gen_reg_rtx (SImode);
14778 emit_move_insn (tmp, operands[4]);
14779 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14780 emit_move_insn (operands[0], tmp);
14781 }
14782 DONE;
14783 })
14784
14785 (define_insn_and_split "*x86_shrd_2"
14786 [(set (match_operand:SI 0 "nonimmediate_operand")
14787 (ior:SI (lshiftrt:SI (match_dup 0)
14788 (match_operand:QI 2 "nonmemory_operand"))
14789 (ashift:SI (match_operand:SI 1 "register_operand")
14790 (minus:QI (const_int 32) (match_dup 2)))))
14791 (clobber (reg:CC FLAGS_REG))]
14792 "TARGET_64BIT && ix86_pre_reload_split ()"
14793 "#"
14794 "&& 1"
14795 [(parallel [(set (match_dup 0)
14796 (ior:SI (lshiftrt:SI (match_dup 0)
14797 (and:QI (match_dup 2) (const_int 31)))
14798 (subreg:SI
14799 (ashift:DI
14800 (zero_extend:DI (match_dup 1))
14801 (minus:QI (const_int 32)
14802 (and:QI (match_dup 2)
14803 (const_int 31)))) 0)))
14804 (clobber (reg:CC FLAGS_REG))])])
14805
14806 ;; Base name for insn mnemonic.
14807 (define_mode_attr cvt_mnemonic
14808 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
14809
14810 (define_insn "ashr<mode>3_cvt"
14811 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
14812 (ashiftrt:SWI48
14813 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
14814 (match_operand:QI 2 "const_int_operand")))
14815 (clobber (reg:CC FLAGS_REG))]
14816 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
14817 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14818 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14819 "@
14820 <cvt_mnemonic>
14821 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
14822 [(set_attr "type" "imovx,ishift")
14823 (set_attr "prefix_0f" "0,*")
14824 (set_attr "length_immediate" "0,*")
14825 (set_attr "modrm" "0,1")
14826 (set_attr "mode" "<MODE>")])
14827
14828 (define_insn "*ashrsi3_cvt_zext"
14829 [(set (match_operand:DI 0 "register_operand" "=*d,r")
14830 (zero_extend:DI
14831 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
14832 (match_operand:QI 2 "const_int_operand"))))
14833 (clobber (reg:CC FLAGS_REG))]
14834 "TARGET_64BIT && INTVAL (operands[2]) == 31
14835 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14836 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
14837 "@
14838 {cltd|cdq}
14839 sar{l}\t{%2, %k0|%k0, %2}"
14840 [(set_attr "type" "imovx,ishift")
14841 (set_attr "prefix_0f" "0,*")
14842 (set_attr "length_immediate" "0,*")
14843 (set_attr "modrm" "0,1")
14844 (set_attr "mode" "SI")])
14845
14846 (define_expand "@x86_shift<mode>_adj_3"
14847 [(use (match_operand:SWI48 0 "register_operand"))
14848 (use (match_operand:SWI48 1 "register_operand"))
14849 (use (match_operand:QI 2 "register_operand"))]
14850 ""
14851 {
14852 rtx_code_label *label = gen_label_rtx ();
14853 rtx tmp;
14854
14855 emit_insn (gen_testqi_ccz_1 (operands[2],
14856 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14857
14858 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14859 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14860 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14861 gen_rtx_LABEL_REF (VOIDmode, label),
14862 pc_rtx);
14863 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14864 JUMP_LABEL (tmp) = label;
14865
14866 emit_move_insn (operands[0], operands[1]);
14867 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
14868 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
14869 emit_label (label);
14870 LABEL_NUSES (label) = 1;
14871
14872 DONE;
14873 })
14874
14875 (define_insn "*bmi2_<insn><mode>3_1"
14876 [(set (match_operand:SWI48 0 "register_operand" "=r")
14877 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14878 (match_operand:SWI48 2 "register_operand" "r")))]
14879 "TARGET_BMI2"
14880 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
14881 [(set_attr "type" "ishiftx")
14882 (set_attr "mode" "<MODE>")])
14883
14884 (define_insn "*ashr<mode>3_1"
14885 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
14886 (ashiftrt:SWI48
14887 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
14888 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
14889 (clobber (reg:CC FLAGS_REG))]
14890 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14891 {
14892 switch (get_attr_type (insn))
14893 {
14894 case TYPE_ISHIFTX:
14895 return "#";
14896
14897 default:
14898 if (operands[2] == const1_rtx
14899 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14900 return "sar{<imodesuffix>}\t%0";
14901 else
14902 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
14903 }
14904 }
14905 [(set_attr "isa" "*,bmi2")
14906 (set_attr "type" "ishift,ishiftx")
14907 (set (attr "length_immediate")
14908 (if_then_else
14909 (and (match_operand 2 "const1_operand")
14910 (ior (match_test "TARGET_SHIFT1")
14911 (match_test "optimize_function_for_size_p (cfun)")))
14912 (const_string "0")
14913 (const_string "*")))
14914 (set_attr "mode" "<MODE>")])
14915
14916 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
14917 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
14918 (define_insn_and_split "*highpartdisi2"
14919 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
14920 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
14921 (const_int 32)))
14922 (clobber (reg:CC FLAGS_REG))]
14923 "TARGET_64BIT"
14924 "#"
14925 "&& reload_completed"
14926 [(parallel
14927 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
14928 (clobber (reg:CC FLAGS_REG))])]
14929 {
14930 if (SSE_REG_P (operands[0]))
14931 {
14932 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
14933 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
14934 const1_rtx, const1_rtx,
14935 GEN_INT (5), GEN_INT (5)));
14936 DONE;
14937 }
14938 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
14939 })
14940
14941 (define_insn "*lshr<mode>3_1"
14942 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
14943 (lshiftrt:SWI48
14944 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
14945 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
14946 (clobber (reg:CC FLAGS_REG))]
14947 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
14948 {
14949 switch (get_attr_type (insn))
14950 {
14951 case TYPE_ISHIFTX:
14952 case TYPE_MSKLOG:
14953 return "#";
14954
14955 default:
14956 if (operands[2] == const1_rtx
14957 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14958 return "shr{<imodesuffix>}\t%0";
14959 else
14960 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
14961 }
14962 }
14963 [(set_attr "isa" "*,bmi2,avx512bw")
14964 (set_attr "type" "ishift,ishiftx,msklog")
14965 (set (attr "length_immediate")
14966 (if_then_else
14967 (and (and (match_operand 2 "const1_operand")
14968 (eq_attr "alternative" "0"))
14969 (ior (match_test "TARGET_SHIFT1")
14970 (match_test "optimize_function_for_size_p (cfun)")))
14971 (const_string "0")
14972 (const_string "*")))
14973 (set_attr "mode" "<MODE>")])
14974
14975 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14976 (define_split
14977 [(set (match_operand:SWI48 0 "register_operand")
14978 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14979 (match_operand:QI 2 "register_operand")))
14980 (clobber (reg:CC FLAGS_REG))]
14981 "TARGET_BMI2 && reload_completed"
14982 [(set (match_dup 0)
14983 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
14984 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14985
14986 (define_insn "*bmi2_<insn>si3_1_zext"
14987 [(set (match_operand:DI 0 "register_operand" "=r")
14988 (zero_extend:DI
14989 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14990 (match_operand:SI 2 "register_operand" "r"))))]
14991 "TARGET_64BIT && TARGET_BMI2"
14992 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
14993 [(set_attr "type" "ishiftx")
14994 (set_attr "mode" "SI")])
14995
14996 (define_insn "*<insn>si3_1_zext"
14997 [(set (match_operand:DI 0 "register_operand" "=r,r")
14998 (zero_extend:DI
14999 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15000 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
15001 (clobber (reg:CC FLAGS_REG))]
15002 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15003 {
15004 switch (get_attr_type (insn))
15005 {
15006 case TYPE_ISHIFTX:
15007 return "#";
15008
15009 default:
15010 if (operands[2] == const1_rtx
15011 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15012 return "<shift>{l}\t%k0";
15013 else
15014 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15015 }
15016 }
15017 [(set_attr "isa" "*,bmi2")
15018 (set_attr "type" "ishift,ishiftx")
15019 (set (attr "length_immediate")
15020 (if_then_else
15021 (and (match_operand 2 "const1_operand")
15022 (ior (match_test "TARGET_SHIFT1")
15023 (match_test "optimize_function_for_size_p (cfun)")))
15024 (const_string "0")
15025 (const_string "*")))
15026 (set_attr "mode" "SI")])
15027
15028 ;; Convert shift to the shiftx pattern to avoid flags dependency.
15029 (define_split
15030 [(set (match_operand:DI 0 "register_operand")
15031 (zero_extend:DI
15032 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
15033 (match_operand:QI 2 "register_operand"))))
15034 (clobber (reg:CC FLAGS_REG))]
15035 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
15036 [(set (match_dup 0)
15037 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15038 "operands[2] = gen_lowpart (SImode, operands[2]);")
15039
15040 (define_insn "*ashr<mode>3_1"
15041 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15042 (ashiftrt:SWI12
15043 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15044 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15045 (clobber (reg:CC FLAGS_REG))]
15046 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
15047 {
15048 if (operands[2] == const1_rtx
15049 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15050 return "sar{<imodesuffix>}\t%0";
15051 else
15052 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
15053 }
15054 [(set_attr "type" "ishift")
15055 (set (attr "length_immediate")
15056 (if_then_else
15057 (and (match_operand 2 "const1_operand")
15058 (ior (match_test "TARGET_SHIFT1")
15059 (match_test "optimize_function_for_size_p (cfun)")))
15060 (const_string "0")
15061 (const_string "*")))
15062 (set_attr "mode" "<MODE>")])
15063
15064 (define_insn "*lshrqi3_1"
15065 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
15066 (lshiftrt:QI
15067 (match_operand:QI 1 "nonimmediate_operand" "0, k")
15068 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
15069 (clobber (reg:CC FLAGS_REG))]
15070 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15071 {
15072 switch (get_attr_type (insn))
15073 {
15074 case TYPE_ISHIFT:
15075 if (operands[2] == const1_rtx
15076 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15077 return "shr{b}\t%0";
15078 else
15079 return "shr{b}\t{%2, %0|%0, %2}";
15080 case TYPE_MSKLOG:
15081 return "#";
15082 default:
15083 gcc_unreachable ();
15084 }
15085 }
15086 [(set_attr "isa" "*,avx512dq")
15087 (set_attr "type" "ishift,msklog")
15088 (set (attr "length_immediate")
15089 (if_then_else
15090 (and (and (match_operand 2 "const1_operand")
15091 (eq_attr "alternative" "0"))
15092 (ior (match_test "TARGET_SHIFT1")
15093 (match_test "optimize_function_for_size_p (cfun)")))
15094 (const_string "0")
15095 (const_string "*")))
15096 (set_attr "mode" "QI")])
15097
15098 (define_insn "*lshrhi3_1"
15099 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15100 (lshiftrt:HI
15101 (match_operand:HI 1 "nonimmediate_operand" "0, k")
15102 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15103 (clobber (reg:CC FLAGS_REG))]
15104 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15105 {
15106 switch (get_attr_type (insn))
15107 {
15108 case TYPE_ISHIFT:
15109 if (operands[2] == const1_rtx
15110 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15111 return "shr{w}\t%0";
15112 else
15113 return "shr{w}\t{%2, %0|%0, %2}";
15114 case TYPE_MSKLOG:
15115 return "#";
15116 default:
15117 gcc_unreachable ();
15118 }
15119 }
15120 [(set_attr "isa" "*, avx512f")
15121 (set_attr "type" "ishift,msklog")
15122 (set (attr "length_immediate")
15123 (if_then_else
15124 (and (and (match_operand 2 "const1_operand")
15125 (eq_attr "alternative" "0"))
15126 (ior (match_test "TARGET_SHIFT1")
15127 (match_test "optimize_function_for_size_p (cfun)")))
15128 (const_string "0")
15129 (const_string "*")))
15130 (set_attr "mode" "HI")])
15131
15132 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15133 (define_insn_and_split "*<insn><mode>3_1_slp"
15134 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15135 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15136 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15137 (clobber (reg:CC FLAGS_REG))]
15138 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15139 {
15140 if (which_alternative)
15141 return "#";
15142
15143 if (operands[2] == const1_rtx
15144 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15145 return "<shift>{<imodesuffix>}\t%0";
15146 else
15147 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15148 }
15149 "&& reload_completed"
15150 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15151 (parallel
15152 [(set (strict_low_part (match_dup 0))
15153 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15154 (clobber (reg:CC FLAGS_REG))])]
15155 ""
15156 [(set_attr "type" "ishift")
15157 (set (attr "length_immediate")
15158 (if_then_else
15159 (and (match_operand 2 "const1_operand")
15160 (ior (match_test "TARGET_SHIFT1")
15161 (match_test "optimize_function_for_size_p (cfun)")))
15162 (const_string "0")
15163 (const_string "*")))
15164 (set_attr "mode" "<MODE>")])
15165
15166 ;; This pattern can't accept a variable shift count, since shifts by
15167 ;; zero don't affect the flags. We assume that shifts by constant
15168 ;; zero are optimized away.
15169 (define_insn "*<insn><mode>3_cmp"
15170 [(set (reg FLAGS_REG)
15171 (compare
15172 (any_shiftrt:SWI
15173 (match_operand:SWI 1 "nonimmediate_operand" "0")
15174 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15175 (const_int 0)))
15176 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15177 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15178 "(optimize_function_for_size_p (cfun)
15179 || !TARGET_PARTIAL_FLAG_REG_STALL
15180 || (operands[2] == const1_rtx
15181 && TARGET_SHIFT1))
15182 && ix86_match_ccmode (insn, CCGOCmode)
15183 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15184 {
15185 if (operands[2] == const1_rtx
15186 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15187 return "<shift>{<imodesuffix>}\t%0";
15188 else
15189 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15190 }
15191 [(set_attr "type" "ishift")
15192 (set (attr "length_immediate")
15193 (if_then_else
15194 (and (match_operand 2 "const1_operand")
15195 (ior (match_test "TARGET_SHIFT1")
15196 (match_test "optimize_function_for_size_p (cfun)")))
15197 (const_string "0")
15198 (const_string "*")))
15199 (set_attr "mode" "<MODE>")])
15200
15201 (define_insn "*<insn>si3_cmp_zext"
15202 [(set (reg FLAGS_REG)
15203 (compare
15204 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15205 (match_operand:QI 2 "const_1_to_31_operand"))
15206 (const_int 0)))
15207 (set (match_operand:DI 0 "register_operand" "=r")
15208 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15209 "TARGET_64BIT
15210 && (optimize_function_for_size_p (cfun)
15211 || !TARGET_PARTIAL_FLAG_REG_STALL
15212 || (operands[2] == const1_rtx
15213 && TARGET_SHIFT1))
15214 && ix86_match_ccmode (insn, CCGOCmode)
15215 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15216 {
15217 if (operands[2] == const1_rtx
15218 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15219 return "<shift>{l}\t%k0";
15220 else
15221 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15222 }
15223 [(set_attr "type" "ishift")
15224 (set (attr "length_immediate")
15225 (if_then_else
15226 (and (match_operand 2 "const1_operand")
15227 (ior (match_test "TARGET_SHIFT1")
15228 (match_test "optimize_function_for_size_p (cfun)")))
15229 (const_string "0")
15230 (const_string "*")))
15231 (set_attr "mode" "SI")])
15232
15233 (define_insn "*<insn><mode>3_cconly"
15234 [(set (reg FLAGS_REG)
15235 (compare
15236 (any_shiftrt:SWI
15237 (match_operand:SWI 1 "register_operand" "0")
15238 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15239 (const_int 0)))
15240 (clobber (match_scratch:SWI 0 "=<r>"))]
15241 "(optimize_function_for_size_p (cfun)
15242 || !TARGET_PARTIAL_FLAG_REG_STALL
15243 || (operands[2] == const1_rtx
15244 && TARGET_SHIFT1))
15245 && ix86_match_ccmode (insn, CCGOCmode)"
15246 {
15247 if (operands[2] == const1_rtx
15248 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15249 return "<shift>{<imodesuffix>}\t%0";
15250 else
15251 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15252 }
15253 [(set_attr "type" "ishift")
15254 (set (attr "length_immediate")
15255 (if_then_else
15256 (and (match_operand 2 "const1_operand")
15257 (ior (match_test "TARGET_SHIFT1")
15258 (match_test "optimize_function_for_size_p (cfun)")))
15259 (const_string "0")
15260 (const_string "*")))
15261 (set_attr "mode" "<MODE>")])
15262
15263 (define_insn "*<insn>qi_ext<mode>_2"
15264 [(set (zero_extract:SWI248
15265 (match_operand 0 "int248_register_operand" "+Q")
15266 (const_int 8)
15267 (const_int 8))
15268 (subreg:SWI248
15269 (any_shiftrt:QI
15270 (subreg:QI
15271 (match_operator:SWI248 3 "extract_operator"
15272 [(match_operand 1 "int248_register_operand" "0")
15273 (const_int 8)
15274 (const_int 8)]) 0)
15275 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
15276 (clobber (reg:CC FLAGS_REG))]
15277 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
15278 rtx_equal_p (operands[0], operands[1])"
15279 {
15280 if (operands[2] == const1_rtx
15281 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15282 return "<shift>{b}\t%h0";
15283 else
15284 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15285 }
15286 [(set_attr "type" "ishift")
15287 (set (attr "length_immediate")
15288 (if_then_else
15289 (and (match_operand 2 "const1_operand")
15290 (ior (match_test "TARGET_SHIFT1")
15291 (match_test "optimize_function_for_size_p (cfun)")))
15292 (const_string "0")
15293 (const_string "*")))
15294 (set_attr "mode" "QI")])
15295
15296 (define_insn_and_split "*extend<dwi>2_doubleword_highpart"
15297 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15298 (ashiftrt:<DWI>
15299 (ashift:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")
15300 (match_operand:QI 2 "const_int_operand"))
15301 (match_operand:QI 3 "const_int_operand")))
15302 (clobber (reg:CC FLAGS_REG))]
15303 "INTVAL (operands[2]) == INTVAL (operands[3])
15304 && UINTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT"
15305 "#"
15306 "&& reload_completed"
15307 [(parallel [(set (match_dup 4)
15308 (ashift:DWIH (match_dup 4) (match_dup 2)))
15309 (clobber (reg:CC FLAGS_REG))])
15310 (parallel [(set (match_dup 4)
15311 (ashiftrt:DWIH (match_dup 4) (match_dup 2)))
15312 (clobber (reg:CC FLAGS_REG))])]
15313 "split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[4]);")
15314
15315 (define_insn_and_split "*extendv2di2_highpart_stv"
15316 [(set (match_operand:V2DI 0 "register_operand" "=v")
15317 (ashiftrt:V2DI
15318 (ashift:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "vm")
15319 (match_operand:QI 2 "const_int_operand"))
15320 (match_operand:QI 3 "const_int_operand")))]
15321 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
15322 && INTVAL (operands[2]) == INTVAL (operands[3])
15323 && UINTVAL (operands[2]) < 32"
15324 "#"
15325 "&& reload_completed"
15326 [(set (match_dup 0)
15327 (ashift:V2DI (match_dup 1) (match_dup 2)))
15328 (set (match_dup 0)
15329 (ashiftrt:V2DI (match_dup 0) (match_dup 2)))])
15330 \f
15331 ;; Rotate instructions
15332
15333 (define_expand "<insn>ti3"
15334 [(set (match_operand:TI 0 "register_operand")
15335 (any_rotate:TI (match_operand:TI 1 "register_operand")
15336 (match_operand:QI 2 "nonmemory_operand")))]
15337 "TARGET_64BIT"
15338 {
15339 if (const_1_to_63_operand (operands[2], VOIDmode))
15340 emit_insn (gen_ix86_<insn>ti3_doubleword
15341 (operands[0], operands[1], operands[2]));
15342 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15343 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15344 else
15345 {
15346 rtx amount = force_reg (QImode, operands[2]);
15347 rtx src_lo = gen_lowpart (DImode, operands[1]);
15348 rtx src_hi = gen_highpart (DImode, operands[1]);
15349 rtx tmp_lo = gen_reg_rtx (DImode);
15350 rtx tmp_hi = gen_reg_rtx (DImode);
15351 emit_move_insn (tmp_lo, src_lo);
15352 emit_move_insn (tmp_hi, src_hi);
15353 rtx (*shiftd) (rtx, rtx, rtx)
15354 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15355 emit_insn (shiftd (tmp_lo, src_hi, amount));
15356 emit_insn (shiftd (tmp_hi, src_lo, amount));
15357 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15358 rtx dst_hi = gen_highpart (DImode, operands[0]);
15359 emit_move_insn (dst_lo, tmp_lo);
15360 emit_move_insn (dst_hi, tmp_hi);
15361 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15362 }
15363 DONE;
15364 })
15365
15366 (define_expand "<insn>di3"
15367 [(set (match_operand:DI 0 "shiftdi_operand")
15368 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15369 (match_operand:QI 2 "nonmemory_operand")))]
15370 ""
15371 {
15372 if (TARGET_64BIT)
15373 ix86_expand_binary_operator (<CODE>, DImode, operands);
15374 else if (const_1_to_31_operand (operands[2], VOIDmode))
15375 emit_insn (gen_ix86_<insn>di3_doubleword
15376 (operands[0], operands[1], operands[2]));
15377 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15378 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15379 else
15380 FAIL;
15381
15382 DONE;
15383 })
15384
15385 (define_expand "<insn><mode>3"
15386 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15387 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15388 (match_operand:QI 2 "nonmemory_operand")))]
15389 ""
15390 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15391
15392 ;; Avoid useless masking of count operand.
15393 (define_insn_and_split "*<insn><mode>3_mask"
15394 [(set (match_operand:SWI 0 "nonimmediate_operand")
15395 (any_rotate:SWI
15396 (match_operand:SWI 1 "nonimmediate_operand")
15397 (subreg:QI
15398 (and
15399 (match_operand 2 "int248_register_operand" "c")
15400 (match_operand 3 "const_int_operand")) 0)))
15401 (clobber (reg:CC FLAGS_REG))]
15402 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15403 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15404 == GET_MODE_BITSIZE (<MODE>mode)-1
15405 && ix86_pre_reload_split ()"
15406 "#"
15407 "&& 1"
15408 [(parallel
15409 [(set (match_dup 0)
15410 (any_rotate:SWI (match_dup 1)
15411 (match_dup 2)))
15412 (clobber (reg:CC FLAGS_REG))])]
15413 {
15414 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15415 operands[2] = gen_lowpart (QImode, operands[2]);
15416 })
15417
15418 (define_split
15419 [(set (match_operand:SWI 0 "register_operand")
15420 (any_rotate:SWI
15421 (match_operand:SWI 1 "const_int_operand")
15422 (subreg:QI
15423 (and
15424 (match_operand 2 "int248_register_operand")
15425 (match_operand 3 "const_int_operand")) 0)))]
15426 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15427 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15428 [(set (match_dup 4) (match_dup 1))
15429 (set (match_dup 0)
15430 (any_rotate:SWI (match_dup 4)
15431 (subreg:QI (match_dup 2) 0)))]
15432 "operands[4] = gen_reg_rtx (<MODE>mode);")
15433
15434 (define_insn_and_split "*<insn><mode>3_mask_1"
15435 [(set (match_operand:SWI 0 "nonimmediate_operand")
15436 (any_rotate:SWI
15437 (match_operand:SWI 1 "nonimmediate_operand")
15438 (and:QI
15439 (match_operand:QI 2 "register_operand" "c")
15440 (match_operand:QI 3 "const_int_operand"))))
15441 (clobber (reg:CC FLAGS_REG))]
15442 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15443 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15444 == GET_MODE_BITSIZE (<MODE>mode)-1
15445 && ix86_pre_reload_split ()"
15446 "#"
15447 "&& 1"
15448 [(parallel
15449 [(set (match_dup 0)
15450 (any_rotate:SWI (match_dup 1)
15451 (match_dup 2)))
15452 (clobber (reg:CC FLAGS_REG))])])
15453
15454 (define_split
15455 [(set (match_operand:SWI 0 "register_operand")
15456 (any_rotate:SWI
15457 (match_operand:SWI 1 "const_int_operand")
15458 (and:QI
15459 (match_operand:QI 2 "register_operand")
15460 (match_operand:QI 3 "const_int_operand"))))]
15461 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15462 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15463 [(set (match_dup 4) (match_dup 1))
15464 (set (match_dup 0)
15465 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15466 "operands[4] = gen_reg_rtx (<MODE>mode);")
15467
15468 ;; Implement rotation using two double-precision
15469 ;; shift instructions and a scratch register.
15470
15471 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15472 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15473 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15474 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15475 (clobber (reg:CC FLAGS_REG))
15476 (clobber (match_scratch:DWIH 3 "=&r"))]
15477 ""
15478 "#"
15479 "reload_completed"
15480 [(set (match_dup 3) (match_dup 4))
15481 (parallel
15482 [(set (match_dup 4)
15483 (ior:DWIH (ashift:DWIH (match_dup 4)
15484 (and:QI (match_dup 2) (match_dup 6)))
15485 (subreg:DWIH
15486 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15487 (minus:QI (match_dup 7)
15488 (and:QI (match_dup 2)
15489 (match_dup 6)))) 0)))
15490 (clobber (reg:CC FLAGS_REG))])
15491 (parallel
15492 [(set (match_dup 5)
15493 (ior:DWIH (ashift:DWIH (match_dup 5)
15494 (and:QI (match_dup 2) (match_dup 6)))
15495 (subreg:DWIH
15496 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15497 (minus:QI (match_dup 7)
15498 (and:QI (match_dup 2)
15499 (match_dup 6)))) 0)))
15500 (clobber (reg:CC FLAGS_REG))])]
15501 {
15502 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15503 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15504
15505 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15506 })
15507
15508 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15509 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15510 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15511 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15512 (clobber (reg:CC FLAGS_REG))
15513 (clobber (match_scratch:DWIH 3 "=&r"))]
15514 ""
15515 "#"
15516 "reload_completed"
15517 [(set (match_dup 3) (match_dup 4))
15518 (parallel
15519 [(set (match_dup 4)
15520 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15521 (and:QI (match_dup 2) (match_dup 6)))
15522 (subreg:DWIH
15523 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15524 (minus:QI (match_dup 7)
15525 (and:QI (match_dup 2)
15526 (match_dup 6)))) 0)))
15527 (clobber (reg:CC FLAGS_REG))])
15528 (parallel
15529 [(set (match_dup 5)
15530 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15531 (and:QI (match_dup 2) (match_dup 6)))
15532 (subreg:DWIH
15533 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15534 (minus:QI (match_dup 7)
15535 (and:QI (match_dup 2)
15536 (match_dup 6)))) 0)))
15537 (clobber (reg:CC FLAGS_REG))])]
15538 {
15539 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15540 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15541
15542 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15543 })
15544
15545 (define_insn_and_split "<insn>32di2_doubleword"
15546 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
15547 (any_rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,r,o")
15548 (const_int 32)))]
15549 "!TARGET_64BIT"
15550 "#"
15551 "&& reload_completed"
15552 [(set (match_dup 0) (match_dup 3))
15553 (set (match_dup 2) (match_dup 1))]
15554 {
15555 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15556 if (rtx_equal_p (operands[0], operands[1]))
15557 {
15558 emit_insn (gen_swapsi (operands[0], operands[2]));
15559 DONE;
15560 }
15561 })
15562
15563 (define_insn_and_split "<insn>64ti2_doubleword"
15564 [(set (match_operand:TI 0 "register_operand" "=r,r,r")
15565 (any_rotate:TI (match_operand:TI 1 "nonimmediate_operand" "0,r,o")
15566 (const_int 64)))]
15567 "TARGET_64BIT"
15568 "#"
15569 "&& reload_completed"
15570 [(set (match_dup 0) (match_dup 3))
15571 (set (match_dup 2) (match_dup 1))]
15572 {
15573 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15574 if (rtx_equal_p (operands[0], operands[1]))
15575 {
15576 emit_insn (gen_swapdi (operands[0], operands[2]));
15577 DONE;
15578 }
15579 })
15580
15581 (define_mode_attr rorx_immediate_operand
15582 [(SI "const_0_to_31_operand")
15583 (DI "const_0_to_63_operand")])
15584
15585 (define_insn "*bmi2_rorx<mode>3_1"
15586 [(set (match_operand:SWI48 0 "register_operand" "=r")
15587 (rotatert:SWI48
15588 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15589 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15590 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15591 "rorx\t{%2, %1, %0|%0, %1, %2}"
15592 [(set_attr "type" "rotatex")
15593 (set_attr "mode" "<MODE>")])
15594
15595 (define_insn "*<insn><mode>3_1"
15596 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15597 (any_rotate:SWI48
15598 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15599 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15600 (clobber (reg:CC FLAGS_REG))]
15601 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15602 {
15603 switch (get_attr_type (insn))
15604 {
15605 case TYPE_ROTATEX:
15606 return "#";
15607
15608 default:
15609 if (operands[2] == const1_rtx
15610 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15611 return "<rotate>{<imodesuffix>}\t%0";
15612 else
15613 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15614 }
15615 }
15616 [(set_attr "isa" "*,bmi2")
15617 (set_attr "type" "rotate,rotatex")
15618 (set (attr "preferred_for_size")
15619 (cond [(eq_attr "alternative" "0")
15620 (symbol_ref "true")]
15621 (symbol_ref "false")))
15622 (set (attr "length_immediate")
15623 (if_then_else
15624 (and (eq_attr "type" "rotate")
15625 (and (match_operand 2 "const1_operand")
15626 (ior (match_test "TARGET_SHIFT1")
15627 (match_test "optimize_function_for_size_p (cfun)"))))
15628 (const_string "0")
15629 (const_string "*")))
15630 (set_attr "mode" "<MODE>")])
15631
15632 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15633 (define_split
15634 [(set (match_operand:SWI48 0 "register_operand")
15635 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15636 (match_operand:QI 2 "const_int_operand")))
15637 (clobber (reg:CC FLAGS_REG))]
15638 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15639 [(set (match_dup 0)
15640 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15641 {
15642 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15643
15644 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15645 })
15646
15647 (define_split
15648 [(set (match_operand:SWI48 0 "register_operand")
15649 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15650 (match_operand:QI 2 "const_int_operand")))
15651 (clobber (reg:CC FLAGS_REG))]
15652 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15653 [(set (match_dup 0)
15654 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15655
15656 (define_insn "*bmi2_rorxsi3_1_zext"
15657 [(set (match_operand:DI 0 "register_operand" "=r")
15658 (zero_extend:DI
15659 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15660 (match_operand:QI 2 "const_0_to_31_operand"))))]
15661 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15662 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
15663 [(set_attr "type" "rotatex")
15664 (set_attr "mode" "SI")])
15665
15666 (define_insn "*<insn>si3_1_zext"
15667 [(set (match_operand:DI 0 "register_operand" "=r,r")
15668 (zero_extend:DI
15669 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15670 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
15671 (clobber (reg:CC FLAGS_REG))]
15672 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15673 {
15674 switch (get_attr_type (insn))
15675 {
15676 case TYPE_ROTATEX:
15677 return "#";
15678
15679 default:
15680 if (operands[2] == const1_rtx
15681 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15682 return "<rotate>{l}\t%k0";
15683 else
15684 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
15685 }
15686 }
15687 [(set_attr "isa" "*,bmi2")
15688 (set_attr "type" "rotate,rotatex")
15689 (set (attr "preferred_for_size")
15690 (cond [(eq_attr "alternative" "0")
15691 (symbol_ref "true")]
15692 (symbol_ref "false")))
15693 (set (attr "length_immediate")
15694 (if_then_else
15695 (and (eq_attr "type" "rotate")
15696 (and (match_operand 2 "const1_operand")
15697 (ior (match_test "TARGET_SHIFT1")
15698 (match_test "optimize_function_for_size_p (cfun)"))))
15699 (const_string "0")
15700 (const_string "*")))
15701 (set_attr "mode" "SI")])
15702
15703 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15704 (define_split
15705 [(set (match_operand:DI 0 "register_operand")
15706 (zero_extend:DI
15707 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
15708 (match_operand:QI 2 "const_int_operand"))))
15709 (clobber (reg:CC FLAGS_REG))]
15710 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15711 && !optimize_function_for_size_p (cfun)"
15712 [(set (match_dup 0)
15713 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
15714 {
15715 int bitsize = GET_MODE_BITSIZE (SImode);
15716
15717 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15718 })
15719
15720 (define_split
15721 [(set (match_operand:DI 0 "register_operand")
15722 (zero_extend:DI
15723 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
15724 (match_operand:QI 2 "const_int_operand"))))
15725 (clobber (reg:CC FLAGS_REG))]
15726 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15727 && !optimize_function_for_size_p (cfun)"
15728 [(set (match_dup 0)
15729 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
15730
15731 (define_insn "*<insn><mode>3_1"
15732 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15733 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15734 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15735 (clobber (reg:CC FLAGS_REG))]
15736 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15737 {
15738 if (operands[2] == const1_rtx
15739 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15740 return "<rotate>{<imodesuffix>}\t%0";
15741 else
15742 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15743 }
15744 [(set_attr "type" "rotate")
15745 (set (attr "length_immediate")
15746 (if_then_else
15747 (and (match_operand 2 "const1_operand")
15748 (ior (match_test "TARGET_SHIFT1")
15749 (match_test "optimize_function_for_size_p (cfun)")))
15750 (const_string "0")
15751 (const_string "*")))
15752 (set_attr "mode" "<MODE>")])
15753
15754 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15755 (define_insn_and_split "*<insn><mode>3_1_slp"
15756 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15757 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15758 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15759 (clobber (reg:CC FLAGS_REG))]
15760 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15761 {
15762 if (which_alternative)
15763 return "#";
15764
15765 if (operands[2] == const1_rtx
15766 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15767 return "<rotate>{<imodesuffix>}\t%0";
15768 else
15769 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15770 }
15771 "&& reload_completed"
15772 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15773 (parallel
15774 [(set (strict_low_part (match_dup 0))
15775 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
15776 (clobber (reg:CC FLAGS_REG))])]
15777 ""
15778 [(set_attr "type" "rotate")
15779 (set (attr "length_immediate")
15780 (if_then_else
15781 (and (match_operand 2 "const1_operand")
15782 (ior (match_test "TARGET_SHIFT1")
15783 (match_test "optimize_function_for_size_p (cfun)")))
15784 (const_string "0")
15785 (const_string "*")))
15786 (set_attr "mode" "<MODE>")])
15787
15788 (define_split
15789 [(set (match_operand:HI 0 "QIreg_operand")
15790 (any_rotate:HI (match_dup 0) (const_int 8)))
15791 (clobber (reg:CC FLAGS_REG))]
15792 "reload_completed
15793 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
15794 [(parallel [(set (strict_low_part (match_dup 0))
15795 (bswap:HI (match_dup 0)))
15796 (clobber (reg:CC FLAGS_REG))])])
15797 \f
15798 ;; Bit set / bit test instructions
15799
15800 ;; %%% bts, btr, btc
15801
15802 ;; These instructions are *slow* when applied to memory.
15803
15804 (define_code_attr btsc [(ior "bts") (xor "btc")])
15805
15806 (define_insn "*<btsc><mode>"
15807 [(set (match_operand:SWI48 0 "register_operand" "=r")
15808 (any_or:SWI48
15809 (ashift:SWI48 (const_int 1)
15810 (match_operand:QI 2 "register_operand" "r"))
15811 (match_operand:SWI48 1 "register_operand" "0")))
15812 (clobber (reg:CC FLAGS_REG))]
15813 "TARGET_USE_BT"
15814 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15815 [(set_attr "type" "alu1")
15816 (set_attr "prefix_0f" "1")
15817 (set_attr "znver1_decode" "double")
15818 (set_attr "mode" "<MODE>")])
15819
15820 ;; Avoid useless masking of count operand.
15821 (define_insn_and_split "*<btsc><mode>_mask"
15822 [(set (match_operand:SWI48 0 "register_operand")
15823 (any_or:SWI48
15824 (ashift:SWI48
15825 (const_int 1)
15826 (subreg:QI
15827 (and
15828 (match_operand 1 "int248_register_operand")
15829 (match_operand 2 "const_int_operand")) 0))
15830 (match_operand:SWI48 3 "register_operand")))
15831 (clobber (reg:CC FLAGS_REG))]
15832 "TARGET_USE_BT
15833 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15834 == GET_MODE_BITSIZE (<MODE>mode)-1
15835 && ix86_pre_reload_split ()"
15836 "#"
15837 "&& 1"
15838 [(parallel
15839 [(set (match_dup 0)
15840 (any_or:SWI48
15841 (ashift:SWI48 (const_int 1)
15842 (match_dup 1))
15843 (match_dup 3)))
15844 (clobber (reg:CC FLAGS_REG))])]
15845 {
15846 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
15847 operands[1] = gen_lowpart (QImode, operands[1]);
15848 })
15849
15850 (define_insn_and_split "*<btsc><mode>_mask_1"
15851 [(set (match_operand:SWI48 0 "register_operand")
15852 (any_or:SWI48
15853 (ashift:SWI48
15854 (const_int 1)
15855 (and:QI
15856 (match_operand:QI 1 "register_operand")
15857 (match_operand:QI 2 "const_int_operand")))
15858 (match_operand:SWI48 3 "register_operand")))
15859 (clobber (reg:CC FLAGS_REG))]
15860 "TARGET_USE_BT
15861 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15862 == GET_MODE_BITSIZE (<MODE>mode)-1
15863 && ix86_pre_reload_split ()"
15864 "#"
15865 "&& 1"
15866 [(parallel
15867 [(set (match_dup 0)
15868 (any_or:SWI48
15869 (ashift:SWI48 (const_int 1)
15870 (match_dup 1))
15871 (match_dup 3)))
15872 (clobber (reg:CC FLAGS_REG))])])
15873
15874 (define_insn "*btr<mode>"
15875 [(set (match_operand:SWI48 0 "register_operand" "=r")
15876 (and:SWI48
15877 (rotate:SWI48 (const_int -2)
15878 (match_operand:QI 2 "register_operand" "r"))
15879 (match_operand:SWI48 1 "register_operand" "0")))
15880 (clobber (reg:CC FLAGS_REG))]
15881 "TARGET_USE_BT"
15882 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15883 [(set_attr "type" "alu1")
15884 (set_attr "prefix_0f" "1")
15885 (set_attr "znver1_decode" "double")
15886 (set_attr "mode" "<MODE>")])
15887
15888 ;; Avoid useless masking of count operand.
15889 (define_insn_and_split "*btr<mode>_mask"
15890 [(set (match_operand:SWI48 0 "register_operand")
15891 (and:SWI48
15892 (rotate:SWI48
15893 (const_int -2)
15894 (subreg:QI
15895 (and
15896 (match_operand 1 "int248_register_operand")
15897 (match_operand 2 "const_int_operand")) 0))
15898 (match_operand:SWI48 3 "register_operand")))
15899 (clobber (reg:CC FLAGS_REG))]
15900 "TARGET_USE_BT
15901 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15902 == GET_MODE_BITSIZE (<MODE>mode)-1
15903 && ix86_pre_reload_split ()"
15904 "#"
15905 "&& 1"
15906 [(parallel
15907 [(set (match_dup 0)
15908 (and:SWI48
15909 (rotate:SWI48 (const_int -2)
15910 (match_dup 1))
15911 (match_dup 3)))
15912 (clobber (reg:CC FLAGS_REG))])]
15913 {
15914 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
15915 operands[1] = gen_lowpart (QImode, operands[1]);
15916 })
15917
15918 (define_insn_and_split "*btr<mode>_mask_1"
15919 [(set (match_operand:SWI48 0 "register_operand")
15920 (and:SWI48
15921 (rotate:SWI48
15922 (const_int -2)
15923 (and:QI
15924 (match_operand:QI 1 "register_operand")
15925 (match_operand:QI 2 "const_int_operand")))
15926 (match_operand:SWI48 3 "register_operand")))
15927 (clobber (reg:CC FLAGS_REG))]
15928 "TARGET_USE_BT
15929 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15930 == GET_MODE_BITSIZE (<MODE>mode)-1
15931 && ix86_pre_reload_split ()"
15932 "#"
15933 "&& 1"
15934 [(parallel
15935 [(set (match_dup 0)
15936 (and:SWI48
15937 (rotate:SWI48 (const_int -2)
15938 (match_dup 1))
15939 (match_dup 3)))
15940 (clobber (reg:CC FLAGS_REG))])])
15941
15942 (define_insn_and_split "*btr<mode>_1"
15943 [(set (match_operand:SWI12 0 "register_operand")
15944 (and:SWI12
15945 (subreg:SWI12
15946 (rotate:SI (const_int -2)
15947 (match_operand:QI 2 "register_operand")) 0)
15948 (match_operand:SWI12 1 "nonimmediate_operand")))
15949 (clobber (reg:CC FLAGS_REG))]
15950 "TARGET_USE_BT && ix86_pre_reload_split ()"
15951 "#"
15952 "&& 1"
15953 [(parallel
15954 [(set (match_dup 0)
15955 (and:SI (rotate:SI (const_int -2) (match_dup 2))
15956 (match_dup 1)))
15957 (clobber (reg:CC FLAGS_REG))])]
15958 {
15959 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15960 operands[1] = force_reg (<MODE>mode, operands[1]);
15961 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
15962 })
15963
15964 (define_insn_and_split "*btr<mode>_2"
15965 [(set (zero_extract:HI
15966 (match_operand:SWI12 0 "nonimmediate_operand")
15967 (const_int 1)
15968 (zero_extend:SI (match_operand:QI 1 "register_operand")))
15969 (const_int 0))
15970 (clobber (reg:CC FLAGS_REG))]
15971 "TARGET_USE_BT && ix86_pre_reload_split ()"
15972 "#"
15973 "&& MEM_P (operands[0])"
15974 [(set (match_dup 2) (match_dup 0))
15975 (parallel
15976 [(set (match_dup 3)
15977 (and:SI (rotate:SI (const_int -2) (match_dup 1))
15978 (match_dup 4)))
15979 (clobber (reg:CC FLAGS_REG))])
15980 (set (match_dup 0) (match_dup 5))]
15981 {
15982 operands[2] = gen_reg_rtx (<MODE>mode);
15983 operands[5] = gen_reg_rtx (<MODE>mode);
15984 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
15985 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
15986 })
15987
15988 (define_split
15989 [(set (zero_extract:HI
15990 (match_operand:SWI12 0 "register_operand")
15991 (const_int 1)
15992 (zero_extend:SI (match_operand:QI 1 "register_operand")))
15993 (const_int 0))
15994 (clobber (reg:CC FLAGS_REG))]
15995 "TARGET_USE_BT && ix86_pre_reload_split ()"
15996 [(parallel
15997 [(set (match_dup 0)
15998 (and:SI (rotate:SI (const_int -2) (match_dup 1))
15999 (match_dup 2)))
16000 (clobber (reg:CC FLAGS_REG))])]
16001 {
16002 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16003 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
16004 })
16005
16006 ;; These instructions are never faster than the corresponding
16007 ;; and/ior/xor operations when using immediate operand, so with
16008 ;; 32-bit there's no point. But in 64-bit, we can't hold the
16009 ;; relevant immediates within the instruction itself, so operating
16010 ;; on bits in the high 32-bits of a register becomes easier.
16011 ;;
16012 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
16013 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
16014 ;; negdf respectively, so they can never be disabled entirely.
16015
16016 (define_insn "*btsq_imm"
16017 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16018 (const_int 1)
16019 (match_operand 1 "const_0_to_63_operand"))
16020 (const_int 1))
16021 (clobber (reg:CC FLAGS_REG))]
16022 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16023 "bts{q}\t{%1, %0|%0, %1}"
16024 [(set_attr "type" "alu1")
16025 (set_attr "prefix_0f" "1")
16026 (set_attr "znver1_decode" "double")
16027 (set_attr "mode" "DI")])
16028
16029 (define_insn "*btrq_imm"
16030 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16031 (const_int 1)
16032 (match_operand 1 "const_0_to_63_operand"))
16033 (const_int 0))
16034 (clobber (reg:CC FLAGS_REG))]
16035 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16036 "btr{q}\t{%1, %0|%0, %1}"
16037 [(set_attr "type" "alu1")
16038 (set_attr "prefix_0f" "1")
16039 (set_attr "znver1_decode" "double")
16040 (set_attr "mode" "DI")])
16041
16042 (define_insn "*btcq_imm"
16043 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
16044 (const_int 1)
16045 (match_operand 1 "const_0_to_63_operand"))
16046 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
16047 (clobber (reg:CC FLAGS_REG))]
16048 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
16049 "btc{q}\t{%1, %0|%0, %1}"
16050 [(set_attr "type" "alu1")
16051 (set_attr "prefix_0f" "1")
16052 (set_attr "znver1_decode" "double")
16053 (set_attr "mode" "DI")])
16054
16055 ;; Allow Nocona to avoid these instructions if a register is available.
16056
16057 (define_peephole2
16058 [(match_scratch:DI 2 "r")
16059 (parallel [(set (zero_extract:DI
16060 (match_operand:DI 0 "nonimmediate_operand")
16061 (const_int 1)
16062 (match_operand 1 "const_0_to_63_operand"))
16063 (const_int 1))
16064 (clobber (reg:CC FLAGS_REG))])]
16065 "TARGET_64BIT && !TARGET_USE_BT"
16066 [(parallel [(set (match_dup 0)
16067 (ior:DI (match_dup 0) (match_dup 3)))
16068 (clobber (reg:CC FLAGS_REG))])]
16069 {
16070 int i = INTVAL (operands[1]);
16071
16072 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16073
16074 if (!x86_64_immediate_operand (operands[3], DImode))
16075 {
16076 emit_move_insn (operands[2], operands[3]);
16077 operands[3] = operands[2];
16078 }
16079 })
16080
16081 (define_peephole2
16082 [(match_scratch:DI 2 "r")
16083 (parallel [(set (zero_extract:DI
16084 (match_operand:DI 0 "nonimmediate_operand")
16085 (const_int 1)
16086 (match_operand 1 "const_0_to_63_operand"))
16087 (const_int 0))
16088 (clobber (reg:CC FLAGS_REG))])]
16089 "TARGET_64BIT && !TARGET_USE_BT"
16090 [(parallel [(set (match_dup 0)
16091 (and:DI (match_dup 0) (match_dup 3)))
16092 (clobber (reg:CC FLAGS_REG))])]
16093 {
16094 int i = INTVAL (operands[1]);
16095
16096 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
16097
16098 if (!x86_64_immediate_operand (operands[3], DImode))
16099 {
16100 emit_move_insn (operands[2], operands[3]);
16101 operands[3] = operands[2];
16102 }
16103 })
16104
16105 (define_peephole2
16106 [(match_scratch:DI 2 "r")
16107 (parallel [(set (zero_extract:DI
16108 (match_operand:DI 0 "nonimmediate_operand")
16109 (const_int 1)
16110 (match_operand 1 "const_0_to_63_operand"))
16111 (not:DI (zero_extract:DI
16112 (match_dup 0) (const_int 1) (match_dup 1))))
16113 (clobber (reg:CC FLAGS_REG))])]
16114 "TARGET_64BIT && !TARGET_USE_BT"
16115 [(parallel [(set (match_dup 0)
16116 (xor:DI (match_dup 0) (match_dup 3)))
16117 (clobber (reg:CC FLAGS_REG))])]
16118 {
16119 int i = INTVAL (operands[1]);
16120
16121 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16122
16123 if (!x86_64_immediate_operand (operands[3], DImode))
16124 {
16125 emit_move_insn (operands[2], operands[3]);
16126 operands[3] = operands[2];
16127 }
16128 })
16129
16130 ;; %%% bt
16131
16132 (define_insn "*bt<mode>"
16133 [(set (reg:CCC FLAGS_REG)
16134 (compare:CCC
16135 (zero_extract:SWI48
16136 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16137 (const_int 1)
16138 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
16139 (const_int 0)))]
16140 ""
16141 {
16142 switch (get_attr_mode (insn))
16143 {
16144 case MODE_SI:
16145 return "bt{l}\t{%1, %k0|%k0, %1}";
16146
16147 case MODE_DI:
16148 return "bt{q}\t{%q1, %0|%0, %q1}";
16149
16150 default:
16151 gcc_unreachable ();
16152 }
16153 }
16154 [(set_attr "type" "alu1")
16155 (set_attr "prefix_0f" "1")
16156 (set (attr "mode")
16157 (if_then_else
16158 (and (match_test "CONST_INT_P (operands[1])")
16159 (match_test "INTVAL (operands[1]) < 32"))
16160 (const_string "SI")
16161 (const_string "<MODE>")))])
16162
16163 (define_insn_and_split "*jcc_bt<mode>"
16164 [(set (pc)
16165 (if_then_else (match_operator 0 "bt_comparison_operator"
16166 [(zero_extract:SWI48
16167 (match_operand:SWI48 1 "nonimmediate_operand")
16168 (const_int 1)
16169 (match_operand:SI 2 "nonmemory_operand"))
16170 (const_int 0)])
16171 (label_ref (match_operand 3))
16172 (pc)))
16173 (clobber (reg:CC FLAGS_REG))]
16174 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16175 && (CONST_INT_P (operands[2])
16176 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16177 && INTVAL (operands[2])
16178 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16179 : !memory_operand (operands[1], <MODE>mode))
16180 && ix86_pre_reload_split ()"
16181 "#"
16182 "&& 1"
16183 [(set (reg:CCC FLAGS_REG)
16184 (compare:CCC
16185 (zero_extract:SWI48
16186 (match_dup 1)
16187 (const_int 1)
16188 (match_dup 2))
16189 (const_int 0)))
16190 (set (pc)
16191 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16192 (label_ref (match_dup 3))
16193 (pc)))]
16194 {
16195 operands[0] = shallow_copy_rtx (operands[0]);
16196 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16197 })
16198
16199 (define_insn_and_split "*jcc_bt<mode>_1"
16200 [(set (pc)
16201 (if_then_else (match_operator 0 "bt_comparison_operator"
16202 [(zero_extract:SWI48
16203 (match_operand:SWI48 1 "register_operand")
16204 (const_int 1)
16205 (zero_extend:SI
16206 (match_operand:QI 2 "register_operand")))
16207 (const_int 0)])
16208 (label_ref (match_operand 3))
16209 (pc)))
16210 (clobber (reg:CC FLAGS_REG))]
16211 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16212 && ix86_pre_reload_split ()"
16213 "#"
16214 "&& 1"
16215 [(set (reg:CCC FLAGS_REG)
16216 (compare:CCC
16217 (zero_extract:SWI48
16218 (match_dup 1)
16219 (const_int 1)
16220 (match_dup 2))
16221 (const_int 0)))
16222 (set (pc)
16223 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16224 (label_ref (match_dup 3))
16225 (pc)))]
16226 {
16227 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16228 operands[0] = shallow_copy_rtx (operands[0]);
16229 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16230 })
16231
16232 ;; Avoid useless masking of bit offset operand.
16233 (define_insn_and_split "*jcc_bt<mode>_mask"
16234 [(set (pc)
16235 (if_then_else (match_operator 0 "bt_comparison_operator"
16236 [(zero_extract:SWI48
16237 (match_operand:SWI48 1 "register_operand")
16238 (const_int 1)
16239 (and:SI
16240 (match_operand:SI 2 "register_operand")
16241 (match_operand 3 "const_int_operand")))])
16242 (label_ref (match_operand 4))
16243 (pc)))
16244 (clobber (reg:CC FLAGS_REG))]
16245 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16246 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16247 == GET_MODE_BITSIZE (<MODE>mode)-1
16248 && ix86_pre_reload_split ()"
16249 "#"
16250 "&& 1"
16251 [(set (reg:CCC FLAGS_REG)
16252 (compare:CCC
16253 (zero_extract:SWI48
16254 (match_dup 1)
16255 (const_int 1)
16256 (match_dup 2))
16257 (const_int 0)))
16258 (set (pc)
16259 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16260 (label_ref (match_dup 4))
16261 (pc)))]
16262 {
16263 operands[0] = shallow_copy_rtx (operands[0]);
16264 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16265 })
16266
16267 (define_insn_and_split "*jcc_bt<mode>_mask_1"
16268 [(set (pc)
16269 (if_then_else (match_operator 0 "bt_comparison_operator"
16270 [(zero_extract:SWI48
16271 (match_operand:SWI48 1 "register_operand")
16272 (const_int 1)
16273 (zero_extend:SI
16274 (subreg:QI
16275 (and
16276 (match_operand 2 "int248_register_operand")
16277 (match_operand 3 "const_int_operand")) 0)))])
16278 (label_ref (match_operand 4))
16279 (pc)))
16280 (clobber (reg:CC FLAGS_REG))]
16281 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16282 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16283 == GET_MODE_BITSIZE (<MODE>mode)-1
16284 && ix86_pre_reload_split ()"
16285 "#"
16286 "&& 1"
16287 [(set (reg:CCC FLAGS_REG)
16288 (compare:CCC
16289 (zero_extract:SWI48
16290 (match_dup 1)
16291 (const_int 1)
16292 (match_dup 2))
16293 (const_int 0)))
16294 (set (pc)
16295 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16296 (label_ref (match_dup 4))
16297 (pc)))]
16298 {
16299 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16300 operands[2] = gen_lowpart (SImode, operands[2]);
16301 operands[0] = shallow_copy_rtx (operands[0]);
16302 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16303 })
16304
16305 ;; Help combine recognize bt followed by cmov
16306 (define_split
16307 [(set (match_operand:SWI248 0 "register_operand")
16308 (if_then_else:SWI248
16309 (match_operator 5 "bt_comparison_operator"
16310 [(zero_extract:SWI48
16311 (match_operand:SWI48 1 "register_operand")
16312 (const_int 1)
16313 (zero_extend:SI (match_operand:QI 2 "register_operand")))
16314 (const_int 0)])
16315 (match_operand:SWI248 3 "nonimmediate_operand")
16316 (match_operand:SWI248 4 "nonimmediate_operand")))]
16317 "TARGET_USE_BT && TARGET_CMOVE
16318 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16319 && ix86_pre_reload_split ()"
16320 [(set (reg:CCC FLAGS_REG)
16321 (compare:CCC
16322 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16323 (const_int 0)))
16324 (set (match_dup 0)
16325 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16326 (match_dup 3)
16327 (match_dup 4)))]
16328 {
16329 if (GET_CODE (operands[5]) == EQ)
16330 std::swap (operands[3], operands[4]);
16331 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16332 })
16333
16334 ;; Help combine recognize bt followed by setc
16335 (define_insn_and_split "*bt<mode>_setcqi"
16336 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16337 (zero_extract:SWI48
16338 (match_operand:SWI48 1 "register_operand")
16339 (const_int 1)
16340 (zero_extend:SI (match_operand:QI 2 "register_operand"))))
16341 (clobber (reg:CC FLAGS_REG))]
16342 "TARGET_USE_BT && ix86_pre_reload_split ()"
16343 "#"
16344 "&& 1"
16345 [(set (reg:CCC FLAGS_REG)
16346 (compare:CCC
16347 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16348 (const_int 0)))
16349 (set (match_dup 0)
16350 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16351 "operands[2] = lowpart_subreg (SImode, operands[2], QImode);")
16352
16353 ;; Help combine recognize bt followed by setnc
16354 (define_insn_and_split "*bt<mode>_setncqi"
16355 [(set (match_operand:QI 0 "register_operand")
16356 (and:QI
16357 (not:QI
16358 (subreg:QI
16359 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16360 (match_operand:QI 2 "register_operand")) 0))
16361 (const_int 1)))
16362 (clobber (reg:CC FLAGS_REG))]
16363 "TARGET_USE_BT && ix86_pre_reload_split ()"
16364 "#"
16365 "&& 1"
16366 [(set (reg:CCC FLAGS_REG)
16367 (compare:CCC
16368 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16369 (const_int 0)))
16370 (set (match_dup 0)
16371 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16372 "operands[2] = lowpart_subreg (SImode, operands[2], QImode);")
16373
16374 (define_insn_and_split "*bt<mode>_setnc<mode>"
16375 [(set (match_operand:SWI48 0 "register_operand")
16376 (and:SWI48
16377 (not:SWI48
16378 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16379 (match_operand:QI 2 "register_operand")))
16380 (const_int 1)))
16381 (clobber (reg:CC FLAGS_REG))]
16382 "TARGET_USE_BT && ix86_pre_reload_split ()"
16383 "#"
16384 "&& 1"
16385 [(set (reg:CCC FLAGS_REG)
16386 (compare:CCC
16387 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16388 (const_int 0)))
16389 (set (match_dup 3)
16390 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16391 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16392 {
16393 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16394 operands[3] = gen_reg_rtx (QImode);
16395 })
16396
16397 ;; Help combine recognize bt followed by setnc (PR target/110588)
16398 (define_insn_and_split "*bt<mode>_setncqi_2"
16399 [(set (match_operand:QI 0 "register_operand")
16400 (eq:QI
16401 (zero_extract:SWI48
16402 (match_operand:SWI48 1 "register_operand")
16403 (const_int 1)
16404 (zero_extend:SI (match_operand:QI 2 "register_operand")))
16405 (const_int 0)))
16406 (clobber (reg:CC FLAGS_REG))]
16407 "TARGET_USE_BT && ix86_pre_reload_split ()"
16408 "#"
16409 "&& 1"
16410 [(set (reg:CCC FLAGS_REG)
16411 (compare:CCC
16412 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16413 (const_int 0)))
16414 (set (match_dup 0)
16415 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16416 "operands[2] = lowpart_subreg (SImode, operands[2], QImode);")
16417 \f
16418 ;; Store-flag instructions.
16419
16420 (define_split
16421 [(set (match_operand:QI 0 "nonimmediate_operand")
16422 (match_operator:QI 1 "add_comparison_operator"
16423 [(not:SWI (match_operand:SWI 2 "register_operand"))
16424 (match_operand:SWI 3 "nonimmediate_operand")]))]
16425 ""
16426 [(set (reg:CCC FLAGS_REG)
16427 (compare:CCC
16428 (plus:SWI (match_dup 2) (match_dup 3))
16429 (match_dup 2)))
16430 (set (match_dup 0)
16431 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16432
16433 (define_split
16434 [(set (match_operand:QI 0 "nonimmediate_operand")
16435 (match_operator:QI 1 "shr_comparison_operator"
16436 [(match_operand:DI 2 "register_operand")
16437 (match_operand 3 "const_int_operand")]))]
16438 "TARGET_64BIT
16439 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16440 [(set (reg:CCZ FLAGS_REG)
16441 (compare:CCZ
16442 (lshiftrt:DI (match_dup 2) (match_dup 4))
16443 (const_int 0)))
16444 (set (match_dup 0)
16445 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16446 {
16447 enum rtx_code new_code;
16448
16449 operands[1] = shallow_copy_rtx (operands[1]);
16450 switch (GET_CODE (operands[1]))
16451 {
16452 case GTU: new_code = NE; break;
16453 case LEU: new_code = EQ; break;
16454 default: gcc_unreachable ();
16455 }
16456 PUT_CODE (operands[1], new_code);
16457
16458 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16459 })
16460
16461 ;; For all sCOND expanders, also expand the compare or test insn that
16462 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16463
16464 (define_insn_and_split "*setcc_di_1"
16465 [(set (match_operand:DI 0 "register_operand" "=q")
16466 (match_operator:DI 1 "ix86_comparison_operator"
16467 [(reg FLAGS_REG) (const_int 0)]))]
16468 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16469 "#"
16470 "&& reload_completed"
16471 [(set (match_dup 2) (match_dup 1))
16472 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16473 {
16474 operands[1] = shallow_copy_rtx (operands[1]);
16475 PUT_MODE (operands[1], QImode);
16476 operands[2] = gen_lowpart (QImode, operands[0]);
16477 })
16478
16479 (define_insn_and_split "*setcc_<mode>_1_and"
16480 [(set (match_operand:SWI24 0 "register_operand" "=q")
16481 (match_operator:SWI24 1 "ix86_comparison_operator"
16482 [(reg FLAGS_REG) (const_int 0)]))
16483 (clobber (reg:CC FLAGS_REG))]
16484 "!TARGET_PARTIAL_REG_STALL
16485 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16486 "#"
16487 "&& reload_completed"
16488 [(set (match_dup 2) (match_dup 1))
16489 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16490 (clobber (reg:CC FLAGS_REG))])]
16491 {
16492 operands[1] = shallow_copy_rtx (operands[1]);
16493 PUT_MODE (operands[1], QImode);
16494 operands[2] = gen_lowpart (QImode, operands[0]);
16495 })
16496
16497 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16498 [(set (match_operand:SWI24 0 "register_operand" "=q")
16499 (match_operator:SWI24 1 "ix86_comparison_operator"
16500 [(reg FLAGS_REG) (const_int 0)]))]
16501 "!TARGET_PARTIAL_REG_STALL
16502 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16503 "#"
16504 "&& reload_completed"
16505 [(set (match_dup 2) (match_dup 1))
16506 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16507 {
16508 operands[1] = shallow_copy_rtx (operands[1]);
16509 PUT_MODE (operands[1], QImode);
16510 operands[2] = gen_lowpart (QImode, operands[0]);
16511 })
16512
16513 (define_insn "*setcc_qi"
16514 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16515 (match_operator:QI 1 "ix86_comparison_operator"
16516 [(reg FLAGS_REG) (const_int 0)]))]
16517 ""
16518 "set%C1\t%0"
16519 [(set_attr "type" "setcc")
16520 (set_attr "mode" "QI")])
16521
16522 (define_insn "*setcc_qi_slp"
16523 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16524 (match_operator:QI 1 "ix86_comparison_operator"
16525 [(reg FLAGS_REG) (const_int 0)]))]
16526 ""
16527 "set%C1\t%0"
16528 [(set_attr "type" "setcc")
16529 (set_attr "mode" "QI")])
16530
16531 ;; In general it is not safe to assume too much about CCmode registers,
16532 ;; so simplify-rtx stops when it sees a second one. Under certain
16533 ;; conditions this is safe on x86, so help combine not create
16534 ;;
16535 ;; seta %al
16536 ;; testb %al, %al
16537 ;; sete %al
16538
16539 (define_split
16540 [(set (match_operand:QI 0 "nonimmediate_operand")
16541 (ne:QI (match_operator 1 "ix86_comparison_operator"
16542 [(reg FLAGS_REG) (const_int 0)])
16543 (const_int 0)))]
16544 ""
16545 [(set (match_dup 0) (match_dup 1))]
16546 {
16547 operands[1] = shallow_copy_rtx (operands[1]);
16548 PUT_MODE (operands[1], QImode);
16549 })
16550
16551 (define_split
16552 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16553 (ne:QI (match_operator 1 "ix86_comparison_operator"
16554 [(reg FLAGS_REG) (const_int 0)])
16555 (const_int 0)))]
16556 ""
16557 [(set (match_dup 0) (match_dup 1))]
16558 {
16559 operands[1] = shallow_copy_rtx (operands[1]);
16560 PUT_MODE (operands[1], QImode);
16561 })
16562
16563 (define_split
16564 [(set (match_operand:QI 0 "nonimmediate_operand")
16565 (eq:QI (match_operator 1 "ix86_comparison_operator"
16566 [(reg FLAGS_REG) (const_int 0)])
16567 (const_int 0)))]
16568 ""
16569 [(set (match_dup 0) (match_dup 1))]
16570 {
16571 operands[1] = shallow_copy_rtx (operands[1]);
16572 PUT_MODE (operands[1], QImode);
16573 PUT_CODE (operands[1],
16574 ix86_reverse_condition (GET_CODE (operands[1]),
16575 GET_MODE (XEXP (operands[1], 0))));
16576
16577 /* Make sure that (a) the CCmode we have for the flags is strong
16578 enough for the reversed compare or (b) we have a valid FP compare. */
16579 if (! ix86_comparison_operator (operands[1], VOIDmode))
16580 FAIL;
16581 })
16582
16583 (define_split
16584 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16585 (eq:QI (match_operator 1 "ix86_comparison_operator"
16586 [(reg FLAGS_REG) (const_int 0)])
16587 (const_int 0)))]
16588 ""
16589 [(set (match_dup 0) (match_dup 1))]
16590 {
16591 operands[1] = shallow_copy_rtx (operands[1]);
16592 PUT_MODE (operands[1], QImode);
16593 PUT_CODE (operands[1],
16594 ix86_reverse_condition (GET_CODE (operands[1]),
16595 GET_MODE (XEXP (operands[1], 0))));
16596
16597 /* Make sure that (a) the CCmode we have for the flags is strong
16598 enough for the reversed compare or (b) we have a valid FP compare. */
16599 if (! ix86_comparison_operator (operands[1], VOIDmode))
16600 FAIL;
16601 })
16602
16603 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
16604 ;; subsequent logical operations are used to imitate conditional moves.
16605 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
16606 ;; it directly.
16607
16608 (define_insn "setcc_<mode>_sse"
16609 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16610 (match_operator:MODEF 3 "sse_comparison_operator"
16611 [(match_operand:MODEF 1 "register_operand" "0,x")
16612 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
16613 "SSE_FLOAT_MODE_P (<MODE>mode)"
16614 "@
16615 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
16616 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16617 [(set_attr "isa" "noavx,avx")
16618 (set_attr "type" "ssecmp")
16619 (set_attr "length_immediate" "1")
16620 (set_attr "prefix" "orig,vex")
16621 (set_attr "mode" "<MODE>")])
16622
16623 (define_insn "setcc_hf_mask"
16624 [(set (match_operand:QI 0 "register_operand" "=k")
16625 (unspec:QI
16626 [(match_operand:HF 1 "register_operand" "v")
16627 (match_operand:HF 2 "nonimmediate_operand" "vm")
16628 (match_operand:SI 3 "const_0_to_31_operand")]
16629 UNSPEC_PCMP))]
16630 "TARGET_AVX512FP16"
16631 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16632 [(set_attr "type" "ssecmp")
16633 (set_attr "prefix" "evex")
16634 (set_attr "mode" "HF")])
16635
16636 \f
16637 ;; Basic conditional jump instructions.
16638
16639 (define_split
16640 [(set (pc)
16641 (if_then_else
16642 (match_operator 1 "add_comparison_operator"
16643 [(not:SWI (match_operand:SWI 2 "register_operand"))
16644 (match_operand:SWI 3 "nonimmediate_operand")])
16645 (label_ref (match_operand 0))
16646 (pc)))]
16647 ""
16648 [(set (reg:CCC FLAGS_REG)
16649 (compare:CCC
16650 (plus:SWI (match_dup 2) (match_dup 3))
16651 (match_dup 2)))
16652 (set (pc)
16653 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
16654 (label_ref (match_operand 0))
16655 (pc)))])
16656
16657 (define_split
16658 [(set (pc)
16659 (if_then_else
16660 (match_operator 1 "shr_comparison_operator"
16661 [(match_operand:DI 2 "register_operand")
16662 (match_operand 3 "const_int_operand")])
16663 (label_ref (match_operand 0))
16664 (pc)))]
16665 "TARGET_64BIT
16666 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16667 [(set (reg:CCZ FLAGS_REG)
16668 (compare:CCZ
16669 (lshiftrt:DI (match_dup 2) (match_dup 4))
16670 (const_int 0)))
16671 (set (pc)
16672 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
16673 (label_ref (match_operand 0))
16674 (pc)))]
16675 {
16676 enum rtx_code new_code;
16677
16678 operands[1] = shallow_copy_rtx (operands[1]);
16679 switch (GET_CODE (operands[1]))
16680 {
16681 case GTU: new_code = NE; break;
16682 case LEU: new_code = EQ; break;
16683 default: gcc_unreachable ();
16684 }
16685 PUT_CODE (operands[1], new_code);
16686
16687 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16688 })
16689
16690 ;; We ignore the overflow flag for signed branch instructions.
16691
16692 (define_insn "*jcc"
16693 [(set (pc)
16694 (if_then_else (match_operator 1 "ix86_comparison_operator"
16695 [(reg FLAGS_REG) (const_int 0)])
16696 (label_ref (match_operand 0))
16697 (pc)))]
16698 ""
16699 "%!%+j%C1\t%l0"
16700 [(set_attr "type" "ibr")
16701 (set_attr "modrm" "0")
16702 (set (attr "length")
16703 (if_then_else
16704 (and (ge (minus (match_dup 0) (pc))
16705 (const_int -126))
16706 (lt (minus (match_dup 0) (pc))
16707 (const_int 128)))
16708 (const_int 2)
16709 (const_int 6)))])
16710
16711 ;; In general it is not safe to assume too much about CCmode registers,
16712 ;; so simplify-rtx stops when it sees a second one. Under certain
16713 ;; conditions this is safe on x86, so help combine not create
16714 ;;
16715 ;; seta %al
16716 ;; testb %al, %al
16717 ;; je Lfoo
16718
16719 (define_split
16720 [(set (pc)
16721 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
16722 [(reg FLAGS_REG) (const_int 0)])
16723 (const_int 0))
16724 (label_ref (match_operand 1))
16725 (pc)))]
16726 ""
16727 [(set (pc)
16728 (if_then_else (match_dup 0)
16729 (label_ref (match_dup 1))
16730 (pc)))]
16731 {
16732 operands[0] = shallow_copy_rtx (operands[0]);
16733 PUT_MODE (operands[0], VOIDmode);
16734 })
16735
16736 (define_split
16737 [(set (pc)
16738 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
16739 [(reg FLAGS_REG) (const_int 0)])
16740 (const_int 0))
16741 (label_ref (match_operand 1))
16742 (pc)))]
16743 ""
16744 [(set (pc)
16745 (if_then_else (match_dup 0)
16746 (label_ref (match_dup 1))
16747 (pc)))]
16748 {
16749 operands[0] = shallow_copy_rtx (operands[0]);
16750 PUT_MODE (operands[0], VOIDmode);
16751 PUT_CODE (operands[0],
16752 ix86_reverse_condition (GET_CODE (operands[0]),
16753 GET_MODE (XEXP (operands[0], 0))));
16754
16755 /* Make sure that (a) the CCmode we have for the flags is strong
16756 enough for the reversed compare or (b) we have a valid FP compare. */
16757 if (! ix86_comparison_operator (operands[0], VOIDmode))
16758 FAIL;
16759 })
16760 \f
16761 ;; Unconditional and other jump instructions
16762
16763 (define_insn "jump"
16764 [(set (pc)
16765 (label_ref (match_operand 0)))]
16766 ""
16767 "%!jmp\t%l0"
16768 [(set_attr "type" "ibr")
16769 (set_attr "modrm" "0")
16770 (set (attr "length")
16771 (if_then_else
16772 (and (ge (minus (match_dup 0) (pc))
16773 (const_int -126))
16774 (lt (minus (match_dup 0) (pc))
16775 (const_int 128)))
16776 (const_int 2)
16777 (const_int 5)))])
16778
16779 (define_expand "indirect_jump"
16780 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
16781 ""
16782 {
16783 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16784 operands[0] = convert_memory_address (word_mode, operands[0]);
16785 cfun->machine->has_local_indirect_jump = true;
16786 })
16787
16788 (define_insn "*indirect_jump"
16789 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
16790 ""
16791 "* return ix86_output_indirect_jmp (operands[0]);"
16792 [(set (attr "type")
16793 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16794 != indirect_branch_keep)")
16795 (const_string "multi")
16796 (const_string "ibr")))
16797 (set_attr "length_immediate" "0")])
16798
16799 (define_expand "tablejump"
16800 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
16801 (use (label_ref (match_operand 1)))])]
16802 ""
16803 {
16804 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
16805 relative. Convert the relative address to an absolute address. */
16806 if (flag_pic)
16807 {
16808 rtx op0, op1;
16809 enum rtx_code code;
16810
16811 /* We can't use @GOTOFF for text labels on VxWorks;
16812 see gotoff_operand. */
16813 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
16814 {
16815 code = PLUS;
16816 op0 = operands[0];
16817 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
16818 }
16819 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
16820 {
16821 code = PLUS;
16822 op0 = operands[0];
16823 op1 = pic_offset_table_rtx;
16824 }
16825 else
16826 {
16827 code = MINUS;
16828 op0 = pic_offset_table_rtx;
16829 op1 = operands[0];
16830 }
16831
16832 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
16833 OPTAB_DIRECT);
16834 }
16835
16836 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16837 operands[0] = convert_memory_address (word_mode, operands[0]);
16838 cfun->machine->has_local_indirect_jump = true;
16839 })
16840
16841 (define_insn "*tablejump_1"
16842 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
16843 (use (label_ref (match_operand 1)))]
16844 ""
16845 "* return ix86_output_indirect_jmp (operands[0]);"
16846 [(set (attr "type")
16847 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16848 != indirect_branch_keep)")
16849 (const_string "multi")
16850 (const_string "ibr")))
16851 (set_attr "length_immediate" "0")])
16852 \f
16853 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
16854
16855 (define_peephole2
16856 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
16857 (set (match_operand:QI 1 "register_operand")
16858 (match_operator:QI 2 "ix86_comparison_operator"
16859 [(reg FLAGS_REG) (const_int 0)]))
16860 (set (match_operand 3 "any_QIreg_operand")
16861 (zero_extend (match_dup 1)))]
16862 "(peep2_reg_dead_p (3, operands[1])
16863 || operands_match_p (operands[1], operands[3]))
16864 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16865 && peep2_regno_dead_p (0, FLAGS_REG)"
16866 [(set (match_dup 4) (match_dup 0))
16867 (set (strict_low_part (match_dup 5))
16868 (match_dup 2))]
16869 {
16870 operands[5] = gen_lowpart (QImode, operands[3]);
16871 ix86_expand_clear (operands[3]);
16872 })
16873
16874 (define_peephole2
16875 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
16876 (match_operand 4)])
16877 (set (match_operand:QI 1 "register_operand")
16878 (match_operator:QI 2 "ix86_comparison_operator"
16879 [(reg FLAGS_REG) (const_int 0)]))
16880 (set (match_operand 3 "any_QIreg_operand")
16881 (zero_extend (match_dup 1)))]
16882 "(peep2_reg_dead_p (3, operands[1])
16883 || operands_match_p (operands[1], operands[3]))
16884 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16885 && ! reg_overlap_mentioned_p (operands[3], operands[4])
16886 && ! reg_set_p (operands[3], operands[4])
16887 && peep2_regno_dead_p (0, FLAGS_REG)"
16888 [(parallel [(set (match_dup 5) (match_dup 0))
16889 (match_dup 4)])
16890 (set (strict_low_part (match_dup 6))
16891 (match_dup 2))]
16892 {
16893 operands[6] = gen_lowpart (QImode, operands[3]);
16894 ix86_expand_clear (operands[3]);
16895 })
16896
16897 (define_peephole2
16898 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
16899 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
16900 (match_operand 5)])
16901 (set (match_operand:QI 2 "register_operand")
16902 (match_operator:QI 3 "ix86_comparison_operator"
16903 [(reg FLAGS_REG) (const_int 0)]))
16904 (set (match_operand 4 "any_QIreg_operand")
16905 (zero_extend (match_dup 2)))]
16906 "(peep2_reg_dead_p (4, operands[2])
16907 || operands_match_p (operands[2], operands[4]))
16908 && ! reg_overlap_mentioned_p (operands[4], operands[0])
16909 && ! reg_overlap_mentioned_p (operands[4], operands[1])
16910 && ! reg_overlap_mentioned_p (operands[4], operands[5])
16911 && ! reg_set_p (operands[4], operands[5])
16912 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
16913 && peep2_regno_dead_p (0, FLAGS_REG)"
16914 [(set (match_dup 6) (match_dup 0))
16915 (parallel [(set (match_dup 7) (match_dup 1))
16916 (match_dup 5)])
16917 (set (strict_low_part (match_dup 8))
16918 (match_dup 3))]
16919 {
16920 operands[8] = gen_lowpart (QImode, operands[4]);
16921 ix86_expand_clear (operands[4]);
16922 })
16923
16924 ;; Similar, but match zero extend with andsi3.
16925
16926 (define_peephole2
16927 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
16928 (set (match_operand:QI 1 "register_operand")
16929 (match_operator:QI 2 "ix86_comparison_operator"
16930 [(reg FLAGS_REG) (const_int 0)]))
16931 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
16932 (and:SI (match_dup 3) (const_int 255)))
16933 (clobber (reg:CC FLAGS_REG))])]
16934 "REGNO (operands[1]) == REGNO (operands[3])
16935 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16936 && peep2_regno_dead_p (0, FLAGS_REG)"
16937 [(set (match_dup 4) (match_dup 0))
16938 (set (strict_low_part (match_dup 5))
16939 (match_dup 2))]
16940 {
16941 operands[5] = gen_lowpart (QImode, operands[3]);
16942 ix86_expand_clear (operands[3]);
16943 })
16944
16945 (define_peephole2
16946 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
16947 (match_operand 4)])
16948 (set (match_operand:QI 1 "register_operand")
16949 (match_operator:QI 2 "ix86_comparison_operator"
16950 [(reg FLAGS_REG) (const_int 0)]))
16951 (parallel [(set (match_operand 3 "any_QIreg_operand")
16952 (zero_extend (match_dup 1)))
16953 (clobber (reg:CC FLAGS_REG))])]
16954 "(peep2_reg_dead_p (3, operands[1])
16955 || operands_match_p (operands[1], operands[3]))
16956 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16957 && ! reg_overlap_mentioned_p (operands[3], operands[4])
16958 && ! reg_set_p (operands[3], operands[4])
16959 && peep2_regno_dead_p (0, FLAGS_REG)"
16960 [(parallel [(set (match_dup 5) (match_dup 0))
16961 (match_dup 4)])
16962 (set (strict_low_part (match_dup 6))
16963 (match_dup 2))]
16964 {
16965 operands[6] = gen_lowpart (QImode, operands[3]);
16966 ix86_expand_clear (operands[3]);
16967 })
16968
16969 (define_peephole2
16970 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
16971 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
16972 (match_operand 5)])
16973 (set (match_operand:QI 2 "register_operand")
16974 (match_operator:QI 3 "ix86_comparison_operator"
16975 [(reg FLAGS_REG) (const_int 0)]))
16976 (parallel [(set (match_operand 4 "any_QIreg_operand")
16977 (zero_extend (match_dup 2)))
16978 (clobber (reg:CC FLAGS_REG))])]
16979 "(peep2_reg_dead_p (4, operands[2])
16980 || operands_match_p (operands[2], operands[4]))
16981 && ! reg_overlap_mentioned_p (operands[4], operands[0])
16982 && ! reg_overlap_mentioned_p (operands[4], operands[1])
16983 && ! reg_overlap_mentioned_p (operands[4], operands[5])
16984 && ! reg_set_p (operands[4], operands[5])
16985 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
16986 && peep2_regno_dead_p (0, FLAGS_REG)"
16987 [(set (match_dup 6) (match_dup 0))
16988 (parallel [(set (match_dup 7) (match_dup 1))
16989 (match_dup 5)])
16990 (set (strict_low_part (match_dup 8))
16991 (match_dup 3))]
16992 {
16993 operands[8] = gen_lowpart (QImode, operands[4]);
16994 ix86_expand_clear (operands[4]);
16995 })
16996 \f
16997 ;; Call instructions.
16998
16999 ;; The predicates normally associated with named expanders are not properly
17000 ;; checked for calls. This is a bug in the generic code, but it isn't that
17001 ;; easy to fix. Ignore it for now and be prepared to fix things up.
17002
17003 ;; P6 processors will jump to the address after the decrement when %esp
17004 ;; is used as a call operand, so they will execute return address as a code.
17005 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
17006
17007 ;; Register constraint for call instruction.
17008 (define_mode_attr c [(SI "l") (DI "r")])
17009
17010 ;; Call subroutine returning no value.
17011
17012 (define_expand "call"
17013 [(call (match_operand:QI 0)
17014 (match_operand 1))
17015 (use (match_operand 2))]
17016 ""
17017 {
17018 ix86_expand_call (NULL, operands[0], operands[1],
17019 operands[2], NULL, false);
17020 DONE;
17021 })
17022
17023 (define_expand "sibcall"
17024 [(call (match_operand:QI 0)
17025 (match_operand 1))
17026 (use (match_operand 2))]
17027 ""
17028 {
17029 ix86_expand_call (NULL, operands[0], operands[1],
17030 operands[2], NULL, true);
17031 DONE;
17032 })
17033
17034 (define_insn "*call"
17035 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
17036 (match_operand 1))]
17037 "!SIBLING_CALL_P (insn)"
17038 "* return ix86_output_call_insn (insn, operands[0]);"
17039 [(set_attr "type" "call")])
17040
17041 ;; This covers both call and sibcall since only GOT slot is allowed.
17042 (define_insn "*call_got_x32"
17043 [(call (mem:QI (zero_extend:DI
17044 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
17045 (match_operand 1))]
17046 "TARGET_X32"
17047 {
17048 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
17049 return ix86_output_call_insn (insn, fnaddr);
17050 }
17051 [(set_attr "type" "call")])
17052
17053 ;; Since sibcall never returns, we can only use call-clobbered register
17054 ;; as GOT base.
17055 (define_insn "*sibcall_GOT_32"
17056 [(call (mem:QI
17057 (mem:SI (plus:SI
17058 (match_operand:SI 0 "register_no_elim_operand" "U")
17059 (match_operand:SI 1 "GOT32_symbol_operand"))))
17060 (match_operand 2))]
17061 "!TARGET_MACHO
17062 && !TARGET_64BIT
17063 && !TARGET_INDIRECT_BRANCH_REGISTER
17064 && SIBLING_CALL_P (insn)"
17065 {
17066 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
17067 fnaddr = gen_const_mem (SImode, fnaddr);
17068 return ix86_output_call_insn (insn, fnaddr);
17069 }
17070 [(set_attr "type" "call")])
17071
17072 (define_insn "*sibcall"
17073 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
17074 (match_operand 1))]
17075 "SIBLING_CALL_P (insn)"
17076 "* return ix86_output_call_insn (insn, operands[0]);"
17077 [(set_attr "type" "call")])
17078
17079 (define_insn "*sibcall_memory"
17080 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
17081 (match_operand 1))
17082 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17083 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17084 "* return ix86_output_call_insn (insn, operands[0]);"
17085 [(set_attr "type" "call")])
17086
17087 (define_peephole2
17088 [(set (match_operand:W 0 "register_operand")
17089 (match_operand:W 1 "memory_operand"))
17090 (call (mem:QI (match_dup 0))
17091 (match_operand 3))]
17092 "!TARGET_X32
17093 && !TARGET_INDIRECT_BRANCH_REGISTER
17094 && SIBLING_CALL_P (peep2_next_insn (1))
17095 && !reg_mentioned_p (operands[0],
17096 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17097 [(parallel [(call (mem:QI (match_dup 1))
17098 (match_dup 3))
17099 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17100
17101 (define_peephole2
17102 [(set (match_operand:W 0 "register_operand")
17103 (match_operand:W 1 "memory_operand"))
17104 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17105 (call (mem:QI (match_dup 0))
17106 (match_operand 3))]
17107 "!TARGET_X32
17108 && !TARGET_INDIRECT_BRANCH_REGISTER
17109 && SIBLING_CALL_P (peep2_next_insn (2))
17110 && !reg_mentioned_p (operands[0],
17111 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17112 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17113 (parallel [(call (mem:QI (match_dup 1))
17114 (match_dup 3))
17115 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17116
17117 (define_expand "call_pop"
17118 [(parallel [(call (match_operand:QI 0)
17119 (match_operand:SI 1))
17120 (set (reg:SI SP_REG)
17121 (plus:SI (reg:SI SP_REG)
17122 (match_operand:SI 3)))])]
17123 "!TARGET_64BIT"
17124 {
17125 ix86_expand_call (NULL, operands[0], operands[1],
17126 operands[2], operands[3], false);
17127 DONE;
17128 })
17129
17130 (define_insn "*call_pop"
17131 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17132 (match_operand 1))
17133 (set (reg:SI SP_REG)
17134 (plus:SI (reg:SI SP_REG)
17135 (match_operand:SI 2 "immediate_operand" "i")))]
17136 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17137 "* return ix86_output_call_insn (insn, operands[0]);"
17138 [(set_attr "type" "call")])
17139
17140 (define_insn "*sibcall_pop"
17141 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17142 (match_operand 1))
17143 (set (reg:SI SP_REG)
17144 (plus:SI (reg:SI SP_REG)
17145 (match_operand:SI 2 "immediate_operand" "i")))]
17146 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17147 "* return ix86_output_call_insn (insn, operands[0]);"
17148 [(set_attr "type" "call")])
17149
17150 (define_insn "*sibcall_pop_memory"
17151 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17152 (match_operand 1))
17153 (set (reg:SI SP_REG)
17154 (plus:SI (reg:SI SP_REG)
17155 (match_operand:SI 2 "immediate_operand" "i")))
17156 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17157 "!TARGET_64BIT"
17158 "* return ix86_output_call_insn (insn, operands[0]);"
17159 [(set_attr "type" "call")])
17160
17161 (define_peephole2
17162 [(set (match_operand:SI 0 "register_operand")
17163 (match_operand:SI 1 "memory_operand"))
17164 (parallel [(call (mem:QI (match_dup 0))
17165 (match_operand 3))
17166 (set (reg:SI SP_REG)
17167 (plus:SI (reg:SI SP_REG)
17168 (match_operand:SI 4 "immediate_operand")))])]
17169 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17170 && !reg_mentioned_p (operands[0],
17171 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17172 [(parallel [(call (mem:QI (match_dup 1))
17173 (match_dup 3))
17174 (set (reg:SI SP_REG)
17175 (plus:SI (reg:SI SP_REG)
17176 (match_dup 4)))
17177 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17178
17179 (define_peephole2
17180 [(set (match_operand:SI 0 "register_operand")
17181 (match_operand:SI 1 "memory_operand"))
17182 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17183 (parallel [(call (mem:QI (match_dup 0))
17184 (match_operand 3))
17185 (set (reg:SI SP_REG)
17186 (plus:SI (reg:SI SP_REG)
17187 (match_operand:SI 4 "immediate_operand")))])]
17188 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17189 && !reg_mentioned_p (operands[0],
17190 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17191 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17192 (parallel [(call (mem:QI (match_dup 1))
17193 (match_dup 3))
17194 (set (reg:SI SP_REG)
17195 (plus:SI (reg:SI SP_REG)
17196 (match_dup 4)))
17197 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17198
17199 ;; Combining simple memory jump instruction
17200
17201 (define_peephole2
17202 [(set (match_operand:W 0 "register_operand")
17203 (match_operand:W 1 "memory_operand"))
17204 (set (pc) (match_dup 0))]
17205 "!TARGET_X32
17206 && !TARGET_INDIRECT_BRANCH_REGISTER
17207 && peep2_reg_dead_p (2, operands[0])"
17208 [(set (pc) (match_dup 1))])
17209
17210 ;; Call subroutine, returning value in operand 0
17211
17212 (define_expand "call_value"
17213 [(set (match_operand 0)
17214 (call (match_operand:QI 1)
17215 (match_operand 2)))
17216 (use (match_operand 3))]
17217 ""
17218 {
17219 ix86_expand_call (operands[0], operands[1], operands[2],
17220 operands[3], NULL, false);
17221 DONE;
17222 })
17223
17224 (define_expand "sibcall_value"
17225 [(set (match_operand 0)
17226 (call (match_operand:QI 1)
17227 (match_operand 2)))
17228 (use (match_operand 3))]
17229 ""
17230 {
17231 ix86_expand_call (operands[0], operands[1], operands[2],
17232 operands[3], NULL, true);
17233 DONE;
17234 })
17235
17236 (define_insn "*call_value"
17237 [(set (match_operand 0)
17238 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17239 (match_operand 2)))]
17240 "!SIBLING_CALL_P (insn)"
17241 "* return ix86_output_call_insn (insn, operands[1]);"
17242 [(set_attr "type" "callv")])
17243
17244 ;; This covers both call and sibcall since only GOT slot is allowed.
17245 (define_insn "*call_value_got_x32"
17246 [(set (match_operand 0)
17247 (call (mem:QI
17248 (zero_extend:DI
17249 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17250 (match_operand 2)))]
17251 "TARGET_X32"
17252 {
17253 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17254 return ix86_output_call_insn (insn, fnaddr);
17255 }
17256 [(set_attr "type" "callv")])
17257
17258 ;; Since sibcall never returns, we can only use call-clobbered register
17259 ;; as GOT base.
17260 (define_insn "*sibcall_value_GOT_32"
17261 [(set (match_operand 0)
17262 (call (mem:QI
17263 (mem:SI (plus:SI
17264 (match_operand:SI 1 "register_no_elim_operand" "U")
17265 (match_operand:SI 2 "GOT32_symbol_operand"))))
17266 (match_operand 3)))]
17267 "!TARGET_MACHO
17268 && !TARGET_64BIT
17269 && !TARGET_INDIRECT_BRANCH_REGISTER
17270 && SIBLING_CALL_P (insn)"
17271 {
17272 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17273 fnaddr = gen_const_mem (SImode, fnaddr);
17274 return ix86_output_call_insn (insn, fnaddr);
17275 }
17276 [(set_attr "type" "callv")])
17277
17278 (define_insn "*sibcall_value"
17279 [(set (match_operand 0)
17280 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17281 (match_operand 2)))]
17282 "SIBLING_CALL_P (insn)"
17283 "* return ix86_output_call_insn (insn, operands[1]);"
17284 [(set_attr "type" "callv")])
17285
17286 (define_insn "*sibcall_value_memory"
17287 [(set (match_operand 0)
17288 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17289 (match_operand 2)))
17290 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17291 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17292 "* return ix86_output_call_insn (insn, operands[1]);"
17293 [(set_attr "type" "callv")])
17294
17295 (define_peephole2
17296 [(set (match_operand:W 0 "register_operand")
17297 (match_operand:W 1 "memory_operand"))
17298 (set (match_operand 2)
17299 (call (mem:QI (match_dup 0))
17300 (match_operand 3)))]
17301 "!TARGET_X32
17302 && !TARGET_INDIRECT_BRANCH_REGISTER
17303 && SIBLING_CALL_P (peep2_next_insn (1))
17304 && !reg_mentioned_p (operands[0],
17305 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17306 [(parallel [(set (match_dup 2)
17307 (call (mem:QI (match_dup 1))
17308 (match_dup 3)))
17309 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17310
17311 (define_peephole2
17312 [(set (match_operand:W 0 "register_operand")
17313 (match_operand:W 1 "memory_operand"))
17314 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17315 (set (match_operand 2)
17316 (call (mem:QI (match_dup 0))
17317 (match_operand 3)))]
17318 "!TARGET_X32
17319 && !TARGET_INDIRECT_BRANCH_REGISTER
17320 && SIBLING_CALL_P (peep2_next_insn (2))
17321 && !reg_mentioned_p (operands[0],
17322 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17323 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17324 (parallel [(set (match_dup 2)
17325 (call (mem:QI (match_dup 1))
17326 (match_dup 3)))
17327 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17328
17329 (define_expand "call_value_pop"
17330 [(parallel [(set (match_operand 0)
17331 (call (match_operand:QI 1)
17332 (match_operand:SI 2)))
17333 (set (reg:SI SP_REG)
17334 (plus:SI (reg:SI SP_REG)
17335 (match_operand:SI 4)))])]
17336 "!TARGET_64BIT"
17337 {
17338 ix86_expand_call (operands[0], operands[1], operands[2],
17339 operands[3], operands[4], false);
17340 DONE;
17341 })
17342
17343 (define_insn "*call_value_pop"
17344 [(set (match_operand 0)
17345 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17346 (match_operand 2)))
17347 (set (reg:SI SP_REG)
17348 (plus:SI (reg:SI SP_REG)
17349 (match_operand:SI 3 "immediate_operand" "i")))]
17350 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17351 "* return ix86_output_call_insn (insn, operands[1]);"
17352 [(set_attr "type" "callv")])
17353
17354 (define_insn "*sibcall_value_pop"
17355 [(set (match_operand 0)
17356 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17357 (match_operand 2)))
17358 (set (reg:SI SP_REG)
17359 (plus:SI (reg:SI SP_REG)
17360 (match_operand:SI 3 "immediate_operand" "i")))]
17361 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17362 "* return ix86_output_call_insn (insn, operands[1]);"
17363 [(set_attr "type" "callv")])
17364
17365 (define_insn "*sibcall_value_pop_memory"
17366 [(set (match_operand 0)
17367 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17368 (match_operand 2)))
17369 (set (reg:SI SP_REG)
17370 (plus:SI (reg:SI SP_REG)
17371 (match_operand:SI 3 "immediate_operand" "i")))
17372 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17373 "!TARGET_64BIT"
17374 "* return ix86_output_call_insn (insn, operands[1]);"
17375 [(set_attr "type" "callv")])
17376
17377 (define_peephole2
17378 [(set (match_operand:SI 0 "register_operand")
17379 (match_operand:SI 1 "memory_operand"))
17380 (parallel [(set (match_operand 2)
17381 (call (mem:QI (match_dup 0))
17382 (match_operand 3)))
17383 (set (reg:SI SP_REG)
17384 (plus:SI (reg:SI SP_REG)
17385 (match_operand:SI 4 "immediate_operand")))])]
17386 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17387 && !reg_mentioned_p (operands[0],
17388 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17389 [(parallel [(set (match_dup 2)
17390 (call (mem:QI (match_dup 1))
17391 (match_dup 3)))
17392 (set (reg:SI SP_REG)
17393 (plus:SI (reg:SI SP_REG)
17394 (match_dup 4)))
17395 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17396
17397 (define_peephole2
17398 [(set (match_operand:SI 0 "register_operand")
17399 (match_operand:SI 1 "memory_operand"))
17400 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17401 (parallel [(set (match_operand 2)
17402 (call (mem:QI (match_dup 0))
17403 (match_operand 3)))
17404 (set (reg:SI SP_REG)
17405 (plus:SI (reg:SI SP_REG)
17406 (match_operand:SI 4 "immediate_operand")))])]
17407 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17408 && !reg_mentioned_p (operands[0],
17409 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17410 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17411 (parallel [(set (match_dup 2)
17412 (call (mem:QI (match_dup 1))
17413 (match_dup 3)))
17414 (set (reg:SI SP_REG)
17415 (plus:SI (reg:SI SP_REG)
17416 (match_dup 4)))
17417 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17418
17419 ;; Call subroutine returning any type.
17420
17421 (define_expand "untyped_call"
17422 [(parallel [(call (match_operand 0)
17423 (const_int 0))
17424 (match_operand 1)
17425 (match_operand 2)])]
17426 ""
17427 {
17428 int i;
17429
17430 /* In order to give reg-stack an easier job in validating two
17431 coprocessor registers as containing a possible return value,
17432 simply pretend the untyped call returns a complex long double
17433 value.
17434
17435 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17436 and should have the default ABI. */
17437
17438 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17439 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17440 operands[0], const0_rtx,
17441 GEN_INT ((TARGET_64BIT
17442 ? (ix86_abi == SYSV_ABI
17443 ? X86_64_SSE_REGPARM_MAX
17444 : X86_64_MS_SSE_REGPARM_MAX)
17445 : X86_32_SSE_REGPARM_MAX)
17446 - 1),
17447 NULL, false);
17448
17449 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17450 {
17451 rtx set = XVECEXP (operands[2], 0, i);
17452 emit_move_insn (SET_DEST (set), SET_SRC (set));
17453 }
17454
17455 /* The optimizer does not know that the call sets the function value
17456 registers we stored in the result block. We avoid problems by
17457 claiming that all hard registers are used and clobbered at this
17458 point. */
17459 emit_insn (gen_blockage ());
17460
17461 DONE;
17462 })
17463 \f
17464 ;; Prologue and epilogue instructions
17465
17466 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17467 ;; all of memory. This blocks insns from being moved across this point.
17468
17469 (define_insn "blockage"
17470 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17471 ""
17472 ""
17473 [(set_attr "length" "0")])
17474
17475 ;; Do not schedule instructions accessing memory across this point.
17476
17477 (define_expand "memory_blockage"
17478 [(set (match_dup 0)
17479 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17480 ""
17481 {
17482 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17483 MEM_VOLATILE_P (operands[0]) = 1;
17484 })
17485
17486 (define_insn "*memory_blockage"
17487 [(set (match_operand:BLK 0)
17488 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17489 ""
17490 ""
17491 [(set_attr "length" "0")])
17492
17493 ;; As USE insns aren't meaningful after reload, this is used instead
17494 ;; to prevent deleting instructions setting registers for PIC code
17495 (define_insn "prologue_use"
17496 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17497 ""
17498 ""
17499 [(set_attr "length" "0")])
17500
17501 ;; Insn emitted into the body of a function to return from a function.
17502 ;; This is only done if the function's epilogue is known to be simple.
17503 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17504
17505 (define_expand "return"
17506 [(simple_return)]
17507 "ix86_can_use_return_insn_p ()"
17508 {
17509 if (crtl->args.pops_args)
17510 {
17511 rtx popc = GEN_INT (crtl->args.pops_args);
17512 emit_jump_insn (gen_simple_return_pop_internal (popc));
17513 DONE;
17514 }
17515 })
17516
17517 ;; We need to disable this for TARGET_SEH, as otherwise
17518 ;; shrink-wrapped prologue gets enabled too. This might exceed
17519 ;; the maximum size of prologue in unwind information.
17520 ;; Also disallow shrink-wrapping if using stack slot to pass the
17521 ;; static chain pointer - the first instruction has to be pushl %esi
17522 ;; and it can't be moved around, as we use alternate entry points
17523 ;; in that case.
17524 ;; Also disallow for ms_hook_prologue functions which have frame
17525 ;; pointer set up in function label which is correctly handled in
17526 ;; ix86_expand_{prologue|epligoue}() only.
17527
17528 (define_expand "simple_return"
17529 [(simple_return)]
17530 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17531 {
17532 if (crtl->args.pops_args)
17533 {
17534 rtx popc = GEN_INT (crtl->args.pops_args);
17535 emit_jump_insn (gen_simple_return_pop_internal (popc));
17536 DONE;
17537 }
17538 })
17539
17540 (define_insn "simple_return_internal"
17541 [(simple_return)]
17542 "reload_completed"
17543 "* return ix86_output_function_return (false);"
17544 [(set_attr "length" "1")
17545 (set_attr "atom_unit" "jeu")
17546 (set_attr "length_immediate" "0")
17547 (set_attr "modrm" "0")])
17548
17549 (define_insn "interrupt_return"
17550 [(simple_return)
17551 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17552 "reload_completed"
17553 {
17554 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17555 })
17556
17557 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17558 ;; instruction Athlon and K8 have.
17559
17560 (define_insn "simple_return_internal_long"
17561 [(simple_return)
17562 (unspec [(const_int 0)] UNSPEC_REP)]
17563 "reload_completed"
17564 "* return ix86_output_function_return (true);"
17565 [(set_attr "length" "2")
17566 (set_attr "atom_unit" "jeu")
17567 (set_attr "length_immediate" "0")
17568 (set_attr "prefix_rep" "1")
17569 (set_attr "modrm" "0")])
17570
17571 (define_insn_and_split "simple_return_pop_internal"
17572 [(simple_return)
17573 (use (match_operand:SI 0 "const_int_operand"))]
17574 "reload_completed"
17575 "ret\t%0"
17576 "&& cfun->machine->function_return_type != indirect_branch_keep"
17577 [(const_int 0)]
17578 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17579 [(set_attr "length" "3")
17580 (set_attr "atom_unit" "jeu")
17581 (set_attr "length_immediate" "2")
17582 (set_attr "modrm" "0")])
17583
17584 (define_expand "simple_return_indirect_internal"
17585 [(parallel
17586 [(simple_return)
17587 (use (match_operand 0 "register_operand"))])])
17588
17589 (define_insn "*simple_return_indirect_internal<mode>"
17590 [(simple_return)
17591 (use (match_operand:W 0 "register_operand" "r"))]
17592 "reload_completed"
17593 "* return ix86_output_indirect_function_return (operands[0]);"
17594 [(set (attr "type")
17595 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17596 != indirect_branch_keep)")
17597 (const_string "multi")
17598 (const_string "ibr")))
17599 (set_attr "length_immediate" "0")])
17600
17601 (define_insn "nop"
17602 [(const_int 0)]
17603 ""
17604 "nop"
17605 [(set_attr "length" "1")
17606 (set_attr "length_immediate" "0")
17607 (set_attr "modrm" "0")])
17608
17609 ;; Generate nops. Operand 0 is the number of nops, up to 8.
17610 (define_insn "nops"
17611 [(unspec_volatile [(match_operand 0 "const_int_operand")]
17612 UNSPECV_NOPS)]
17613 "reload_completed"
17614 {
17615 int num = INTVAL (operands[0]);
17616
17617 gcc_assert (IN_RANGE (num, 1, 8));
17618
17619 while (num--)
17620 fputs ("\tnop\n", asm_out_file);
17621
17622 return "";
17623 }
17624 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
17625 (set_attr "length_immediate" "0")
17626 (set_attr "modrm" "0")])
17627
17628 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
17629 ;; branch prediction penalty for the third jump in a 16-byte
17630 ;; block on K8.
17631
17632 (define_insn "pad"
17633 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
17634 ""
17635 {
17636 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
17637 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
17638 #else
17639 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
17640 The align insn is used to avoid 3 jump instructions in the row to improve
17641 branch prediction and the benefits hardly outweigh the cost of extra 8
17642 nops on the average inserted by full alignment pseudo operation. */
17643 #endif
17644 return "";
17645 }
17646 [(set_attr "length" "16")])
17647
17648 (define_expand "prologue"
17649 [(const_int 0)]
17650 ""
17651 "ix86_expand_prologue (); DONE;")
17652
17653 (define_expand "set_got"
17654 [(parallel
17655 [(set (match_operand:SI 0 "register_operand")
17656 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17657 (clobber (reg:CC FLAGS_REG))])]
17658 "!TARGET_64BIT"
17659 {
17660 if (flag_pic && !TARGET_VXWORKS_RTP)
17661 ix86_pc_thunk_call_expanded = true;
17662 })
17663
17664 (define_insn "*set_got"
17665 [(set (match_operand:SI 0 "register_operand" "=r")
17666 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17667 (clobber (reg:CC FLAGS_REG))]
17668 "!TARGET_64BIT"
17669 "* return output_set_got (operands[0], NULL_RTX);"
17670 [(set_attr "type" "multi")
17671 (set_attr "length" "12")])
17672
17673 (define_expand "set_got_labelled"
17674 [(parallel
17675 [(set (match_operand:SI 0 "register_operand")
17676 (unspec:SI [(label_ref (match_operand 1))]
17677 UNSPEC_SET_GOT))
17678 (clobber (reg:CC FLAGS_REG))])]
17679 "!TARGET_64BIT"
17680 {
17681 if (flag_pic && !TARGET_VXWORKS_RTP)
17682 ix86_pc_thunk_call_expanded = true;
17683 })
17684
17685 (define_insn "*set_got_labelled"
17686 [(set (match_operand:SI 0 "register_operand" "=r")
17687 (unspec:SI [(label_ref (match_operand 1))]
17688 UNSPEC_SET_GOT))
17689 (clobber (reg:CC FLAGS_REG))]
17690 "!TARGET_64BIT"
17691 "* return output_set_got (operands[0], operands[1]);"
17692 [(set_attr "type" "multi")
17693 (set_attr "length" "12")])
17694
17695 (define_insn "set_got_rex64"
17696 [(set (match_operand:DI 0 "register_operand" "=r")
17697 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
17698 "TARGET_64BIT"
17699 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
17700 [(set_attr "type" "lea")
17701 (set_attr "length_address" "4")
17702 (set_attr "mode" "DI")])
17703
17704 (define_insn "set_rip_rex64"
17705 [(set (match_operand:DI 0 "register_operand" "=r")
17706 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
17707 "TARGET_64BIT"
17708 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
17709 [(set_attr "type" "lea")
17710 (set_attr "length_address" "4")
17711 (set_attr "mode" "DI")])
17712
17713 (define_insn "set_got_offset_rex64"
17714 [(set (match_operand:DI 0 "register_operand" "=r")
17715 (unspec:DI
17716 [(label_ref (match_operand 1))]
17717 UNSPEC_SET_GOT_OFFSET))]
17718 "TARGET_LP64"
17719 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
17720 [(set_attr "type" "imov")
17721 (set_attr "length_immediate" "0")
17722 (set_attr "length_address" "8")
17723 (set_attr "mode" "DI")])
17724
17725 (define_expand "epilogue"
17726 [(const_int 0)]
17727 ""
17728 "ix86_expand_epilogue (1); DONE;")
17729
17730 (define_expand "sibcall_epilogue"
17731 [(const_int 0)]
17732 ""
17733 "ix86_expand_epilogue (0); DONE;")
17734
17735 (define_expand "eh_return"
17736 [(use (match_operand 0 "register_operand"))]
17737 ""
17738 {
17739 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
17740
17741 /* Tricky bit: we write the address of the handler to which we will
17742 be returning into someone else's stack frame, one word below the
17743 stack address we wish to restore. */
17744 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
17745 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
17746 /* Return address is always in word_mode. */
17747 tmp = gen_rtx_MEM (word_mode, tmp);
17748 if (GET_MODE (ra) != word_mode)
17749 ra = convert_to_mode (word_mode, ra, 1);
17750 emit_move_insn (tmp, ra);
17751
17752 emit_jump_insn (gen_eh_return_internal ());
17753 emit_barrier ();
17754 DONE;
17755 })
17756
17757 (define_insn_and_split "eh_return_internal"
17758 [(eh_return)]
17759 ""
17760 "#"
17761 "epilogue_completed"
17762 [(const_int 0)]
17763 "ix86_expand_epilogue (2); DONE;")
17764
17765 (define_expand "@leave_<mode>"
17766 [(parallel
17767 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
17768 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
17769 (clobber (mem:BLK (scratch)))])]
17770 ""
17771 "operands[0] = GEN_INT (<MODE_SIZE>);")
17772
17773 (define_insn "*leave"
17774 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
17775 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
17776 (clobber (mem:BLK (scratch)))]
17777 "!TARGET_64BIT"
17778 "leave"
17779 [(set_attr "type" "leave")])
17780
17781 (define_insn "*leave_rex64"
17782 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
17783 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
17784 (clobber (mem:BLK (scratch)))]
17785 "TARGET_64BIT"
17786 "leave"
17787 [(set_attr "type" "leave")])
17788 \f
17789 ;; Handle -fsplit-stack.
17790
17791 (define_expand "split_stack_prologue"
17792 [(const_int 0)]
17793 ""
17794 {
17795 ix86_expand_split_stack_prologue ();
17796 DONE;
17797 })
17798
17799 ;; In order to support the call/return predictor, we use a return
17800 ;; instruction which the middle-end doesn't see.
17801 (define_insn "split_stack_return"
17802 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
17803 UNSPECV_SPLIT_STACK_RETURN)]
17804 ""
17805 {
17806 if (operands[0] == const0_rtx)
17807 return "ret";
17808 else
17809 return "ret\t%0";
17810 }
17811 [(set_attr "atom_unit" "jeu")
17812 (set_attr "modrm" "0")
17813 (set (attr "length")
17814 (if_then_else (match_operand:SI 0 "const0_operand")
17815 (const_int 1)
17816 (const_int 3)))
17817 (set (attr "length_immediate")
17818 (if_then_else (match_operand:SI 0 "const0_operand")
17819 (const_int 0)
17820 (const_int 2)))])
17821
17822 ;; If there are operand 0 bytes available on the stack, jump to
17823 ;; operand 1.
17824
17825 (define_expand "split_stack_space_check"
17826 [(set (pc) (if_then_else
17827 (ltu (minus (reg SP_REG)
17828 (match_operand 0 "register_operand"))
17829 (match_dup 2))
17830 (label_ref (match_operand 1))
17831 (pc)))]
17832 ""
17833 {
17834 rtx reg = gen_reg_rtx (Pmode);
17835
17836 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
17837
17838 operands[2] = ix86_split_stack_guard ();
17839 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
17840
17841 DONE;
17842 })
17843 \f
17844 ;; Bit manipulation instructions.
17845
17846 (define_expand "ffs<mode>2"
17847 [(set (match_dup 2) (const_int -1))
17848 (parallel [(set (match_dup 3) (match_dup 4))
17849 (set (match_operand:SWI48 0 "register_operand")
17850 (ctz:SWI48
17851 (match_operand:SWI48 1 "nonimmediate_operand")))])
17852 (set (match_dup 0) (if_then_else:SWI48
17853 (eq (match_dup 3) (const_int 0))
17854 (match_dup 2)
17855 (match_dup 0)))
17856 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
17857 (clobber (reg:CC FLAGS_REG))])]
17858 ""
17859 {
17860 machine_mode flags_mode;
17861
17862 if (<MODE>mode == SImode && !TARGET_CMOVE)
17863 {
17864 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
17865 DONE;
17866 }
17867
17868 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
17869
17870 operands[2] = gen_reg_rtx (<MODE>mode);
17871 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
17872 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
17873 })
17874
17875 (define_insn_and_split "ffssi2_no_cmove"
17876 [(set (match_operand:SI 0 "register_operand" "=r")
17877 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
17878 (clobber (match_scratch:SI 2 "=&q"))
17879 (clobber (reg:CC FLAGS_REG))]
17880 "!TARGET_CMOVE"
17881 "#"
17882 "&& reload_completed"
17883 [(parallel [(set (match_dup 4) (match_dup 5))
17884 (set (match_dup 0) (ctz:SI (match_dup 1)))])
17885 (set (strict_low_part (match_dup 3))
17886 (eq:QI (match_dup 4) (const_int 0)))
17887 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
17888 (clobber (reg:CC FLAGS_REG))])
17889 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
17890 (clobber (reg:CC FLAGS_REG))])
17891 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
17892 (clobber (reg:CC FLAGS_REG))])]
17893 {
17894 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
17895
17896 operands[3] = gen_lowpart (QImode, operands[2]);
17897 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
17898 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
17899
17900 ix86_expand_clear (operands[2]);
17901 })
17902
17903 (define_insn_and_split "*tzcnt<mode>_1"
17904 [(set (reg:CCC FLAGS_REG)
17905 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17906 (const_int 0)))
17907 (set (match_operand:SWI48 0 "register_operand" "=r")
17908 (ctz:SWI48 (match_dup 1)))]
17909 "TARGET_BMI"
17910 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17911 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17912 && optimize_function_for_speed_p (cfun)
17913 && !reg_mentioned_p (operands[0], operands[1])"
17914 [(parallel
17915 [(set (reg:CCC FLAGS_REG)
17916 (compare:CCC (match_dup 1) (const_int 0)))
17917 (set (match_dup 0)
17918 (ctz:SWI48 (match_dup 1)))
17919 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
17920 "ix86_expand_clear (operands[0]);"
17921 [(set_attr "type" "alu1")
17922 (set_attr "prefix_0f" "1")
17923 (set_attr "prefix_rep" "1")
17924 (set_attr "btver2_decode" "double")
17925 (set_attr "mode" "<MODE>")])
17926
17927 ; False dependency happens when destination is only updated by tzcnt,
17928 ; lzcnt or popcnt. There is no false dependency when destination is
17929 ; also used in source.
17930 (define_insn "*tzcnt<mode>_1_falsedep"
17931 [(set (reg:CCC FLAGS_REG)
17932 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17933 (const_int 0)))
17934 (set (match_operand:SWI48 0 "register_operand" "=r")
17935 (ctz:SWI48 (match_dup 1)))
17936 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
17937 UNSPEC_INSN_FALSE_DEP)]
17938 "TARGET_BMI"
17939 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17940 [(set_attr "type" "alu1")
17941 (set_attr "prefix_0f" "1")
17942 (set_attr "prefix_rep" "1")
17943 (set_attr "btver2_decode" "double")
17944 (set_attr "mode" "<MODE>")])
17945
17946 (define_insn "*bsf<mode>_1"
17947 [(set (reg:CCZ FLAGS_REG)
17948 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17949 (const_int 0)))
17950 (set (match_operand:SWI48 0 "register_operand" "=r")
17951 (ctz:SWI48 (match_dup 1)))]
17952 ""
17953 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
17954 [(set_attr "type" "alu1")
17955 (set_attr "prefix_0f" "1")
17956 (set_attr "btver2_decode" "double")
17957 (set_attr "znver1_decode" "vector")
17958 (set_attr "mode" "<MODE>")])
17959
17960 (define_insn_and_split "ctz<mode>2"
17961 [(set (match_operand:SWI48 0 "register_operand" "=r")
17962 (ctz:SWI48
17963 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
17964 (clobber (reg:CC FLAGS_REG))]
17965 ""
17966 {
17967 if (TARGET_BMI)
17968 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17969 else if (optimize_function_for_size_p (cfun))
17970 ;
17971 else if (TARGET_CPU_P (GENERIC))
17972 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17973 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17974
17975 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17976 }
17977 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
17978 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17979 && optimize_function_for_speed_p (cfun)
17980 && !reg_mentioned_p (operands[0], operands[1])"
17981 [(parallel
17982 [(set (match_dup 0)
17983 (ctz:SWI48 (match_dup 1)))
17984 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17985 (clobber (reg:CC FLAGS_REG))])]
17986 "ix86_expand_clear (operands[0]);"
17987 [(set_attr "type" "alu1")
17988 (set_attr "prefix_0f" "1")
17989 (set (attr "prefix_rep")
17990 (if_then_else
17991 (ior (match_test "TARGET_BMI")
17992 (and (not (match_test "optimize_function_for_size_p (cfun)"))
17993 (match_test "TARGET_CPU_P (GENERIC)")))
17994 (const_string "1")
17995 (const_string "0")))
17996 (set_attr "mode" "<MODE>")])
17997
17998 ; False dependency happens when destination is only updated by tzcnt,
17999 ; lzcnt or popcnt. There is no false dependency when destination is
18000 ; also used in source.
18001 (define_insn "*ctz<mode>2_falsedep"
18002 [(set (match_operand:SWI48 0 "register_operand" "=r")
18003 (ctz:SWI48
18004 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18005 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18006 UNSPEC_INSN_FALSE_DEP)
18007 (clobber (reg:CC FLAGS_REG))]
18008 ""
18009 {
18010 if (TARGET_BMI)
18011 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18012 else if (TARGET_CPU_P (GENERIC))
18013 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18014 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
18015 else
18016 gcc_unreachable ();
18017 }
18018 [(set_attr "type" "alu1")
18019 (set_attr "prefix_0f" "1")
18020 (set_attr "prefix_rep" "1")
18021 (set_attr "mode" "<MODE>")])
18022
18023 (define_insn_and_split "*ctzsi2_zext"
18024 [(set (match_operand:DI 0 "register_operand" "=r")
18025 (and:DI
18026 (subreg:DI
18027 (ctz:SI
18028 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18029 (const_int 63)))
18030 (clobber (reg:CC FLAGS_REG))]
18031 "TARGET_BMI && TARGET_64BIT"
18032 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18033 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18034 && optimize_function_for_speed_p (cfun)
18035 && !reg_mentioned_p (operands[0], operands[1])"
18036 [(parallel
18037 [(set (match_dup 0)
18038 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
18039 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18040 (clobber (reg:CC FLAGS_REG))])]
18041 "ix86_expand_clear (operands[0]);"
18042 [(set_attr "type" "alu1")
18043 (set_attr "prefix_0f" "1")
18044 (set_attr "prefix_rep" "1")
18045 (set_attr "mode" "SI")])
18046
18047 ; False dependency happens when destination is only updated by tzcnt,
18048 ; lzcnt or popcnt. There is no false dependency when destination is
18049 ; also used in source.
18050 (define_insn "*ctzsi2_zext_falsedep"
18051 [(set (match_operand:DI 0 "register_operand" "=r")
18052 (and:DI
18053 (subreg:DI
18054 (ctz:SI
18055 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18056 (const_int 63)))
18057 (unspec [(match_operand:DI 2 "register_operand" "0")]
18058 UNSPEC_INSN_FALSE_DEP)
18059 (clobber (reg:CC FLAGS_REG))]
18060 "TARGET_BMI && TARGET_64BIT"
18061 "tzcnt{l}\t{%1, %k0|%k0, %1}"
18062 [(set_attr "type" "alu1")
18063 (set_attr "prefix_0f" "1")
18064 (set_attr "prefix_rep" "1")
18065 (set_attr "mode" "SI")])
18066
18067 (define_insn_and_split "*ctzsidi2_<s>ext"
18068 [(set (match_operand:DI 0 "register_operand" "=r")
18069 (any_extend:DI
18070 (ctz:SI
18071 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18072 (clobber (reg:CC FLAGS_REG))]
18073 "TARGET_64BIT"
18074 {
18075 if (TARGET_BMI)
18076 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18077 else if (TARGET_CPU_P (GENERIC)
18078 && !optimize_function_for_size_p (cfun))
18079 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18080 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18081 return "bsf{l}\t{%1, %k0|%k0, %1}";
18082 }
18083 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
18084 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18085 && optimize_function_for_speed_p (cfun)
18086 && !reg_mentioned_p (operands[0], operands[1])"
18087 [(parallel
18088 [(set (match_dup 0)
18089 (any_extend:DI (ctz:SI (match_dup 1))))
18090 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18091 (clobber (reg:CC FLAGS_REG))])]
18092 "ix86_expand_clear (operands[0]);"
18093 [(set_attr "type" "alu1")
18094 (set_attr "prefix_0f" "1")
18095 (set (attr "prefix_rep")
18096 (if_then_else
18097 (ior (match_test "TARGET_BMI")
18098 (and (not (match_test "optimize_function_for_size_p (cfun)"))
18099 (match_test "TARGET_CPU_P (GENERIC)")))
18100 (const_string "1")
18101 (const_string "0")))
18102 (set_attr "mode" "SI")])
18103
18104 (define_insn "*ctzsidi2_<s>ext_falsedep"
18105 [(set (match_operand:DI 0 "register_operand" "=r")
18106 (any_extend:DI
18107 (ctz:SI
18108 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18109 (unspec [(match_operand:DI 2 "register_operand" "0")]
18110 UNSPEC_INSN_FALSE_DEP)
18111 (clobber (reg:CC FLAGS_REG))]
18112 "TARGET_64BIT"
18113 {
18114 if (TARGET_BMI)
18115 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
18116 else if (TARGET_CPU_P (GENERIC))
18117 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
18118 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
18119 else
18120 gcc_unreachable ();
18121 }
18122 [(set_attr "type" "alu1")
18123 (set_attr "prefix_0f" "1")
18124 (set_attr "prefix_rep" "1")
18125 (set_attr "mode" "SI")])
18126
18127 (define_insn "bsr_rex64"
18128 [(set (reg:CCZ FLAGS_REG)
18129 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18130 (const_int 0)))
18131 (set (match_operand:DI 0 "register_operand" "=r")
18132 (minus:DI (const_int 63)
18133 (clz:DI (match_dup 1))))]
18134 "TARGET_64BIT"
18135 "bsr{q}\t{%1, %0|%0, %1}"
18136 [(set_attr "type" "alu1")
18137 (set_attr "prefix_0f" "1")
18138 (set_attr "znver1_decode" "vector")
18139 (set_attr "mode" "DI")])
18140
18141 (define_insn "bsr_rex64_1"
18142 [(set (match_operand:DI 0 "register_operand" "=r")
18143 (minus:DI (const_int 63)
18144 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18145 (clobber (reg:CC FLAGS_REG))]
18146 "!TARGET_LZCNT && TARGET_64BIT"
18147 "bsr{q}\t{%1, %0|%0, %1}"
18148 [(set_attr "type" "alu1")
18149 (set_attr "prefix_0f" "1")
18150 (set_attr "znver1_decode" "vector")
18151 (set_attr "mode" "DI")])
18152
18153 (define_insn "bsr_rex64_1_zext"
18154 [(set (match_operand:DI 0 "register_operand" "=r")
18155 (zero_extend:DI
18156 (minus:SI (const_int 63)
18157 (subreg:SI
18158 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18159 0))))
18160 (clobber (reg:CC FLAGS_REG))]
18161 "!TARGET_LZCNT && TARGET_64BIT"
18162 "bsr{q}\t{%1, %0|%0, %1}"
18163 [(set_attr "type" "alu1")
18164 (set_attr "prefix_0f" "1")
18165 (set_attr "znver1_decode" "vector")
18166 (set_attr "mode" "DI")])
18167
18168 (define_insn "bsr"
18169 [(set (reg:CCZ FLAGS_REG)
18170 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18171 (const_int 0)))
18172 (set (match_operand:SI 0 "register_operand" "=r")
18173 (minus:SI (const_int 31)
18174 (clz:SI (match_dup 1))))]
18175 ""
18176 "bsr{l}\t{%1, %0|%0, %1}"
18177 [(set_attr "type" "alu1")
18178 (set_attr "prefix_0f" "1")
18179 (set_attr "znver1_decode" "vector")
18180 (set_attr "mode" "SI")])
18181
18182 (define_insn "bsr_1"
18183 [(set (match_operand:SI 0 "register_operand" "=r")
18184 (minus:SI (const_int 31)
18185 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18186 (clobber (reg:CC FLAGS_REG))]
18187 "!TARGET_LZCNT"
18188 "bsr{l}\t{%1, %0|%0, %1}"
18189 [(set_attr "type" "alu1")
18190 (set_attr "prefix_0f" "1")
18191 (set_attr "znver1_decode" "vector")
18192 (set_attr "mode" "SI")])
18193
18194 (define_insn "bsr_zext_1"
18195 [(set (match_operand:DI 0 "register_operand" "=r")
18196 (zero_extend:DI
18197 (minus:SI
18198 (const_int 31)
18199 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18200 (clobber (reg:CC FLAGS_REG))]
18201 "!TARGET_LZCNT && TARGET_64BIT"
18202 "bsr{l}\t{%1, %k0|%k0, %1}"
18203 [(set_attr "type" "alu1")
18204 (set_attr "prefix_0f" "1")
18205 (set_attr "znver1_decode" "vector")
18206 (set_attr "mode" "SI")])
18207
18208 ; As bsr is undefined behavior on zero and for other input
18209 ; values it is in range 0 to 63, we can optimize away sign-extends.
18210 (define_insn_and_split "*bsr_rex64_2"
18211 [(set (match_operand:DI 0 "register_operand")
18212 (xor:DI
18213 (sign_extend:DI
18214 (minus:SI
18215 (const_int 63)
18216 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18217 0)))
18218 (const_int 63)))
18219 (clobber (reg:CC FLAGS_REG))]
18220 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18221 "#"
18222 "&& 1"
18223 [(parallel [(set (reg:CCZ FLAGS_REG)
18224 (compare:CCZ (match_dup 1) (const_int 0)))
18225 (set (match_dup 2)
18226 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18227 (parallel [(set (match_dup 0)
18228 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18229 (clobber (reg:CC FLAGS_REG))])]
18230 {
18231 operands[2] = gen_reg_rtx (DImode);
18232 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18233 })
18234
18235 (define_insn_and_split "*bsr_2"
18236 [(set (match_operand:DI 0 "register_operand")
18237 (sign_extend:DI
18238 (xor:SI
18239 (minus:SI
18240 (const_int 31)
18241 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18242 (const_int 31))))
18243 (clobber (reg:CC FLAGS_REG))]
18244 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18245 "#"
18246 "&& 1"
18247 [(parallel [(set (reg:CCZ FLAGS_REG)
18248 (compare:CCZ (match_dup 1) (const_int 0)))
18249 (set (match_dup 2)
18250 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18251 (parallel [(set (match_dup 0)
18252 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18253 (clobber (reg:CC FLAGS_REG))])]
18254 "operands[2] = gen_reg_rtx (SImode);")
18255
18256 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18257 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18258 ; in [0, 63] or [0, 31] range.
18259 (define_split
18260 [(set (match_operand:SI 0 "register_operand")
18261 (minus:SI
18262 (match_operand:SI 2 "const_int_operand")
18263 (xor:SI
18264 (minus:SI (const_int 63)
18265 (subreg:SI
18266 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18267 0))
18268 (const_int 63))))]
18269 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18270 [(set (match_dup 3)
18271 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18272 (set (match_dup 0)
18273 (plus:SI (match_dup 5) (match_dup 4)))]
18274 {
18275 operands[3] = gen_reg_rtx (DImode);
18276 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18277 if (INTVAL (operands[2]) == 63)
18278 {
18279 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18280 emit_move_insn (operands[0], operands[5]);
18281 DONE;
18282 }
18283 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18284 })
18285
18286 (define_split
18287 [(set (match_operand:SI 0 "register_operand")
18288 (minus:SI
18289 (match_operand:SI 2 "const_int_operand")
18290 (xor:SI
18291 (minus:SI (const_int 31)
18292 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18293 (const_int 31))))]
18294 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18295 [(set (match_dup 3)
18296 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18297 (set (match_dup 0)
18298 (plus:SI (match_dup 3) (match_dup 4)))]
18299 {
18300 if (INTVAL (operands[2]) == 31)
18301 {
18302 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18303 DONE;
18304 }
18305 operands[3] = gen_reg_rtx (SImode);
18306 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18307 })
18308
18309 (define_split
18310 [(set (match_operand:DI 0 "register_operand")
18311 (minus:DI
18312 (match_operand:DI 2 "const_int_operand")
18313 (xor:DI
18314 (sign_extend:DI
18315 (minus:SI (const_int 63)
18316 (subreg:SI
18317 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18318 0)))
18319 (const_int 63))))]
18320 "!TARGET_LZCNT
18321 && TARGET_64BIT
18322 && ix86_pre_reload_split ()
18323 && ((unsigned HOST_WIDE_INT)
18324 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18325 == UINTVAL (operands[2]) - 63)"
18326 [(set (match_dup 3)
18327 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18328 (set (match_dup 0)
18329 (plus:DI (match_dup 3) (match_dup 4)))]
18330 {
18331 if (INTVAL (operands[2]) == 63)
18332 {
18333 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18334 DONE;
18335 }
18336 operands[3] = gen_reg_rtx (DImode);
18337 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18338 })
18339
18340 (define_split
18341 [(set (match_operand:DI 0 "register_operand")
18342 (minus:DI
18343 (match_operand:DI 2 "const_int_operand")
18344 (sign_extend:DI
18345 (xor:SI
18346 (minus:SI (const_int 31)
18347 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18348 (const_int 31)))))]
18349 "!TARGET_LZCNT
18350 && TARGET_64BIT
18351 && ix86_pre_reload_split ()
18352 && ((unsigned HOST_WIDE_INT)
18353 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18354 == UINTVAL (operands[2]) - 31)"
18355 [(set (match_dup 3)
18356 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18357 (set (match_dup 0)
18358 (plus:DI (match_dup 3) (match_dup 4)))]
18359 {
18360 if (INTVAL (operands[2]) == 31)
18361 {
18362 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18363 DONE;
18364 }
18365 operands[3] = gen_reg_rtx (DImode);
18366 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18367 })
18368
18369 (define_expand "clz<mode>2"
18370 [(parallel
18371 [(set (reg:CCZ FLAGS_REG)
18372 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18373 (const_int 0)))
18374 (set (match_dup 3) (minus:SWI48
18375 (match_dup 2)
18376 (clz:SWI48 (match_dup 1))))])
18377 (parallel
18378 [(set (match_operand:SWI48 0 "register_operand")
18379 (xor:SWI48 (match_dup 3) (match_dup 2)))
18380 (clobber (reg:CC FLAGS_REG))])]
18381 ""
18382 {
18383 if (TARGET_LZCNT)
18384 {
18385 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18386 DONE;
18387 }
18388 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18389 operands[3] = gen_reg_rtx (<MODE>mode);
18390 })
18391
18392 (define_insn_and_split "clz<mode>2_lzcnt"
18393 [(set (match_operand:SWI48 0 "register_operand" "=r")
18394 (clz:SWI48
18395 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18396 (clobber (reg:CC FLAGS_REG))]
18397 "TARGET_LZCNT"
18398 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18399 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18400 && optimize_function_for_speed_p (cfun)
18401 && !reg_mentioned_p (operands[0], operands[1])"
18402 [(parallel
18403 [(set (match_dup 0)
18404 (clz:SWI48 (match_dup 1)))
18405 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18406 (clobber (reg:CC FLAGS_REG))])]
18407 "ix86_expand_clear (operands[0]);"
18408 [(set_attr "prefix_rep" "1")
18409 (set_attr "type" "bitmanip")
18410 (set_attr "mode" "<MODE>")])
18411
18412 ; False dependency happens when destination is only updated by tzcnt,
18413 ; lzcnt or popcnt. There is no false dependency when destination is
18414 ; also used in source.
18415 (define_insn "*clz<mode>2_lzcnt_falsedep"
18416 [(set (match_operand:SWI48 0 "register_operand" "=r")
18417 (clz:SWI48
18418 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18419 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18420 UNSPEC_INSN_FALSE_DEP)
18421 (clobber (reg:CC FLAGS_REG))]
18422 "TARGET_LZCNT"
18423 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18424 [(set_attr "prefix_rep" "1")
18425 (set_attr "type" "bitmanip")
18426 (set_attr "mode" "<MODE>")])
18427
18428 (define_insn_and_split "*clzsi2_lzcnt_zext"
18429 [(set (match_operand:DI 0 "register_operand" "=r")
18430 (and:DI
18431 (subreg:DI
18432 (clz:SI
18433 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18434 (const_int 63)))
18435 (clobber (reg:CC FLAGS_REG))]
18436 "TARGET_LZCNT && TARGET_64BIT"
18437 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18438 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18439 && optimize_function_for_speed_p (cfun)
18440 && !reg_mentioned_p (operands[0], operands[1])"
18441 [(parallel
18442 [(set (match_dup 0)
18443 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18444 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18445 (clobber (reg:CC FLAGS_REG))])]
18446 "ix86_expand_clear (operands[0]);"
18447 [(set_attr "prefix_rep" "1")
18448 (set_attr "type" "bitmanip")
18449 (set_attr "mode" "SI")])
18450
18451 ; False dependency happens when destination is only updated by tzcnt,
18452 ; lzcnt or popcnt. There is no false dependency when destination is
18453 ; also used in source.
18454 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18455 [(set (match_operand:DI 0 "register_operand" "=r")
18456 (and:DI
18457 (subreg:DI
18458 (clz:SI
18459 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18460 (const_int 63)))
18461 (unspec [(match_operand:DI 2 "register_operand" "0")]
18462 UNSPEC_INSN_FALSE_DEP)
18463 (clobber (reg:CC FLAGS_REG))]
18464 "TARGET_LZCNT"
18465 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18466 [(set_attr "prefix_rep" "1")
18467 (set_attr "type" "bitmanip")
18468 (set_attr "mode" "SI")])
18469
18470 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18471 [(set (match_operand:DI 0 "register_operand" "=r")
18472 (zero_extend:DI
18473 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18474 (clobber (reg:CC FLAGS_REG))]
18475 "TARGET_LZCNT && TARGET_64BIT"
18476 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18477 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18478 && optimize_function_for_speed_p (cfun)
18479 && !reg_mentioned_p (operands[0], operands[1])"
18480 [(parallel
18481 [(set (match_dup 0)
18482 (zero_extend:DI (clz:SI (match_dup 1))))
18483 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18484 (clobber (reg:CC FLAGS_REG))])]
18485 "ix86_expand_clear (operands[0]);"
18486 [(set_attr "prefix_rep" "1")
18487 (set_attr "type" "bitmanip")
18488 (set_attr "mode" "SI")])
18489
18490 ; False dependency happens when destination is only updated by tzcnt,
18491 ; lzcnt or popcnt. There is no false dependency when destination is
18492 ; also used in source.
18493 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18494 [(set (match_operand:DI 0 "register_operand" "=r")
18495 (zero_extend:DI
18496 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18497 (unspec [(match_operand:DI 2 "register_operand" "0")]
18498 UNSPEC_INSN_FALSE_DEP)
18499 (clobber (reg:CC FLAGS_REG))]
18500 "TARGET_LZCNT"
18501 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18502 [(set_attr "prefix_rep" "1")
18503 (set_attr "type" "bitmanip")
18504 (set_attr "mode" "SI")])
18505
18506 (define_int_iterator LT_ZCNT
18507 [(UNSPEC_TZCNT "TARGET_BMI")
18508 (UNSPEC_LZCNT "TARGET_LZCNT")])
18509
18510 (define_int_attr lt_zcnt
18511 [(UNSPEC_TZCNT "tzcnt")
18512 (UNSPEC_LZCNT "lzcnt")])
18513
18514 (define_int_attr lt_zcnt_type
18515 [(UNSPEC_TZCNT "alu1")
18516 (UNSPEC_LZCNT "bitmanip")])
18517
18518 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
18519 ;; provides operand size as output when source operand is zero.
18520
18521 (define_insn_and_split "<lt_zcnt>_<mode>"
18522 [(set (match_operand:SWI48 0 "register_operand" "=r")
18523 (unspec:SWI48
18524 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18525 (clobber (reg:CC FLAGS_REG))]
18526 ""
18527 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18528 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18529 && optimize_function_for_speed_p (cfun)
18530 && !reg_mentioned_p (operands[0], operands[1])"
18531 [(parallel
18532 [(set (match_dup 0)
18533 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18534 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18535 (clobber (reg:CC FLAGS_REG))])]
18536 "ix86_expand_clear (operands[0]);"
18537 [(set_attr "type" "<lt_zcnt_type>")
18538 (set_attr "prefix_0f" "1")
18539 (set_attr "prefix_rep" "1")
18540 (set_attr "mode" "<MODE>")])
18541
18542 ; False dependency happens when destination is only updated by tzcnt,
18543 ; lzcnt or popcnt. There is no false dependency when destination is
18544 ; also used in source.
18545 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18546 [(set (match_operand:SWI48 0 "register_operand" "=r")
18547 (unspec:SWI48
18548 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18549 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18550 UNSPEC_INSN_FALSE_DEP)
18551 (clobber (reg:CC FLAGS_REG))]
18552 ""
18553 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18554 [(set_attr "type" "<lt_zcnt_type>")
18555 (set_attr "prefix_0f" "1")
18556 (set_attr "prefix_rep" "1")
18557 (set_attr "mode" "<MODE>")])
18558
18559 (define_insn "<lt_zcnt>_hi"
18560 [(set (match_operand:HI 0 "register_operand" "=r")
18561 (unspec:HI
18562 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18563 (clobber (reg:CC FLAGS_REG))]
18564 ""
18565 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18566 [(set_attr "type" "<lt_zcnt_type>")
18567 (set_attr "prefix_0f" "1")
18568 (set_attr "prefix_rep" "1")
18569 (set_attr "mode" "HI")])
18570
18571 ;; BMI instructions.
18572
18573 (define_insn "bmi_bextr_<mode>"
18574 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18575 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18576 (match_operand:SWI48 2 "register_operand" "r,r")]
18577 UNSPEC_BEXTR))
18578 (clobber (reg:CC FLAGS_REG))]
18579 "TARGET_BMI"
18580 "bextr\t{%2, %1, %0|%0, %1, %2}"
18581 [(set_attr "type" "bitmanip")
18582 (set_attr "btver2_decode" "direct, double")
18583 (set_attr "mode" "<MODE>")])
18584
18585 (define_insn "*bmi_bextr_<mode>_ccz"
18586 [(set (reg:CCZ FLAGS_REG)
18587 (compare:CCZ
18588 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18589 (match_operand:SWI48 2 "register_operand" "r,r")]
18590 UNSPEC_BEXTR)
18591 (const_int 0)))
18592 (clobber (match_scratch:SWI48 0 "=r,r"))]
18593 "TARGET_BMI"
18594 "bextr\t{%2, %1, %0|%0, %1, %2}"
18595 [(set_attr "type" "bitmanip")
18596 (set_attr "btver2_decode" "direct, double")
18597 (set_attr "mode" "<MODE>")])
18598
18599 (define_insn "*bmi_blsi_<mode>"
18600 [(set (match_operand:SWI48 0 "register_operand" "=r")
18601 (and:SWI48
18602 (neg:SWI48
18603 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18604 (match_dup 1)))
18605 (clobber (reg:CC FLAGS_REG))]
18606 "TARGET_BMI"
18607 "blsi\t{%1, %0|%0, %1}"
18608 [(set_attr "type" "bitmanip")
18609 (set_attr "btver2_decode" "double")
18610 (set_attr "mode" "<MODE>")])
18611
18612 (define_insn "*bmi_blsi_<mode>_cmp"
18613 [(set (reg FLAGS_REG)
18614 (compare
18615 (and:SWI48
18616 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18617 (match_dup 1))
18618 (const_int 0)))
18619 (set (match_operand:SWI48 0 "register_operand" "=r")
18620 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
18621 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18622 "blsi\t{%1, %0|%0, %1}"
18623 [(set_attr "type" "bitmanip")
18624 (set_attr "btver2_decode" "double")
18625 (set_attr "mode" "<MODE>")])
18626
18627 (define_insn "*bmi_blsi_<mode>_ccno"
18628 [(set (reg FLAGS_REG)
18629 (compare
18630 (and:SWI48
18631 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18632 (match_dup 1))
18633 (const_int 0)))
18634 (clobber (match_scratch:SWI48 0 "=r"))]
18635 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18636 "blsi\t{%1, %0|%0, %1}"
18637 [(set_attr "type" "bitmanip")
18638 (set_attr "btver2_decode" "double")
18639 (set_attr "mode" "<MODE>")])
18640
18641 (define_insn "*bmi_blsmsk_<mode>"
18642 [(set (match_operand:SWI48 0 "register_operand" "=r")
18643 (xor:SWI48
18644 (plus:SWI48
18645 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18646 (const_int -1))
18647 (match_dup 1)))
18648 (clobber (reg:CC FLAGS_REG))]
18649 "TARGET_BMI"
18650 "blsmsk\t{%1, %0|%0, %1}"
18651 [(set_attr "type" "bitmanip")
18652 (set_attr "btver2_decode" "double")
18653 (set_attr "mode" "<MODE>")])
18654
18655 (define_insn "*bmi_blsr_<mode>"
18656 [(set (match_operand:SWI48 0 "register_operand" "=r")
18657 (and:SWI48
18658 (plus:SWI48
18659 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18660 (const_int -1))
18661 (match_dup 1)))
18662 (clobber (reg:CC FLAGS_REG))]
18663 "TARGET_BMI"
18664 "blsr\t{%1, %0|%0, %1}"
18665 [(set_attr "type" "bitmanip")
18666 (set_attr "btver2_decode" "double")
18667 (set_attr "mode" "<MODE>")])
18668
18669 (define_insn "*bmi_blsr_<mode>_cmp"
18670 [(set (reg:CCZ FLAGS_REG)
18671 (compare:CCZ
18672 (and:SWI48
18673 (plus:SWI48
18674 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18675 (const_int -1))
18676 (match_dup 1))
18677 (const_int 0)))
18678 (set (match_operand:SWI48 0 "register_operand" "=r")
18679 (and:SWI48
18680 (plus:SWI48
18681 (match_dup 1)
18682 (const_int -1))
18683 (match_dup 1)))]
18684 "TARGET_BMI"
18685 "blsr\t{%1, %0|%0, %1}"
18686 [(set_attr "type" "bitmanip")
18687 (set_attr "btver2_decode" "double")
18688 (set_attr "mode" "<MODE>")])
18689
18690 (define_insn "*bmi_blsr_<mode>_ccz"
18691 [(set (reg:CCZ FLAGS_REG)
18692 (compare:CCZ
18693 (and:SWI48
18694 (plus:SWI48
18695 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18696 (const_int -1))
18697 (match_dup 1))
18698 (const_int 0)))
18699 (clobber (match_scratch:SWI48 0 "=r"))]
18700 "TARGET_BMI"
18701 "blsr\t{%1, %0|%0, %1}"
18702 [(set_attr "type" "bitmanip")
18703 (set_attr "btver2_decode" "double")
18704 (set_attr "mode" "<MODE>")])
18705
18706 ;; BMI2 instructions.
18707 (define_expand "bmi2_bzhi_<mode>3"
18708 [(parallel
18709 [(set (match_operand:SWI48 0 "register_operand")
18710 (if_then_else:SWI48
18711 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
18712 (const_int 255))
18713 (const_int 0))
18714 (zero_extract:SWI48
18715 (match_operand:SWI48 1 "nonimmediate_operand")
18716 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
18717 (match_dup 3))
18718 (const_int 0))
18719 (const_int 0)))
18720 (clobber (reg:CC FLAGS_REG))])]
18721 "TARGET_BMI2"
18722 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
18723
18724 (define_insn "*bmi2_bzhi_<mode>3"
18725 [(set (match_operand:SWI48 0 "register_operand" "=r")
18726 (if_then_else:SWI48
18727 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
18728 (const_int 255))
18729 (const_int 0))
18730 (zero_extract:SWI48
18731 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18732 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
18733 (match_operand:SWI48 3 "const_int_operand"))
18734 (const_int 0))
18735 (const_int 0)))
18736 (clobber (reg:CC FLAGS_REG))]
18737 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18738 "bzhi\t{%2, %1, %0|%0, %1, %2}"
18739 [(set_attr "type" "bitmanip")
18740 (set_attr "prefix" "vex")
18741 (set_attr "mode" "<MODE>")])
18742
18743 (define_insn "*bmi2_bzhi_<mode>3_1"
18744 [(set (match_operand:SWI48 0 "register_operand" "=r")
18745 (if_then_else:SWI48
18746 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18747 (zero_extract:SWI48
18748 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18749 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
18750 (match_operand:SWI48 3 "const_int_operand"))
18751 (const_int 0))
18752 (const_int 0)))
18753 (clobber (reg:CC FLAGS_REG))]
18754 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18755 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18756 [(set_attr "type" "bitmanip")
18757 (set_attr "prefix" "vex")
18758 (set_attr "mode" "<MODE>")])
18759
18760 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
18761 [(set (reg:CCZ FLAGS_REG)
18762 (compare:CCZ
18763 (if_then_else:SWI48
18764 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18765 (zero_extract:SWI48
18766 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18767 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
18768 (match_operand:SWI48 3 "const_int_operand"))
18769 (const_int 0))
18770 (const_int 0))
18771 (const_int 0)))
18772 (clobber (match_scratch:SWI48 0 "=r"))]
18773 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18774 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18775 [(set_attr "type" "bitmanip")
18776 (set_attr "prefix" "vex")
18777 (set_attr "mode" "<MODE>")])
18778
18779 (define_insn "*bmi2_bzhi_<mode>3_2"
18780 [(set (match_operand:SWI48 0 "register_operand" "=r")
18781 (and:SWI48
18782 (plus:SWI48
18783 (ashift:SWI48 (const_int 1)
18784 (match_operand:QI 2 "register_operand" "r"))
18785 (const_int -1))
18786 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18787 (clobber (reg:CC FLAGS_REG))]
18788 "TARGET_BMI2"
18789 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18790 [(set_attr "type" "bitmanip")
18791 (set_attr "prefix" "vex")
18792 (set_attr "mode" "<MODE>")])
18793
18794 (define_insn "*bmi2_bzhi_<mode>3_3"
18795 [(set (match_operand:SWI48 0 "register_operand" "=r")
18796 (and:SWI48
18797 (not:SWI48
18798 (ashift:SWI48 (const_int -1)
18799 (match_operand:QI 2 "register_operand" "r")))
18800 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18801 (clobber (reg:CC FLAGS_REG))]
18802 "TARGET_BMI2"
18803 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18804 [(set_attr "type" "bitmanip")
18805 (set_attr "prefix" "vex")
18806 (set_attr "mode" "<MODE>")])
18807
18808 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
18809 [(set (match_operand:DI 0 "register_operand" "=r")
18810 (zero_extend:DI
18811 (and:SI
18812 (plus:SI
18813 (ashift:SI (const_int 1)
18814 (match_operand:QI 2 "register_operand" "r"))
18815 (const_int -1))
18816 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18817 (clobber (reg:CC FLAGS_REG))]
18818 "TARGET_64BIT && TARGET_BMI2"
18819 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18820 [(set_attr "type" "bitmanip")
18821 (set_attr "prefix" "vex")
18822 (set_attr "mode" "DI")])
18823
18824 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
18825 [(set (match_operand:DI 0 "register_operand" "=r")
18826 (and:DI
18827 (zero_extend:DI
18828 (plus:SI
18829 (ashift:SI (const_int 1)
18830 (match_operand:QI 2 "register_operand" "r"))
18831 (const_int -1)))
18832 (match_operand:DI 1 "nonimmediate_operand" "rm")))
18833 (clobber (reg:CC FLAGS_REG))]
18834 "TARGET_64BIT && TARGET_BMI2"
18835 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18836 [(set_attr "type" "bitmanip")
18837 (set_attr "prefix" "vex")
18838 (set_attr "mode" "DI")])
18839
18840 (define_insn "bmi2_pdep_<mode>3"
18841 [(set (match_operand:SWI48 0 "register_operand" "=r")
18842 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18843 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18844 UNSPEC_PDEP))]
18845 "TARGET_BMI2"
18846 "pdep\t{%2, %1, %0|%0, %1, %2}"
18847 [(set_attr "type" "bitmanip")
18848 (set_attr "prefix" "vex")
18849 (set_attr "mode" "<MODE>")])
18850
18851 (define_insn "bmi2_pext_<mode>3"
18852 [(set (match_operand:SWI48 0 "register_operand" "=r")
18853 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18854 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18855 UNSPEC_PEXT))]
18856 "TARGET_BMI2"
18857 "pext\t{%2, %1, %0|%0, %1, %2}"
18858 [(set_attr "type" "bitmanip")
18859 (set_attr "prefix" "vex")
18860 (set_attr "mode" "<MODE>")])
18861
18862 ;; TBM instructions.
18863 (define_insn "@tbm_bextri_<mode>"
18864 [(set (match_operand:SWI48 0 "register_operand" "=r")
18865 (zero_extract:SWI48
18866 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18867 (match_operand 2 "const_0_to_255_operand")
18868 (match_operand 3 "const_0_to_255_operand")))
18869 (clobber (reg:CC FLAGS_REG))]
18870 "TARGET_TBM"
18871 {
18872 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
18873 return "bextr\t{%2, %1, %0|%0, %1, %2}";
18874 }
18875 [(set_attr "type" "bitmanip")
18876 (set_attr "mode" "<MODE>")])
18877
18878 (define_insn "*tbm_blcfill_<mode>"
18879 [(set (match_operand:SWI48 0 "register_operand" "=r")
18880 (and:SWI48
18881 (plus:SWI48
18882 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18883 (const_int 1))
18884 (match_dup 1)))
18885 (clobber (reg:CC FLAGS_REG))]
18886 "TARGET_TBM"
18887 "blcfill\t{%1, %0|%0, %1}"
18888 [(set_attr "type" "bitmanip")
18889 (set_attr "mode" "<MODE>")])
18890
18891 (define_insn "*tbm_blci_<mode>"
18892 [(set (match_operand:SWI48 0 "register_operand" "=r")
18893 (ior:SWI48
18894 (not:SWI48
18895 (plus:SWI48
18896 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18897 (const_int 1)))
18898 (match_dup 1)))
18899 (clobber (reg:CC FLAGS_REG))]
18900 "TARGET_TBM"
18901 "blci\t{%1, %0|%0, %1}"
18902 [(set_attr "type" "bitmanip")
18903 (set_attr "mode" "<MODE>")])
18904
18905 (define_insn "*tbm_blcic_<mode>"
18906 [(set (match_operand:SWI48 0 "register_operand" "=r")
18907 (and:SWI48
18908 (plus:SWI48
18909 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18910 (const_int 1))
18911 (not:SWI48
18912 (match_dup 1))))
18913 (clobber (reg:CC FLAGS_REG))]
18914 "TARGET_TBM"
18915 "blcic\t{%1, %0|%0, %1}"
18916 [(set_attr "type" "bitmanip")
18917 (set_attr "mode" "<MODE>")])
18918
18919 (define_insn "*tbm_blcmsk_<mode>"
18920 [(set (match_operand:SWI48 0 "register_operand" "=r")
18921 (xor:SWI48
18922 (plus:SWI48
18923 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18924 (const_int 1))
18925 (match_dup 1)))
18926 (clobber (reg:CC FLAGS_REG))]
18927 "TARGET_TBM"
18928 "blcmsk\t{%1, %0|%0, %1}"
18929 [(set_attr "type" "bitmanip")
18930 (set_attr "mode" "<MODE>")])
18931
18932 (define_insn "*tbm_blcs_<mode>"
18933 [(set (match_operand:SWI48 0 "register_operand" "=r")
18934 (ior:SWI48
18935 (plus:SWI48
18936 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18937 (const_int 1))
18938 (match_dup 1)))
18939 (clobber (reg:CC FLAGS_REG))]
18940 "TARGET_TBM"
18941 "blcs\t{%1, %0|%0, %1}"
18942 [(set_attr "type" "bitmanip")
18943 (set_attr "mode" "<MODE>")])
18944
18945 (define_insn "*tbm_blsfill_<mode>"
18946 [(set (match_operand:SWI48 0 "register_operand" "=r")
18947 (ior:SWI48
18948 (plus:SWI48
18949 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18950 (const_int -1))
18951 (match_dup 1)))
18952 (clobber (reg:CC FLAGS_REG))]
18953 "TARGET_TBM"
18954 "blsfill\t{%1, %0|%0, %1}"
18955 [(set_attr "type" "bitmanip")
18956 (set_attr "mode" "<MODE>")])
18957
18958 (define_insn "*tbm_blsic_<mode>"
18959 [(set (match_operand:SWI48 0 "register_operand" "=r")
18960 (ior:SWI48
18961 (plus:SWI48
18962 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18963 (const_int -1))
18964 (not:SWI48
18965 (match_dup 1))))
18966 (clobber (reg:CC FLAGS_REG))]
18967 "TARGET_TBM"
18968 "blsic\t{%1, %0|%0, %1}"
18969 [(set_attr "type" "bitmanip")
18970 (set_attr "mode" "<MODE>")])
18971
18972 (define_insn "*tbm_t1mskc_<mode>"
18973 [(set (match_operand:SWI48 0 "register_operand" "=r")
18974 (ior:SWI48
18975 (plus:SWI48
18976 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18977 (const_int 1))
18978 (not:SWI48
18979 (match_dup 1))))
18980 (clobber (reg:CC FLAGS_REG))]
18981 "TARGET_TBM"
18982 "t1mskc\t{%1, %0|%0, %1}"
18983 [(set_attr "type" "bitmanip")
18984 (set_attr "mode" "<MODE>")])
18985
18986 (define_insn "*tbm_tzmsk_<mode>"
18987 [(set (match_operand:SWI48 0 "register_operand" "=r")
18988 (and:SWI48
18989 (plus:SWI48
18990 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18991 (const_int -1))
18992 (not:SWI48
18993 (match_dup 1))))
18994 (clobber (reg:CC FLAGS_REG))]
18995 "TARGET_TBM"
18996 "tzmsk\t{%1, %0|%0, %1}"
18997 [(set_attr "type" "bitmanip")
18998 (set_attr "mode" "<MODE>")])
18999
19000 (define_insn_and_split "popcount<mode>2"
19001 [(set (match_operand:SWI48 0 "register_operand" "=r")
19002 (popcount:SWI48
19003 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19004 (clobber (reg:CC FLAGS_REG))]
19005 "TARGET_POPCNT"
19006 {
19007 #if TARGET_MACHO
19008 return "popcnt\t{%1, %0|%0, %1}";
19009 #else
19010 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19011 #endif
19012 }
19013 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19014 && optimize_function_for_speed_p (cfun)
19015 && !reg_mentioned_p (operands[0], operands[1])"
19016 [(parallel
19017 [(set (match_dup 0)
19018 (popcount:SWI48 (match_dup 1)))
19019 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19020 (clobber (reg:CC FLAGS_REG))])]
19021 "ix86_expand_clear (operands[0]);"
19022 [(set_attr "prefix_rep" "1")
19023 (set_attr "type" "bitmanip")
19024 (set_attr "mode" "<MODE>")])
19025
19026 ; False dependency happens when destination is only updated by tzcnt,
19027 ; lzcnt or popcnt. There is no false dependency when destination is
19028 ; also used in source.
19029 (define_insn "*popcount<mode>2_falsedep"
19030 [(set (match_operand:SWI48 0 "register_operand" "=r")
19031 (popcount:SWI48
19032 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
19033 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
19034 UNSPEC_INSN_FALSE_DEP)
19035 (clobber (reg:CC FLAGS_REG))]
19036 "TARGET_POPCNT"
19037 {
19038 #if TARGET_MACHO
19039 return "popcnt\t{%1, %0|%0, %1}";
19040 #else
19041 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
19042 #endif
19043 }
19044 [(set_attr "prefix_rep" "1")
19045 (set_attr "type" "bitmanip")
19046 (set_attr "mode" "<MODE>")])
19047
19048 (define_insn_and_split "*popcountsi2_zext"
19049 [(set (match_operand:DI 0 "register_operand" "=r")
19050 (and:DI
19051 (subreg:DI
19052 (popcount:SI
19053 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19054 (const_int 63)))
19055 (clobber (reg:CC FLAGS_REG))]
19056 "TARGET_POPCNT && TARGET_64BIT"
19057 {
19058 #if TARGET_MACHO
19059 return "popcnt\t{%1, %k0|%k0, %1}";
19060 #else
19061 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19062 #endif
19063 }
19064 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19065 && optimize_function_for_speed_p (cfun)
19066 && !reg_mentioned_p (operands[0], operands[1])"
19067 [(parallel
19068 [(set (match_dup 0)
19069 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
19070 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19071 (clobber (reg:CC FLAGS_REG))])]
19072 "ix86_expand_clear (operands[0]);"
19073 [(set_attr "prefix_rep" "1")
19074 (set_attr "type" "bitmanip")
19075 (set_attr "mode" "SI")])
19076
19077 ; False dependency happens when destination is only updated by tzcnt,
19078 ; lzcnt or popcnt. There is no false dependency when destination is
19079 ; also used in source.
19080 (define_insn "*popcountsi2_zext_falsedep"
19081 [(set (match_operand:DI 0 "register_operand" "=r")
19082 (and:DI
19083 (subreg:DI
19084 (popcount:SI
19085 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
19086 (const_int 63)))
19087 (unspec [(match_operand:DI 2 "register_operand" "0")]
19088 UNSPEC_INSN_FALSE_DEP)
19089 (clobber (reg:CC FLAGS_REG))]
19090 "TARGET_POPCNT && TARGET_64BIT"
19091 {
19092 #if TARGET_MACHO
19093 return "popcnt\t{%1, %k0|%k0, %1}";
19094 #else
19095 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19096 #endif
19097 }
19098 [(set_attr "prefix_rep" "1")
19099 (set_attr "type" "bitmanip")
19100 (set_attr "mode" "SI")])
19101
19102 (define_insn_and_split "*popcountsi2_zext_2"
19103 [(set (match_operand:DI 0 "register_operand" "=r")
19104 (zero_extend:DI
19105 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19106 (clobber (reg:CC FLAGS_REG))]
19107 "TARGET_POPCNT && TARGET_64BIT"
19108 {
19109 #if TARGET_MACHO
19110 return "popcnt\t{%1, %k0|%k0, %1}";
19111 #else
19112 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19113 #endif
19114 }
19115 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
19116 && optimize_function_for_speed_p (cfun)
19117 && !reg_mentioned_p (operands[0], operands[1])"
19118 [(parallel
19119 [(set (match_dup 0)
19120 (zero_extend:DI (popcount:SI (match_dup 1))))
19121 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
19122 (clobber (reg:CC FLAGS_REG))])]
19123 "ix86_expand_clear (operands[0]);"
19124 [(set_attr "prefix_rep" "1")
19125 (set_attr "type" "bitmanip")
19126 (set_attr "mode" "SI")])
19127
19128 ; False dependency happens when destination is only updated by tzcnt,
19129 ; lzcnt or popcnt. There is no false dependency when destination is
19130 ; also used in source.
19131 (define_insn "*popcountsi2_zext_2_falsedep"
19132 [(set (match_operand:DI 0 "register_operand" "=r")
19133 (zero_extend:DI
19134 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19135 (unspec [(match_operand:DI 2 "register_operand" "0")]
19136 UNSPEC_INSN_FALSE_DEP)
19137 (clobber (reg:CC FLAGS_REG))]
19138 "TARGET_POPCNT && TARGET_64BIT"
19139 {
19140 #if TARGET_MACHO
19141 return "popcnt\t{%1, %k0|%k0, %1}";
19142 #else
19143 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19144 #endif
19145 }
19146 [(set_attr "prefix_rep" "1")
19147 (set_attr "type" "bitmanip")
19148 (set_attr "mode" "SI")])
19149
19150 (define_insn_and_split "*popcounthi2_1"
19151 [(set (match_operand:SI 0 "register_operand")
19152 (popcount:SI
19153 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19154 (clobber (reg:CC FLAGS_REG))]
19155 "TARGET_POPCNT
19156 && ix86_pre_reload_split ()"
19157 "#"
19158 "&& 1"
19159 [(const_int 0)]
19160 {
19161 rtx tmp = gen_reg_rtx (HImode);
19162
19163 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19164 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19165 DONE;
19166 })
19167
19168 (define_insn_and_split "*popcounthi2_2"
19169 [(set (match_operand:SI 0 "register_operand")
19170 (zero_extend:SI
19171 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19172 (clobber (reg:CC FLAGS_REG))]
19173 "TARGET_POPCNT
19174 && ix86_pre_reload_split ()"
19175 "#"
19176 "&& 1"
19177 [(const_int 0)]
19178 {
19179 rtx tmp = gen_reg_rtx (HImode);
19180
19181 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19182 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19183 DONE;
19184 })
19185
19186 (define_insn "popcounthi2"
19187 [(set (match_operand:HI 0 "register_operand" "=r")
19188 (popcount:HI
19189 (match_operand:HI 1 "nonimmediate_operand" "rm")))
19190 (clobber (reg:CC FLAGS_REG))]
19191 "TARGET_POPCNT"
19192 {
19193 #if TARGET_MACHO
19194 return "popcnt\t{%1, %0|%0, %1}";
19195 #else
19196 return "popcnt{w}\t{%1, %0|%0, %1}";
19197 #endif
19198 }
19199 [(set_attr "prefix_rep" "1")
19200 (set_attr "type" "bitmanip")
19201 (set_attr "mode" "HI")])
19202
19203 (define_expand "bswapdi2"
19204 [(set (match_operand:DI 0 "register_operand")
19205 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19206 "TARGET_64BIT"
19207 {
19208 if (!TARGET_MOVBE)
19209 operands[1] = force_reg (DImode, operands[1]);
19210 })
19211
19212 (define_expand "bswapsi2"
19213 [(set (match_operand:SI 0 "register_operand")
19214 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19215 ""
19216 {
19217 if (TARGET_MOVBE)
19218 ;
19219 else if (TARGET_BSWAP)
19220 operands[1] = force_reg (SImode, operands[1]);
19221 else
19222 {
19223 rtx x = operands[0];
19224
19225 emit_move_insn (x, operands[1]);
19226 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19227 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19228 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19229 DONE;
19230 }
19231 })
19232
19233 (define_insn "*bswap<mode>2_movbe"
19234 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19235 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19236 "TARGET_MOVBE
19237 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19238 "@
19239 bswap\t%0
19240 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19241 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19242 [(set_attr "type" "bitmanip,imov,imov")
19243 (set_attr "modrm" "0,1,1")
19244 (set_attr "prefix_0f" "*,1,1")
19245 (set_attr "prefix_extra" "*,1,1")
19246 (set_attr "mode" "<MODE>")])
19247
19248 (define_insn "*bswap<mode>2"
19249 [(set (match_operand:SWI48 0 "register_operand" "=r")
19250 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19251 "TARGET_BSWAP"
19252 "bswap\t%0"
19253 [(set_attr "type" "bitmanip")
19254 (set_attr "modrm" "0")
19255 (set_attr "mode" "<MODE>")])
19256
19257 (define_expand "bswaphi2"
19258 [(set (match_operand:HI 0 "register_operand")
19259 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19260 "TARGET_MOVBE")
19261
19262 (define_insn "*bswaphi2_movbe"
19263 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19264 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19265 "TARGET_MOVBE
19266 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19267 "@
19268 xchg{b}\t{%h0, %b0|%b0, %h0}
19269 movbe{w}\t{%1, %0|%0, %1}
19270 movbe{w}\t{%1, %0|%0, %1}"
19271 [(set_attr "type" "imov")
19272 (set_attr "modrm" "*,1,1")
19273 (set_attr "prefix_0f" "*,1,1")
19274 (set_attr "prefix_extra" "*,1,1")
19275 (set_attr "pent_pair" "np,*,*")
19276 (set_attr "athlon_decode" "vector,*,*")
19277 (set_attr "amdfam10_decode" "double,*,*")
19278 (set_attr "bdver1_decode" "double,*,*")
19279 (set_attr "mode" "QI,HI,HI")])
19280
19281 (define_peephole2
19282 [(set (match_operand:HI 0 "general_reg_operand")
19283 (bswap:HI (match_dup 0)))]
19284 "TARGET_MOVBE
19285 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19286 && peep2_regno_dead_p (0, FLAGS_REG)"
19287 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19288 (clobber (reg:CC FLAGS_REG))])])
19289
19290 (define_insn "bswaphi_lowpart"
19291 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19292 (bswap:HI (match_dup 0)))
19293 (clobber (reg:CC FLAGS_REG))]
19294 ""
19295 "@
19296 xchg{b}\t{%h0, %b0|%b0, %h0}
19297 rol{w}\t{$8, %0|%0, 8}"
19298 [(set (attr "preferred_for_size")
19299 (cond [(eq_attr "alternative" "0")
19300 (symbol_ref "true")]
19301 (symbol_ref "false")))
19302 (set (attr "preferred_for_speed")
19303 (cond [(eq_attr "alternative" "0")
19304 (symbol_ref "TARGET_USE_XCHGB")]
19305 (symbol_ref "!TARGET_USE_XCHGB")))
19306 (set_attr "length" "2,4")
19307 (set_attr "mode" "QI,HI")])
19308
19309 (define_expand "paritydi2"
19310 [(set (match_operand:DI 0 "register_operand")
19311 (parity:DI (match_operand:DI 1 "register_operand")))]
19312 "! TARGET_POPCNT"
19313 {
19314 rtx scratch = gen_reg_rtx (QImode);
19315 rtx hipart1 = gen_reg_rtx (SImode);
19316 rtx lopart1 = gen_reg_rtx (SImode);
19317 rtx xor1 = gen_reg_rtx (SImode);
19318 rtx shift2 = gen_reg_rtx (SImode);
19319 rtx hipart2 = gen_reg_rtx (HImode);
19320 rtx lopart2 = gen_reg_rtx (HImode);
19321 rtx xor2 = gen_reg_rtx (HImode);
19322
19323 if (TARGET_64BIT)
19324 {
19325 rtx shift1 = gen_reg_rtx (DImode);
19326 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19327 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19328 }
19329 else
19330 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19331
19332 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19333 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19334
19335 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19336 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19337 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19338 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19339
19340 emit_insn (gen_parityhi2_cmp (xor2));
19341
19342 ix86_expand_setcc (scratch, ORDERED,
19343 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19344
19345 if (TARGET_64BIT)
19346 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19347 else
19348 {
19349 rtx tmp = gen_reg_rtx (SImode);
19350
19351 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19352 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19353 }
19354 DONE;
19355 })
19356
19357 (define_expand "paritysi2"
19358 [(set (match_operand:SI 0 "register_operand")
19359 (parity:SI (match_operand:SI 1 "register_operand")))]
19360 "! TARGET_POPCNT"
19361 {
19362 rtx scratch = gen_reg_rtx (QImode);
19363 rtx shift = gen_reg_rtx (SImode);
19364 rtx hipart = gen_reg_rtx (HImode);
19365 rtx lopart = gen_reg_rtx (HImode);
19366 rtx tmp = gen_reg_rtx (HImode);
19367
19368 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19369 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19370 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19371 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19372
19373 emit_insn (gen_parityhi2_cmp (tmp));
19374
19375 ix86_expand_setcc (scratch, ORDERED,
19376 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19377
19378 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19379 DONE;
19380 })
19381
19382 (define_expand "parityhi2"
19383 [(set (match_operand:HI 0 "register_operand")
19384 (parity:HI (match_operand:HI 1 "register_operand")))]
19385 "! TARGET_POPCNT"
19386 {
19387 rtx scratch = gen_reg_rtx (QImode);
19388
19389 emit_insn (gen_parityhi2_cmp (operands[1]));
19390
19391 ix86_expand_setcc (scratch, ORDERED,
19392 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19393
19394 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19395 DONE;
19396 })
19397
19398 (define_expand "parityqi2"
19399 [(set (match_operand:QI 0 "register_operand")
19400 (parity:QI (match_operand:QI 1 "register_operand")))]
19401 "! TARGET_POPCNT"
19402 {
19403 emit_insn (gen_parityqi2_cmp (operands[1]));
19404
19405 ix86_expand_setcc (operands[0], ORDERED,
19406 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19407 DONE;
19408 })
19409
19410 (define_insn "parityhi2_cmp"
19411 [(set (reg:CC FLAGS_REG)
19412 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19413 UNSPEC_PARITY))
19414 (clobber (match_dup 0))]
19415 ""
19416 "xor{b}\t{%h0, %b0|%b0, %h0}"
19417 [(set_attr "length" "2")
19418 (set_attr "mode" "QI")])
19419
19420 (define_insn "parityqi2_cmp"
19421 [(set (reg:CC FLAGS_REG)
19422 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19423 UNSPEC_PARITY))]
19424 ""
19425 "test{b}\t%0, %0"
19426 [(set_attr "mode" "QI")])
19427
19428 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19429 (define_peephole2
19430 [(set (match_operand:HI 0 "register_operand")
19431 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19432 (parallel [(set (reg:CC FLAGS_REG)
19433 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19434 (clobber (match_dup 0))])]
19435 ""
19436 [(set (reg:CC FLAGS_REG)
19437 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19438
19439 ;; Eliminate QImode popcount&1 using parity flag
19440 (define_peephole2
19441 [(set (match_operand:SI 0 "register_operand")
19442 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19443 (parallel [(set (match_operand:SI 2 "register_operand")
19444 (popcount:SI (match_dup 0)))
19445 (clobber (reg:CC FLAGS_REG))])
19446 (set (reg:CCZ FLAGS_REG)
19447 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19448 (const_int 1))
19449 (const_int 0)))
19450 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19451 [(reg:CCZ FLAGS_REG)
19452 (const_int 0)])
19453 (label_ref (match_operand 5))
19454 (pc)))]
19455 "REGNO (operands[2]) == REGNO (operands[3])
19456 && peep2_reg_dead_p (3, operands[0])
19457 && peep2_reg_dead_p (3, operands[2])
19458 && peep2_regno_dead_p (4, FLAGS_REG)"
19459 [(set (reg:CC FLAGS_REG)
19460 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19461 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19462 (const_int 0)])
19463 (label_ref (match_dup 5))
19464 (pc)))]
19465 {
19466 operands[4] = shallow_copy_rtx (operands[4]);
19467 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19468 })
19469
19470 ;; Eliminate HImode popcount&1 using parity flag
19471 (define_peephole2
19472 [(match_scratch:HI 0 "Q")
19473 (parallel [(set (match_operand:HI 1 "register_operand")
19474 (popcount:HI
19475 (match_operand:HI 2 "nonimmediate_operand")))
19476 (clobber (reg:CC FLAGS_REG))])
19477 (set (match_operand 3 "register_operand")
19478 (zero_extend (match_dup 1)))
19479 (set (reg:CCZ FLAGS_REG)
19480 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19481 (const_int 1))
19482 (const_int 0)))
19483 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19484 [(reg:CCZ FLAGS_REG)
19485 (const_int 0)])
19486 (label_ref (match_operand 6))
19487 (pc)))]
19488 "REGNO (operands[3]) == REGNO (operands[4])
19489 && peep2_reg_dead_p (3, operands[1])
19490 && peep2_reg_dead_p (3, operands[3])
19491 && peep2_regno_dead_p (4, FLAGS_REG)"
19492 [(set (match_dup 0) (match_dup 2))
19493 (parallel [(set (reg:CC FLAGS_REG)
19494 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19495 (clobber (match_dup 0))])
19496 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19497 (const_int 0)])
19498 (label_ref (match_dup 6))
19499 (pc)))]
19500 {
19501 operands[5] = shallow_copy_rtx (operands[5]);
19502 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19503 })
19504
19505 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19506 (define_peephole2
19507 [(match_scratch:HI 0 "Q")
19508 (parallel [(set (match_operand:HI 1 "register_operand")
19509 (popcount:HI
19510 (match_operand:HI 2 "nonimmediate_operand")))
19511 (clobber (reg:CC FLAGS_REG))])
19512 (set (reg:CCZ FLAGS_REG)
19513 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19514 (const_int 1))
19515 (const_int 0)))
19516 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19517 [(reg:CCZ FLAGS_REG)
19518 (const_int 0)])
19519 (label_ref (match_operand 5))
19520 (pc)))]
19521 "REGNO (operands[1]) == REGNO (operands[3])
19522 && peep2_reg_dead_p (2, operands[1])
19523 && peep2_reg_dead_p (2, operands[3])
19524 && peep2_regno_dead_p (3, FLAGS_REG)"
19525 [(set (match_dup 0) (match_dup 2))
19526 (parallel [(set (reg:CC FLAGS_REG)
19527 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19528 (clobber (match_dup 0))])
19529 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19530 (const_int 0)])
19531 (label_ref (match_dup 5))
19532 (pc)))]
19533 {
19534 operands[4] = shallow_copy_rtx (operands[4]);
19535 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19536 })
19537
19538 \f
19539 ;; Thread-local storage patterns for ELF.
19540 ;;
19541 ;; Note that these code sequences must appear exactly as shown
19542 ;; in order to allow linker relaxation.
19543
19544 (define_insn "*tls_global_dynamic_32_gnu"
19545 [(set (match_operand:SI 0 "register_operand" "=a")
19546 (unspec:SI
19547 [(match_operand:SI 1 "register_operand" "Yb")
19548 (match_operand 2 "tls_symbolic_operand")
19549 (match_operand 3 "constant_call_address_operand" "Bz")
19550 (reg:SI SP_REG)]
19551 UNSPEC_TLS_GD))
19552 (clobber (match_scratch:SI 4 "=d"))
19553 (clobber (match_scratch:SI 5 "=c"))
19554 (clobber (reg:CC FLAGS_REG))]
19555 "!TARGET_64BIT && TARGET_GNU_TLS"
19556 {
19557 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19558 output_asm_insn
19559 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19560 else
19561 output_asm_insn
19562 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19563 if (TARGET_SUN_TLS)
19564 #ifdef HAVE_AS_IX86_TLSGDPLT
19565 return "call\t%a2@tlsgdplt";
19566 #else
19567 return "call\t%p3@plt";
19568 #endif
19569 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19570 return "call\t%P3";
19571 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19572 }
19573 [(set_attr "type" "multi")
19574 (set_attr "length" "12")])
19575
19576 (define_expand "tls_global_dynamic_32"
19577 [(parallel
19578 [(set (match_operand:SI 0 "register_operand")
19579 (unspec:SI [(match_operand:SI 2 "register_operand")
19580 (match_operand 1 "tls_symbolic_operand")
19581 (match_operand 3 "constant_call_address_operand")
19582 (reg:SI SP_REG)]
19583 UNSPEC_TLS_GD))
19584 (clobber (scratch:SI))
19585 (clobber (scratch:SI))
19586 (clobber (reg:CC FLAGS_REG))])]
19587 ""
19588 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19589
19590 (define_insn "*tls_global_dynamic_64_<mode>"
19591 [(set (match_operand:P 0 "register_operand" "=a")
19592 (call:P
19593 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19594 (match_operand 3)))
19595 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19596 (reg:P SP_REG)]
19597 UNSPEC_TLS_GD)]
19598 "TARGET_64BIT"
19599 {
19600 if (!TARGET_X32)
19601 /* The .loc directive has effect for 'the immediately following assembly
19602 instruction'. So for a sequence:
19603 .loc f l
19604 .byte x
19605 insn1
19606 the 'immediately following assembly instruction' is insn1.
19607 We want to emit an insn prefix here, but if we use .byte (as shown in
19608 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19609 inside the insn sequence, rather than to the start. After relaxation
19610 of the sequence by the linker, the .loc might point inside an insn.
19611 Use data16 prefix instead, which doesn't have this problem. */
19612 fputs ("\tdata16", asm_out_file);
19613 output_asm_insn
19614 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19615 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19616 fputs (ASM_SHORT "0x6666\n", asm_out_file);
19617 else
19618 fputs (ASM_BYTE "0x66\n", asm_out_file);
19619 fputs ("\trex64\n", asm_out_file);
19620 if (TARGET_SUN_TLS)
19621 return "call\t%p2@plt";
19622 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19623 return "call\t%P2";
19624 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
19625 }
19626 [(set_attr "type" "multi")
19627 (set (attr "length")
19628 (symbol_ref "TARGET_X32 ? 15 : 16"))])
19629
19630 (define_insn "*tls_global_dynamic_64_largepic"
19631 [(set (match_operand:DI 0 "register_operand" "=a")
19632 (call:DI
19633 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
19634 (match_operand:DI 3 "immediate_operand" "i")))
19635 (match_operand 4)))
19636 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
19637 (reg:DI SP_REG)]
19638 UNSPEC_TLS_GD)]
19639 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19640 && GET_CODE (operands[3]) == CONST
19641 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
19642 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
19643 {
19644 output_asm_insn
19645 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19646 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
19647 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
19648 return "call\t{*%%rax|rax}";
19649 }
19650 [(set_attr "type" "multi")
19651 (set_attr "length" "22")])
19652
19653 (define_expand "@tls_global_dynamic_64_<mode>"
19654 [(parallel
19655 [(set (match_operand:P 0 "register_operand")
19656 (call:P
19657 (mem:QI (match_operand 2))
19658 (const_int 0)))
19659 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19660 (reg:P SP_REG)]
19661 UNSPEC_TLS_GD)])]
19662 "TARGET_64BIT"
19663 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19664
19665 (define_insn "*tls_local_dynamic_base_32_gnu"
19666 [(set (match_operand:SI 0 "register_operand" "=a")
19667 (unspec:SI
19668 [(match_operand:SI 1 "register_operand" "Yb")
19669 (match_operand 2 "constant_call_address_operand" "Bz")
19670 (reg:SI SP_REG)]
19671 UNSPEC_TLS_LD_BASE))
19672 (clobber (match_scratch:SI 3 "=d"))
19673 (clobber (match_scratch:SI 4 "=c"))
19674 (clobber (reg:CC FLAGS_REG))]
19675 "!TARGET_64BIT && TARGET_GNU_TLS"
19676 {
19677 output_asm_insn
19678 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
19679 if (TARGET_SUN_TLS)
19680 {
19681 if (HAVE_AS_IX86_TLSLDMPLT)
19682 return "call\t%&@tlsldmplt";
19683 else
19684 return "call\t%p2@plt";
19685 }
19686 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19687 return "call\t%P2";
19688 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
19689 }
19690 [(set_attr "type" "multi")
19691 (set_attr "length" "11")])
19692
19693 (define_expand "tls_local_dynamic_base_32"
19694 [(parallel
19695 [(set (match_operand:SI 0 "register_operand")
19696 (unspec:SI
19697 [(match_operand:SI 1 "register_operand")
19698 (match_operand 2 "constant_call_address_operand")
19699 (reg:SI SP_REG)]
19700 UNSPEC_TLS_LD_BASE))
19701 (clobber (scratch:SI))
19702 (clobber (scratch:SI))
19703 (clobber (reg:CC FLAGS_REG))])]
19704 ""
19705 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19706
19707 (define_insn "*tls_local_dynamic_base_64_<mode>"
19708 [(set (match_operand:P 0 "register_operand" "=a")
19709 (call:P
19710 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
19711 (match_operand 2)))
19712 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
19713 "TARGET_64BIT"
19714 {
19715 output_asm_insn
19716 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19717 if (TARGET_SUN_TLS)
19718 return "call\t%p1@plt";
19719 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19720 return "call\t%P1";
19721 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
19722 }
19723 [(set_attr "type" "multi")
19724 (set_attr "length" "12")])
19725
19726 (define_insn "*tls_local_dynamic_base_64_largepic"
19727 [(set (match_operand:DI 0 "register_operand" "=a")
19728 (call:DI
19729 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
19730 (match_operand:DI 2 "immediate_operand" "i")))
19731 (match_operand 3)))
19732 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
19733 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19734 && GET_CODE (operands[2]) == CONST
19735 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
19736 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
19737 {
19738 output_asm_insn
19739 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19740 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
19741 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
19742 return "call\t{*%%rax|rax}";
19743 }
19744 [(set_attr "type" "multi")
19745 (set_attr "length" "22")])
19746
19747 (define_expand "@tls_local_dynamic_base_64_<mode>"
19748 [(parallel
19749 [(set (match_operand:P 0 "register_operand")
19750 (call:P
19751 (mem:QI (match_operand 1))
19752 (const_int 0)))
19753 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
19754 "TARGET_64BIT"
19755 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19756
19757 ;; Local dynamic of a single variable is a lose. Show combine how
19758 ;; to convert that back to global dynamic.
19759
19760 (define_insn_and_split "*tls_local_dynamic_32_once"
19761 [(set (match_operand:SI 0 "register_operand" "=a")
19762 (plus:SI
19763 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
19764 (match_operand 2 "constant_call_address_operand" "Bz")
19765 (reg:SI SP_REG)]
19766 UNSPEC_TLS_LD_BASE)
19767 (const:SI (unspec:SI
19768 [(match_operand 3 "tls_symbolic_operand")]
19769 UNSPEC_DTPOFF))))
19770 (clobber (match_scratch:SI 4 "=d"))
19771 (clobber (match_scratch:SI 5 "=c"))
19772 (clobber (reg:CC FLAGS_REG))]
19773 ""
19774 "#"
19775 ""
19776 [(parallel
19777 [(set (match_dup 0)
19778 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
19779 (reg:SI SP_REG)]
19780 UNSPEC_TLS_GD))
19781 (clobber (match_dup 4))
19782 (clobber (match_dup 5))
19783 (clobber (reg:CC FLAGS_REG))])])
19784
19785 ;; Load and add the thread base pointer from %<tp_seg>:0.
19786 (define_expand "get_thread_pointer<mode>"
19787 [(set (match_operand:PTR 0 "register_operand")
19788 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19789 ""
19790 {
19791 /* targetm is not visible in the scope of the condition. */
19792 if (!targetm.have_tls)
19793 error ("%<__builtin_thread_pointer%> is not supported on this target");
19794 })
19795
19796 (define_insn_and_split "*load_tp_<mode>"
19797 [(set (match_operand:PTR 0 "register_operand" "=r")
19798 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19799 ""
19800 "#"
19801 ""
19802 [(set (match_dup 0)
19803 (match_dup 1))]
19804 {
19805 addr_space_t as = DEFAULT_TLS_SEG_REG;
19806
19807 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
19808 set_mem_addr_space (operands[1], as);
19809 })
19810
19811 (define_insn_and_split "*load_tp_x32_zext"
19812 [(set (match_operand:DI 0 "register_operand" "=r")
19813 (zero_extend:DI
19814 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
19815 "TARGET_X32"
19816 "#"
19817 "&& 1"
19818 [(set (match_dup 0)
19819 (zero_extend:DI (match_dup 1)))]
19820 {
19821 addr_space_t as = DEFAULT_TLS_SEG_REG;
19822
19823 operands[1] = gen_const_mem (SImode, const0_rtx);
19824 set_mem_addr_space (operands[1], as);
19825 })
19826
19827 (define_insn_and_split "*add_tp_<mode>"
19828 [(set (match_operand:PTR 0 "register_operand" "=r")
19829 (plus:PTR
19830 (unspec:PTR [(const_int 0)] UNSPEC_TP)
19831 (match_operand:PTR 1 "register_operand" "0")))
19832 (clobber (reg:CC FLAGS_REG))]
19833 ""
19834 "#"
19835 ""
19836 [(parallel
19837 [(set (match_dup 0)
19838 (plus:PTR (match_dup 1) (match_dup 2)))
19839 (clobber (reg:CC FLAGS_REG))])]
19840 {
19841 addr_space_t as = DEFAULT_TLS_SEG_REG;
19842
19843 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
19844 set_mem_addr_space (operands[2], as);
19845 })
19846
19847 (define_insn_and_split "*add_tp_x32_zext"
19848 [(set (match_operand:DI 0 "register_operand" "=r")
19849 (zero_extend:DI
19850 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
19851 (match_operand:SI 1 "register_operand" "0"))))
19852 (clobber (reg:CC FLAGS_REG))]
19853 "TARGET_X32"
19854 "#"
19855 "&& 1"
19856 [(parallel
19857 [(set (match_dup 0)
19858 (zero_extend:DI
19859 (plus:SI (match_dup 1) (match_dup 2))))
19860 (clobber (reg:CC FLAGS_REG))])]
19861 {
19862 addr_space_t as = DEFAULT_TLS_SEG_REG;
19863
19864 operands[2] = gen_const_mem (SImode, const0_rtx);
19865 set_mem_addr_space (operands[2], as);
19866 })
19867
19868 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
19869 ;; %rax as destination of the initial executable code sequence.
19870 (define_insn "tls_initial_exec_64_sun"
19871 [(set (match_operand:DI 0 "register_operand" "=a")
19872 (unspec:DI
19873 [(match_operand 1 "tls_symbolic_operand")]
19874 UNSPEC_TLS_IE_SUN))
19875 (clobber (reg:CC FLAGS_REG))]
19876 "TARGET_64BIT && TARGET_SUN_TLS"
19877 {
19878 output_asm_insn
19879 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
19880 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
19881 }
19882 [(set_attr "type" "multi")])
19883
19884 ;; GNU2 TLS patterns can be split.
19885
19886 (define_expand "tls_dynamic_gnu2_32"
19887 [(set (match_dup 3)
19888 (plus:SI (match_operand:SI 2 "register_operand")
19889 (const:SI
19890 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
19891 UNSPEC_TLSDESC))))
19892 (parallel
19893 [(set (match_operand:SI 0 "register_operand")
19894 (unspec:SI [(match_dup 1) (match_dup 3)
19895 (match_dup 2) (reg:SI SP_REG)]
19896 UNSPEC_TLSDESC))
19897 (clobber (reg:CC FLAGS_REG))])]
19898 "!TARGET_64BIT && TARGET_GNU2_TLS"
19899 {
19900 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
19901 ix86_tls_descriptor_calls_expanded_in_cfun = true;
19902 })
19903
19904 (define_insn "*tls_dynamic_gnu2_lea_32"
19905 [(set (match_operand:SI 0 "register_operand" "=r")
19906 (plus:SI (match_operand:SI 1 "register_operand" "b")
19907 (const:SI
19908 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
19909 UNSPEC_TLSDESC))))]
19910 "!TARGET_64BIT && TARGET_GNU2_TLS"
19911 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
19912 [(set_attr "type" "lea")
19913 (set_attr "mode" "SI")
19914 (set_attr "length" "6")
19915 (set_attr "length_address" "4")])
19916
19917 (define_insn "*tls_dynamic_gnu2_call_32"
19918 [(set (match_operand:SI 0 "register_operand" "=a")
19919 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
19920 (match_operand:SI 2 "register_operand" "0")
19921 ;; we have to make sure %ebx still points to the GOT
19922 (match_operand:SI 3 "register_operand" "b")
19923 (reg:SI SP_REG)]
19924 UNSPEC_TLSDESC))
19925 (clobber (reg:CC FLAGS_REG))]
19926 "!TARGET_64BIT && TARGET_GNU2_TLS"
19927 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
19928 [(set_attr "type" "call")
19929 (set_attr "length" "2")
19930 (set_attr "length_address" "0")])
19931
19932 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
19933 [(set (match_operand:SI 0 "register_operand" "=&a")
19934 (plus:SI
19935 (unspec:SI [(match_operand 3 "tls_modbase_operand")
19936 (match_operand:SI 4)
19937 (match_operand:SI 2 "register_operand" "b")
19938 (reg:SI SP_REG)]
19939 UNSPEC_TLSDESC)
19940 (const:SI (unspec:SI
19941 [(match_operand 1 "tls_symbolic_operand")]
19942 UNSPEC_DTPOFF))))
19943 (clobber (reg:CC FLAGS_REG))]
19944 "!TARGET_64BIT && TARGET_GNU2_TLS"
19945 "#"
19946 "&& 1"
19947 [(set (match_dup 0) (match_dup 5))]
19948 {
19949 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
19950 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
19951 })
19952
19953 (define_expand "@tls_dynamic_gnu2_64_<mode>"
19954 [(set (match_dup 2)
19955 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
19956 UNSPEC_TLSDESC))
19957 (parallel
19958 [(set (match_operand:PTR 0 "register_operand")
19959 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
19960 UNSPEC_TLSDESC))
19961 (clobber (reg:CC FLAGS_REG))])]
19962 "TARGET_64BIT && TARGET_GNU2_TLS"
19963 {
19964 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
19965 ix86_tls_descriptor_calls_expanded_in_cfun = true;
19966 })
19967
19968 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
19969 [(set (match_operand:PTR 0 "register_operand" "=r")
19970 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
19971 UNSPEC_TLSDESC))]
19972 "TARGET_64BIT && TARGET_GNU2_TLS"
19973 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
19974 [(set_attr "type" "lea")
19975 (set_attr "mode" "<MODE>")
19976 (set_attr "length" "7")
19977 (set_attr "length_address" "4")])
19978
19979 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
19980 [(set (match_operand:PTR 0 "register_operand" "=a")
19981 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
19982 (match_operand:PTR 2 "register_operand" "0")
19983 (reg:PTR SP_REG)]
19984 UNSPEC_TLSDESC))
19985 (clobber (reg:CC FLAGS_REG))]
19986 "TARGET_64BIT && TARGET_GNU2_TLS"
19987 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
19988 [(set_attr "type" "call")
19989 (set_attr "length" "2")
19990 (set_attr "length_address" "0")])
19991
19992 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
19993 [(set (match_operand:PTR 0 "register_operand" "=&a")
19994 (plus:PTR
19995 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
19996 (match_operand:PTR 3)
19997 (reg:PTR SP_REG)]
19998 UNSPEC_TLSDESC)
19999 (const:PTR (unspec:PTR
20000 [(match_operand 1 "tls_symbolic_operand")]
20001 UNSPEC_DTPOFF))))
20002 (clobber (reg:CC FLAGS_REG))]
20003 "TARGET_64BIT && TARGET_GNU2_TLS"
20004 "#"
20005 "&& 1"
20006 [(set (match_dup 0) (match_dup 4))]
20007 {
20008 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
20009 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
20010 })
20011
20012 (define_split
20013 [(match_operand 0 "tls_address_pattern")]
20014 "TARGET_TLS_DIRECT_SEG_REFS"
20015 [(match_dup 0)]
20016 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
20017
20018 \f
20019 ;; These patterns match the binary 387 instructions for addM3, subM3,
20020 ;; mulM3 and divM3. There are three patterns for each of DFmode and
20021 ;; SFmode. The first is the normal insn, the second the same insn but
20022 ;; with one operand a conversion, and the third the same insn but with
20023 ;; the other operand a conversion. The conversion may be SFmode or
20024 ;; SImode if the target mode DFmode, but only SImode if the target mode
20025 ;; is SFmode.
20026
20027 ;; Gcc is slightly more smart about handling normal two address instructions
20028 ;; so use special patterns for add and mull.
20029
20030 (define_insn "*fop_xf_comm_i387"
20031 [(set (match_operand:XF 0 "register_operand" "=f")
20032 (match_operator:XF 3 "binary_fp_operator"
20033 [(match_operand:XF 1 "register_operand" "%0")
20034 (match_operand:XF 2 "register_operand" "f")]))]
20035 "TARGET_80387
20036 && COMMUTATIVE_ARITH_P (operands[3])"
20037 "* return output_387_binary_op (insn, operands);"
20038 [(set (attr "type")
20039 (if_then_else (match_operand:XF 3 "mult_operator")
20040 (const_string "fmul")
20041 (const_string "fop")))
20042 (set_attr "mode" "XF")])
20043
20044 (define_insn "*fop_<mode>_comm"
20045 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
20046 (match_operator:MODEF 3 "binary_fp_operator"
20047 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
20048 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
20049 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20050 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20051 && COMMUTATIVE_ARITH_P (operands[3])
20052 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20053 "* return output_387_binary_op (insn, operands);"
20054 [(set (attr "type")
20055 (if_then_else (eq_attr "alternative" "1,2")
20056 (if_then_else (match_operand:MODEF 3 "mult_operator")
20057 (const_string "ssemul")
20058 (const_string "sseadd"))
20059 (if_then_else (match_operand:MODEF 3 "mult_operator")
20060 (const_string "fmul")
20061 (const_string "fop"))))
20062 (set_attr "isa" "*,noavx,avx")
20063 (set_attr "prefix" "orig,orig,vex")
20064 (set_attr "mode" "<MODE>")
20065 (set (attr "enabled")
20066 (if_then_else
20067 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20068 (if_then_else
20069 (eq_attr "alternative" "0")
20070 (symbol_ref "TARGET_MIX_SSE_I387
20071 && X87_ENABLE_ARITH (<MODE>mode)")
20072 (const_string "*"))
20073 (if_then_else
20074 (eq_attr "alternative" "0")
20075 (symbol_ref "true")
20076 (symbol_ref "false"))))])
20077
20078 (define_insn "*<insn>hf"
20079 [(set (match_operand:HF 0 "register_operand" "=v")
20080 (plusminusmultdiv:HF
20081 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
20082 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
20083 "TARGET_AVX512FP16
20084 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20085 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
20086 [(set_attr "prefix" "evex")
20087 (set_attr "mode" "HF")])
20088
20089 (define_insn "*rcpsf2_sse"
20090 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
20091 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
20092 UNSPEC_RCP))]
20093 "TARGET_SSE && TARGET_SSE_MATH"
20094 "@
20095 %vrcpss\t{%d1, %0|%0, %d1}
20096 %vrcpss\t{%d1, %0|%0, %d1}
20097 %vrcpss\t{%1, %d0|%d0, %1}"
20098 [(set_attr "type" "sse")
20099 (set_attr "atom_sse_attr" "rcp")
20100 (set_attr "btver2_sse_attr" "rcp")
20101 (set_attr "prefix" "maybe_vex")
20102 (set_attr "mode" "SF")
20103 (set_attr "avx_partial_xmm_update" "false,false,true")
20104 (set (attr "preferred_for_speed")
20105 (cond [(match_test "TARGET_AVX")
20106 (symbol_ref "true")
20107 (eq_attr "alternative" "1,2")
20108 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20109 ]
20110 (symbol_ref "true")))])
20111
20112 (define_insn "rcphf2"
20113 [(set (match_operand:HF 0 "register_operand" "=v,v")
20114 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20115 UNSPEC_RCP))]
20116 "TARGET_AVX512FP16"
20117 "@
20118 vrcpsh\t{%d1, %0|%0, %d1}
20119 vrcpsh\t{%1, %d0|%d0, %1}"
20120 [(set_attr "type" "sse")
20121 (set_attr "prefix" "evex")
20122 (set_attr "mode" "HF")
20123 (set_attr "avx_partial_xmm_update" "false,true")])
20124
20125 (define_insn "*fop_xf_1_i387"
20126 [(set (match_operand:XF 0 "register_operand" "=f,f")
20127 (match_operator:XF 3 "binary_fp_operator"
20128 [(match_operand:XF 1 "register_operand" "0,f")
20129 (match_operand:XF 2 "register_operand" "f,0")]))]
20130 "TARGET_80387
20131 && !COMMUTATIVE_ARITH_P (operands[3])"
20132 "* return output_387_binary_op (insn, operands);"
20133 [(set (attr "type")
20134 (if_then_else (match_operand:XF 3 "div_operator")
20135 (const_string "fdiv")
20136 (const_string "fop")))
20137 (set_attr "mode" "XF")])
20138
20139 (define_insn "*fop_<mode>_1"
20140 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20141 (match_operator:MODEF 3 "binary_fp_operator"
20142 [(match_operand:MODEF 1
20143 "x87nonimm_ssenomem_operand" "0,fm,0,v")
20144 (match_operand:MODEF 2
20145 "nonimmediate_operand" "fm,0,xm,vm")]))]
20146 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20147 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20148 && !COMMUTATIVE_ARITH_P (operands[3])
20149 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20150 "* return output_387_binary_op (insn, operands);"
20151 [(set (attr "type")
20152 (if_then_else (eq_attr "alternative" "2,3")
20153 (if_then_else (match_operand:MODEF 3 "div_operator")
20154 (const_string "ssediv")
20155 (const_string "sseadd"))
20156 (if_then_else (match_operand:MODEF 3 "div_operator")
20157 (const_string "fdiv")
20158 (const_string "fop"))))
20159 (set_attr "isa" "*,*,noavx,avx")
20160 (set_attr "prefix" "orig,orig,orig,vex")
20161 (set_attr "mode" "<MODE>")
20162 (set (attr "enabled")
20163 (if_then_else
20164 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20165 (if_then_else
20166 (eq_attr "alternative" "0,1")
20167 (symbol_ref "TARGET_MIX_SSE_I387
20168 && X87_ENABLE_ARITH (<MODE>mode)")
20169 (const_string "*"))
20170 (if_then_else
20171 (eq_attr "alternative" "0,1")
20172 (symbol_ref "true")
20173 (symbol_ref "false"))))])
20174
20175 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20176 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20177 (match_operator:X87MODEF 3 "binary_fp_operator"
20178 [(float:X87MODEF
20179 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20180 (match_operand:X87MODEF 2 "register_operand" "0")]))]
20181 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20182 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20183 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20184 || optimize_function_for_size_p (cfun))"
20185 "* return output_387_binary_op (insn, operands);"
20186 [(set (attr "type")
20187 (cond [(match_operand:X87MODEF 3 "mult_operator")
20188 (const_string "fmul")
20189 (match_operand:X87MODEF 3 "div_operator")
20190 (const_string "fdiv")
20191 ]
20192 (const_string "fop")))
20193 (set_attr "fp_int_src" "true")
20194 (set_attr "mode" "<SWI24:MODE>")])
20195
20196 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20197 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20198 (match_operator:X87MODEF 3 "binary_fp_operator"
20199 [(match_operand:X87MODEF 1 "register_operand" "0")
20200 (float:X87MODEF
20201 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20202 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20203 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20204 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20205 || optimize_function_for_size_p (cfun))"
20206 "* return output_387_binary_op (insn, operands);"
20207 [(set (attr "type")
20208 (cond [(match_operand:X87MODEF 3 "mult_operator")
20209 (const_string "fmul")
20210 (match_operand:X87MODEF 3 "div_operator")
20211 (const_string "fdiv")
20212 ]
20213 (const_string "fop")))
20214 (set_attr "fp_int_src" "true")
20215 (set_attr "mode" "<SWI24:MODE>")])
20216
20217 (define_insn "*fop_xf_4_i387"
20218 [(set (match_operand:XF 0 "register_operand" "=f,f")
20219 (match_operator:XF 3 "binary_fp_operator"
20220 [(float_extend:XF
20221 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20222 (match_operand:XF 2 "register_operand" "0,f")]))]
20223 "TARGET_80387"
20224 "* return output_387_binary_op (insn, operands);"
20225 [(set (attr "type")
20226 (cond [(match_operand:XF 3 "mult_operator")
20227 (const_string "fmul")
20228 (match_operand:XF 3 "div_operator")
20229 (const_string "fdiv")
20230 ]
20231 (const_string "fop")))
20232 (set_attr "mode" "<MODE>")])
20233
20234 (define_insn "*fop_df_4_i387"
20235 [(set (match_operand:DF 0 "register_operand" "=f,f")
20236 (match_operator:DF 3 "binary_fp_operator"
20237 [(float_extend:DF
20238 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20239 (match_operand:DF 2 "register_operand" "0,f")]))]
20240 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20241 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20242 "* return output_387_binary_op (insn, operands);"
20243 [(set (attr "type")
20244 (cond [(match_operand:DF 3 "mult_operator")
20245 (const_string "fmul")
20246 (match_operand:DF 3 "div_operator")
20247 (const_string "fdiv")
20248 ]
20249 (const_string "fop")))
20250 (set_attr "mode" "SF")])
20251
20252 (define_insn "*fop_xf_5_i387"
20253 [(set (match_operand:XF 0 "register_operand" "=f,f")
20254 (match_operator:XF 3 "binary_fp_operator"
20255 [(match_operand:XF 1 "register_operand" "0,f")
20256 (float_extend:XF
20257 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20258 "TARGET_80387"
20259 "* return output_387_binary_op (insn, operands);"
20260 [(set (attr "type")
20261 (cond [(match_operand:XF 3 "mult_operator")
20262 (const_string "fmul")
20263 (match_operand:XF 3 "div_operator")
20264 (const_string "fdiv")
20265 ]
20266 (const_string "fop")))
20267 (set_attr "mode" "<MODE>")])
20268
20269 (define_insn "*fop_df_5_i387"
20270 [(set (match_operand:DF 0 "register_operand" "=f,f")
20271 (match_operator:DF 3 "binary_fp_operator"
20272 [(match_operand:DF 1 "register_operand" "0,f")
20273 (float_extend:DF
20274 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20275 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20276 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20277 "* return output_387_binary_op (insn, operands);"
20278 [(set (attr "type")
20279 (cond [(match_operand:DF 3 "mult_operator")
20280 (const_string "fmul")
20281 (match_operand:DF 3 "div_operator")
20282 (const_string "fdiv")
20283 ]
20284 (const_string "fop")))
20285 (set_attr "mode" "SF")])
20286
20287 (define_insn "*fop_xf_6_i387"
20288 [(set (match_operand:XF 0 "register_operand" "=f,f")
20289 (match_operator:XF 3 "binary_fp_operator"
20290 [(float_extend:XF
20291 (match_operand:MODEF 1 "register_operand" "0,f"))
20292 (float_extend:XF
20293 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20294 "TARGET_80387"
20295 "* return output_387_binary_op (insn, operands);"
20296 [(set (attr "type")
20297 (cond [(match_operand:XF 3 "mult_operator")
20298 (const_string "fmul")
20299 (match_operand:XF 3 "div_operator")
20300 (const_string "fdiv")
20301 ]
20302 (const_string "fop")))
20303 (set_attr "mode" "<MODE>")])
20304
20305 (define_insn "*fop_df_6_i387"
20306 [(set (match_operand:DF 0 "register_operand" "=f,f")
20307 (match_operator:DF 3 "binary_fp_operator"
20308 [(float_extend:DF
20309 (match_operand:SF 1 "register_operand" "0,f"))
20310 (float_extend:DF
20311 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20312 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20313 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20314 "* return output_387_binary_op (insn, operands);"
20315 [(set (attr "type")
20316 (cond [(match_operand:DF 3 "mult_operator")
20317 (const_string "fmul")
20318 (match_operand:DF 3 "div_operator")
20319 (const_string "fdiv")
20320 ]
20321 (const_string "fop")))
20322 (set_attr "mode" "SF")])
20323 \f
20324 ;; FPU special functions.
20325
20326 ;; This pattern implements a no-op XFmode truncation for
20327 ;; all fancy i386 XFmode math functions.
20328
20329 (define_insn "truncxf<mode>2_i387_noop_unspec"
20330 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20331 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20332 UNSPEC_TRUNC_NOOP))]
20333 "TARGET_USE_FANCY_MATH_387"
20334 "* return output_387_reg_move (insn, operands);"
20335 [(set_attr "type" "fmov")
20336 (set_attr "mode" "<MODE>")])
20337
20338 (define_insn "sqrtxf2"
20339 [(set (match_operand:XF 0 "register_operand" "=f")
20340 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20341 "TARGET_USE_FANCY_MATH_387"
20342 "fsqrt"
20343 [(set_attr "type" "fpspc")
20344 (set_attr "mode" "XF")
20345 (set_attr "athlon_decode" "direct")
20346 (set_attr "amdfam10_decode" "direct")
20347 (set_attr "bdver1_decode" "direct")])
20348
20349 (define_insn "*rsqrtsf2_sse"
20350 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
20351 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
20352 UNSPEC_RSQRT))]
20353 "TARGET_SSE && TARGET_SSE_MATH"
20354 "@
20355 %vrsqrtss\t{%d1, %0|%0, %d1}
20356 %vrsqrtss\t{%d1, %0|%0, %d1}
20357 %vrsqrtss\t{%1, %d0|%d0, %1}"
20358 [(set_attr "type" "sse")
20359 (set_attr "atom_sse_attr" "rcp")
20360 (set_attr "btver2_sse_attr" "rcp")
20361 (set_attr "prefix" "maybe_vex")
20362 (set_attr "mode" "SF")
20363 (set_attr "avx_partial_xmm_update" "false,false,true")
20364 (set (attr "preferred_for_speed")
20365 (cond [(match_test "TARGET_AVX")
20366 (symbol_ref "true")
20367 (eq_attr "alternative" "1,2")
20368 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20369 ]
20370 (symbol_ref "true")))])
20371
20372 (define_expand "rsqrtsf2"
20373 [(set (match_operand:SF 0 "register_operand")
20374 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20375 UNSPEC_RSQRT))]
20376 "TARGET_SSE && TARGET_SSE_MATH"
20377 {
20378 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20379 DONE;
20380 })
20381
20382 (define_insn "rsqrthf2"
20383 [(set (match_operand:HF 0 "register_operand" "=v,v")
20384 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20385 UNSPEC_RSQRT))]
20386 "TARGET_AVX512FP16"
20387 "@
20388 vrsqrtsh\t{%d1, %0|%0, %d1}
20389 vrsqrtsh\t{%1, %d0|%d0, %1}"
20390 [(set_attr "type" "sse")
20391 (set_attr "prefix" "evex")
20392 (set_attr "avx_partial_xmm_update" "false,true")
20393 (set_attr "mode" "HF")])
20394
20395 (define_insn "sqrthf2"
20396 [(set (match_operand:HF 0 "register_operand" "=v,v")
20397 (sqrt:HF
20398 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20399 "TARGET_AVX512FP16"
20400 "@
20401 vsqrtsh\t{%d1, %0|%0, %d1}
20402 vsqrtsh\t{%1, %d0|%d0, %1}"
20403 [(set_attr "type" "sse")
20404 (set_attr "prefix" "evex")
20405 (set_attr "avx_partial_xmm_update" "false,true")
20406 (set_attr "mode" "HF")])
20407
20408 (define_insn "*sqrt<mode>2_sse"
20409 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20410 (sqrt:MODEF
20411 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20412 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20413 "@
20414 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20415 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20416 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20417 [(set_attr "type" "sse")
20418 (set_attr "atom_sse_attr" "sqrt")
20419 (set_attr "btver2_sse_attr" "sqrt")
20420 (set_attr "prefix" "maybe_vex")
20421 (set_attr "avx_partial_xmm_update" "false,false,true")
20422 (set_attr "mode" "<MODE>")
20423 (set (attr "preferred_for_speed")
20424 (cond [(match_test "TARGET_AVX")
20425 (symbol_ref "true")
20426 (eq_attr "alternative" "1,2")
20427 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20428 ]
20429 (symbol_ref "true")))])
20430
20431 (define_expand "sqrt<mode>2"
20432 [(set (match_operand:MODEF 0 "register_operand")
20433 (sqrt:MODEF
20434 (match_operand:MODEF 1 "nonimmediate_operand")))]
20435 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20436 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20437 {
20438 if (<MODE>mode == SFmode
20439 && TARGET_SSE && TARGET_SSE_MATH
20440 && TARGET_RECIP_SQRT
20441 && !optimize_function_for_size_p (cfun)
20442 && flag_finite_math_only && !flag_trapping_math
20443 && flag_unsafe_math_optimizations)
20444 {
20445 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20446 DONE;
20447 }
20448
20449 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20450 {
20451 rtx op0 = gen_reg_rtx (XFmode);
20452 rtx op1 = gen_reg_rtx (XFmode);
20453
20454 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20455 emit_insn (gen_sqrtxf2 (op0, op1));
20456 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20457 DONE;
20458 }
20459 })
20460
20461 (define_expand "hypot<mode>3"
20462 [(use (match_operand:MODEF 0 "register_operand"))
20463 (use (match_operand:MODEF 1 "general_operand"))
20464 (use (match_operand:MODEF 2 "general_operand"))]
20465 "TARGET_USE_FANCY_MATH_387
20466 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20467 || TARGET_MIX_SSE_I387)
20468 && flag_finite_math_only
20469 && flag_unsafe_math_optimizations"
20470 {
20471 rtx op0 = gen_reg_rtx (XFmode);
20472 rtx op1 = gen_reg_rtx (XFmode);
20473 rtx op2 = gen_reg_rtx (XFmode);
20474
20475 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20477
20478 emit_insn (gen_mulxf3 (op1, op1, op1));
20479 emit_insn (gen_mulxf3 (op2, op2, op2));
20480 emit_insn (gen_addxf3 (op0, op2, op1));
20481 emit_insn (gen_sqrtxf2 (op0, op0));
20482
20483 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20484 DONE;
20485 })
20486
20487 (define_insn "x86_fnstsw_1"
20488 [(set (match_operand:HI 0 "register_operand" "=a")
20489 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20490 "TARGET_80387"
20491 "fnstsw\t%0"
20492 [(set_attr "length" "2")
20493 (set_attr "mode" "SI")
20494 (set_attr "unit" "i387")])
20495
20496 (define_insn "fpremxf4_i387"
20497 [(set (match_operand:XF 0 "register_operand" "=f")
20498 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20499 (match_operand:XF 3 "register_operand" "1")]
20500 UNSPEC_FPREM_F))
20501 (set (match_operand:XF 1 "register_operand" "=f")
20502 (unspec:XF [(match_dup 2) (match_dup 3)]
20503 UNSPEC_FPREM_U))
20504 (set (reg:CCFP FPSR_REG)
20505 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20506 UNSPEC_C2_FLAG))]
20507 "TARGET_USE_FANCY_MATH_387"
20508 "fprem"
20509 [(set_attr "type" "fpspc")
20510 (set_attr "znver1_decode" "vector")
20511 (set_attr "mode" "XF")])
20512
20513 (define_expand "fmodxf3"
20514 [(use (match_operand:XF 0 "register_operand"))
20515 (use (match_operand:XF 1 "general_operand"))
20516 (use (match_operand:XF 2 "general_operand"))]
20517 "TARGET_USE_FANCY_MATH_387"
20518 {
20519 rtx_code_label *label = gen_label_rtx ();
20520
20521 rtx op1 = gen_reg_rtx (XFmode);
20522 rtx op2 = gen_reg_rtx (XFmode);
20523
20524 emit_move_insn (op2, operands[2]);
20525 emit_move_insn (op1, operands[1]);
20526
20527 emit_label (label);
20528 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20529 ix86_emit_fp_unordered_jump (label);
20530 LABEL_NUSES (label) = 1;
20531
20532 emit_move_insn (operands[0], op1);
20533 DONE;
20534 })
20535
20536 (define_expand "fmod<mode>3"
20537 [(use (match_operand:MODEF 0 "register_operand"))
20538 (use (match_operand:MODEF 1 "general_operand"))
20539 (use (match_operand:MODEF 2 "general_operand"))]
20540 "TARGET_USE_FANCY_MATH_387"
20541 {
20542 rtx (*gen_truncxf) (rtx, rtx);
20543
20544 rtx_code_label *label = gen_label_rtx ();
20545
20546 rtx op1 = gen_reg_rtx (XFmode);
20547 rtx op2 = gen_reg_rtx (XFmode);
20548
20549 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20550 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20551
20552 emit_label (label);
20553 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20554 ix86_emit_fp_unordered_jump (label);
20555 LABEL_NUSES (label) = 1;
20556
20557 /* Truncate the result properly for strict SSE math. */
20558 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20559 && !TARGET_MIX_SSE_I387)
20560 gen_truncxf = gen_truncxf<mode>2;
20561 else
20562 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20563
20564 emit_insn (gen_truncxf (operands[0], op1));
20565 DONE;
20566 })
20567
20568 (define_insn "fprem1xf4_i387"
20569 [(set (match_operand:XF 0 "register_operand" "=f")
20570 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20571 (match_operand:XF 3 "register_operand" "1")]
20572 UNSPEC_FPREM1_F))
20573 (set (match_operand:XF 1 "register_operand" "=f")
20574 (unspec:XF [(match_dup 2) (match_dup 3)]
20575 UNSPEC_FPREM1_U))
20576 (set (reg:CCFP FPSR_REG)
20577 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20578 UNSPEC_C2_FLAG))]
20579 "TARGET_USE_FANCY_MATH_387"
20580 "fprem1"
20581 [(set_attr "type" "fpspc")
20582 (set_attr "znver1_decode" "vector")
20583 (set_attr "mode" "XF")])
20584
20585 (define_expand "remainderxf3"
20586 [(use (match_operand:XF 0 "register_operand"))
20587 (use (match_operand:XF 1 "general_operand"))
20588 (use (match_operand:XF 2 "general_operand"))]
20589 "TARGET_USE_FANCY_MATH_387"
20590 {
20591 rtx_code_label *label = gen_label_rtx ();
20592
20593 rtx op1 = gen_reg_rtx (XFmode);
20594 rtx op2 = gen_reg_rtx (XFmode);
20595
20596 emit_move_insn (op2, operands[2]);
20597 emit_move_insn (op1, operands[1]);
20598
20599 emit_label (label);
20600 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20601 ix86_emit_fp_unordered_jump (label);
20602 LABEL_NUSES (label) = 1;
20603
20604 emit_move_insn (operands[0], op1);
20605 DONE;
20606 })
20607
20608 (define_expand "remainder<mode>3"
20609 [(use (match_operand:MODEF 0 "register_operand"))
20610 (use (match_operand:MODEF 1 "general_operand"))
20611 (use (match_operand:MODEF 2 "general_operand"))]
20612 "TARGET_USE_FANCY_MATH_387"
20613 {
20614 rtx (*gen_truncxf) (rtx, rtx);
20615
20616 rtx_code_label *label = gen_label_rtx ();
20617
20618 rtx op1 = gen_reg_rtx (XFmode);
20619 rtx op2 = gen_reg_rtx (XFmode);
20620
20621 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20622 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20623
20624 emit_label (label);
20625
20626 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20627 ix86_emit_fp_unordered_jump (label);
20628 LABEL_NUSES (label) = 1;
20629
20630 /* Truncate the result properly for strict SSE math. */
20631 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20632 && !TARGET_MIX_SSE_I387)
20633 gen_truncxf = gen_truncxf<mode>2;
20634 else
20635 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20636
20637 emit_insn (gen_truncxf (operands[0], op1));
20638 DONE;
20639 })
20640
20641 (define_int_iterator SINCOS
20642 [UNSPEC_SIN
20643 UNSPEC_COS])
20644
20645 (define_int_attr sincos
20646 [(UNSPEC_SIN "sin")
20647 (UNSPEC_COS "cos")])
20648
20649 (define_insn "<sincos>xf2"
20650 [(set (match_operand:XF 0 "register_operand" "=f")
20651 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
20652 SINCOS))]
20653 "TARGET_USE_FANCY_MATH_387
20654 && flag_unsafe_math_optimizations"
20655 "f<sincos>"
20656 [(set_attr "type" "fpspc")
20657 (set_attr "znver1_decode" "vector")
20658 (set_attr "mode" "XF")])
20659
20660 (define_expand "<sincos><mode>2"
20661 [(set (match_operand:MODEF 0 "register_operand")
20662 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
20663 SINCOS))]
20664 "TARGET_USE_FANCY_MATH_387
20665 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20666 || TARGET_MIX_SSE_I387)
20667 && flag_unsafe_math_optimizations"
20668 {
20669 rtx op0 = gen_reg_rtx (XFmode);
20670 rtx op1 = gen_reg_rtx (XFmode);
20671
20672 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20673 emit_insn (gen_<sincos>xf2 (op0, op1));
20674 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20675 DONE;
20676 })
20677
20678 (define_insn "sincosxf3"
20679 [(set (match_operand:XF 0 "register_operand" "=f")
20680 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20681 UNSPEC_SINCOS_COS))
20682 (set (match_operand:XF 1 "register_operand" "=f")
20683 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
20684 "TARGET_USE_FANCY_MATH_387
20685 && flag_unsafe_math_optimizations"
20686 "fsincos"
20687 [(set_attr "type" "fpspc")
20688 (set_attr "znver1_decode" "vector")
20689 (set_attr "mode" "XF")])
20690
20691 (define_expand "sincos<mode>3"
20692 [(use (match_operand:MODEF 0 "register_operand"))
20693 (use (match_operand:MODEF 1 "register_operand"))
20694 (use (match_operand:MODEF 2 "general_operand"))]
20695 "TARGET_USE_FANCY_MATH_387
20696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20697 || TARGET_MIX_SSE_I387)
20698 && flag_unsafe_math_optimizations"
20699 {
20700 rtx op0 = gen_reg_rtx (XFmode);
20701 rtx op1 = gen_reg_rtx (XFmode);
20702 rtx op2 = gen_reg_rtx (XFmode);
20703
20704 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20705 emit_insn (gen_sincosxf3 (op0, op1, op2));
20706 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20707 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
20708 DONE;
20709 })
20710
20711 (define_insn "fptanxf4_i387"
20712 [(set (match_operand:SF 0 "register_operand" "=f")
20713 (match_operand:SF 3 "const1_operand"))
20714 (set (match_operand:XF 1 "register_operand" "=f")
20715 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20716 UNSPEC_TAN))]
20717 "TARGET_USE_FANCY_MATH_387
20718 && flag_unsafe_math_optimizations"
20719 "fptan"
20720 [(set_attr "type" "fpspc")
20721 (set_attr "znver1_decode" "vector")
20722 (set_attr "mode" "XF")])
20723
20724 (define_expand "tanxf2"
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 rtx one = gen_reg_rtx (SFmode);
20731 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
20732 CONST1_RTX (SFmode)));
20733 DONE;
20734 })
20735
20736 (define_expand "tan<mode>2"
20737 [(use (match_operand:MODEF 0 "register_operand"))
20738 (use (match_operand:MODEF 1 "general_operand"))]
20739 "TARGET_USE_FANCY_MATH_387
20740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20741 || TARGET_MIX_SSE_I387)
20742 && flag_unsafe_math_optimizations"
20743 {
20744 rtx op0 = gen_reg_rtx (XFmode);
20745 rtx op1 = gen_reg_rtx (XFmode);
20746
20747 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20748 emit_insn (gen_tanxf2 (op0, op1));
20749 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20750 DONE;
20751 })
20752
20753 (define_insn "atan2xf3"
20754 [(set (match_operand:XF 0 "register_operand" "=f")
20755 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20756 (match_operand:XF 1 "register_operand" "f")]
20757 UNSPEC_FPATAN))
20758 (clobber (match_scratch:XF 3 "=1"))]
20759 "TARGET_USE_FANCY_MATH_387
20760 && flag_unsafe_math_optimizations"
20761 "fpatan"
20762 [(set_attr "type" "fpspc")
20763 (set_attr "znver1_decode" "vector")
20764 (set_attr "mode" "XF")])
20765
20766 (define_expand "atan2<mode>3"
20767 [(use (match_operand:MODEF 0 "register_operand"))
20768 (use (match_operand:MODEF 1 "general_operand"))
20769 (use (match_operand:MODEF 2 "general_operand"))]
20770 "TARGET_USE_FANCY_MATH_387
20771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20772 || TARGET_MIX_SSE_I387)
20773 && flag_unsafe_math_optimizations"
20774 {
20775 rtx op0 = gen_reg_rtx (XFmode);
20776 rtx op1 = gen_reg_rtx (XFmode);
20777 rtx op2 = gen_reg_rtx (XFmode);
20778
20779 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20780 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20781
20782 emit_insn (gen_atan2xf3 (op0, op1, op2));
20783 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20784 DONE;
20785 })
20786
20787 (define_expand "atanxf2"
20788 [(parallel [(set (match_operand:XF 0 "register_operand")
20789 (unspec:XF [(match_dup 2)
20790 (match_operand:XF 1 "register_operand")]
20791 UNSPEC_FPATAN))
20792 (clobber (scratch:XF))])]
20793 "TARGET_USE_FANCY_MATH_387
20794 && flag_unsafe_math_optimizations"
20795 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
20796
20797 (define_expand "atan<mode>2"
20798 [(use (match_operand:MODEF 0 "register_operand"))
20799 (use (match_operand:MODEF 1 "general_operand"))]
20800 "TARGET_USE_FANCY_MATH_387
20801 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20802 || TARGET_MIX_SSE_I387)
20803 && flag_unsafe_math_optimizations"
20804 {
20805 rtx op0 = gen_reg_rtx (XFmode);
20806 rtx op1 = gen_reg_rtx (XFmode);
20807
20808 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20809 emit_insn (gen_atanxf2 (op0, op1));
20810 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20811 DONE;
20812 })
20813
20814 (define_expand "asinxf2"
20815 [(set (match_dup 2)
20816 (mult:XF (match_operand:XF 1 "register_operand")
20817 (match_dup 1)))
20818 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20819 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20820 (parallel [(set (match_operand:XF 0 "register_operand")
20821 (unspec:XF [(match_dup 5) (match_dup 1)]
20822 UNSPEC_FPATAN))
20823 (clobber (scratch:XF))])]
20824 "TARGET_USE_FANCY_MATH_387
20825 && flag_unsafe_math_optimizations"
20826 {
20827 int i;
20828
20829 for (i = 2; i < 6; i++)
20830 operands[i] = gen_reg_rtx (XFmode);
20831
20832 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20833 })
20834
20835 (define_expand "asin<mode>2"
20836 [(use (match_operand:MODEF 0 "register_operand"))
20837 (use (match_operand:MODEF 1 "general_operand"))]
20838 "TARGET_USE_FANCY_MATH_387
20839 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20840 || TARGET_MIX_SSE_I387)
20841 && flag_unsafe_math_optimizations"
20842 {
20843 rtx op0 = gen_reg_rtx (XFmode);
20844 rtx op1 = gen_reg_rtx (XFmode);
20845
20846 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20847 emit_insn (gen_asinxf2 (op0, op1));
20848 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20849 DONE;
20850 })
20851
20852 (define_expand "acosxf2"
20853 [(set (match_dup 2)
20854 (mult:XF (match_operand:XF 1 "register_operand")
20855 (match_dup 1)))
20856 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20857 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20858 (parallel [(set (match_operand:XF 0 "register_operand")
20859 (unspec:XF [(match_dup 1) (match_dup 5)]
20860 UNSPEC_FPATAN))
20861 (clobber (scratch:XF))])]
20862 "TARGET_USE_FANCY_MATH_387
20863 && flag_unsafe_math_optimizations"
20864 {
20865 int i;
20866
20867 for (i = 2; i < 6; i++)
20868 operands[i] = gen_reg_rtx (XFmode);
20869
20870 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20871 })
20872
20873 (define_expand "acos<mode>2"
20874 [(use (match_operand:MODEF 0 "register_operand"))
20875 (use (match_operand:MODEF 1 "general_operand"))]
20876 "TARGET_USE_FANCY_MATH_387
20877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20878 || TARGET_MIX_SSE_I387)
20879 && flag_unsafe_math_optimizations"
20880 {
20881 rtx op0 = gen_reg_rtx (XFmode);
20882 rtx op1 = gen_reg_rtx (XFmode);
20883
20884 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20885 emit_insn (gen_acosxf2 (op0, op1));
20886 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20887 DONE;
20888 })
20889
20890 (define_expand "sinhxf2"
20891 [(use (match_operand:XF 0 "register_operand"))
20892 (use (match_operand:XF 1 "register_operand"))]
20893 "TARGET_USE_FANCY_MATH_387
20894 && flag_finite_math_only
20895 && flag_unsafe_math_optimizations"
20896 {
20897 ix86_emit_i387_sinh (operands[0], operands[1]);
20898 DONE;
20899 })
20900
20901 (define_expand "sinh<mode>2"
20902 [(use (match_operand:MODEF 0 "register_operand"))
20903 (use (match_operand:MODEF 1 "general_operand"))]
20904 "TARGET_USE_FANCY_MATH_387
20905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20906 || TARGET_MIX_SSE_I387)
20907 && flag_finite_math_only
20908 && flag_unsafe_math_optimizations"
20909 {
20910 rtx op0 = gen_reg_rtx (XFmode);
20911 rtx op1 = gen_reg_rtx (XFmode);
20912
20913 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20914 emit_insn (gen_sinhxf2 (op0, op1));
20915 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20916 DONE;
20917 })
20918
20919 (define_expand "coshxf2"
20920 [(use (match_operand:XF 0 "register_operand"))
20921 (use (match_operand:XF 1 "register_operand"))]
20922 "TARGET_USE_FANCY_MATH_387
20923 && flag_unsafe_math_optimizations"
20924 {
20925 ix86_emit_i387_cosh (operands[0], operands[1]);
20926 DONE;
20927 })
20928
20929 (define_expand "cosh<mode>2"
20930 [(use (match_operand:MODEF 0 "register_operand"))
20931 (use (match_operand:MODEF 1 "general_operand"))]
20932 "TARGET_USE_FANCY_MATH_387
20933 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20934 || TARGET_MIX_SSE_I387)
20935 && flag_unsafe_math_optimizations"
20936 {
20937 rtx op0 = gen_reg_rtx (XFmode);
20938 rtx op1 = gen_reg_rtx (XFmode);
20939
20940 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20941 emit_insn (gen_coshxf2 (op0, op1));
20942 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20943 DONE;
20944 })
20945
20946 (define_expand "tanhxf2"
20947 [(use (match_operand:XF 0 "register_operand"))
20948 (use (match_operand:XF 1 "register_operand"))]
20949 "TARGET_USE_FANCY_MATH_387
20950 && flag_unsafe_math_optimizations"
20951 {
20952 ix86_emit_i387_tanh (operands[0], operands[1]);
20953 DONE;
20954 })
20955
20956 (define_expand "tanh<mode>2"
20957 [(use (match_operand:MODEF 0 "register_operand"))
20958 (use (match_operand:MODEF 1 "general_operand"))]
20959 "TARGET_USE_FANCY_MATH_387
20960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20961 || TARGET_MIX_SSE_I387)
20962 && flag_unsafe_math_optimizations"
20963 {
20964 rtx op0 = gen_reg_rtx (XFmode);
20965 rtx op1 = gen_reg_rtx (XFmode);
20966
20967 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20968 emit_insn (gen_tanhxf2 (op0, op1));
20969 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20970 DONE;
20971 })
20972
20973 (define_expand "asinhxf2"
20974 [(use (match_operand:XF 0 "register_operand"))
20975 (use (match_operand:XF 1 "register_operand"))]
20976 "TARGET_USE_FANCY_MATH_387
20977 && flag_finite_math_only
20978 && flag_unsafe_math_optimizations"
20979 {
20980 ix86_emit_i387_asinh (operands[0], operands[1]);
20981 DONE;
20982 })
20983
20984 (define_expand "asinh<mode>2"
20985 [(use (match_operand:MODEF 0 "register_operand"))
20986 (use (match_operand:MODEF 1 "general_operand"))]
20987 "TARGET_USE_FANCY_MATH_387
20988 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20989 || TARGET_MIX_SSE_I387)
20990 && flag_finite_math_only
20991 && flag_unsafe_math_optimizations"
20992 {
20993 rtx op0 = gen_reg_rtx (XFmode);
20994 rtx op1 = gen_reg_rtx (XFmode);
20995
20996 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20997 emit_insn (gen_asinhxf2 (op0, op1));
20998 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20999 DONE;
21000 })
21001
21002 (define_expand "acoshxf2"
21003 [(use (match_operand:XF 0 "register_operand"))
21004 (use (match_operand:XF 1 "register_operand"))]
21005 "TARGET_USE_FANCY_MATH_387
21006 && flag_unsafe_math_optimizations"
21007 {
21008 ix86_emit_i387_acosh (operands[0], operands[1]);
21009 DONE;
21010 })
21011
21012 (define_expand "acosh<mode>2"
21013 [(use (match_operand:MODEF 0 "register_operand"))
21014 (use (match_operand:MODEF 1 "general_operand"))]
21015 "TARGET_USE_FANCY_MATH_387
21016 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21017 || TARGET_MIX_SSE_I387)
21018 && flag_unsafe_math_optimizations"
21019 {
21020 rtx op0 = gen_reg_rtx (XFmode);
21021 rtx op1 = gen_reg_rtx (XFmode);
21022
21023 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21024 emit_insn (gen_acoshxf2 (op0, op1));
21025 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21026 DONE;
21027 })
21028
21029 (define_expand "atanhxf2"
21030 [(use (match_operand:XF 0 "register_operand"))
21031 (use (match_operand:XF 1 "register_operand"))]
21032 "TARGET_USE_FANCY_MATH_387
21033 && flag_unsafe_math_optimizations"
21034 {
21035 ix86_emit_i387_atanh (operands[0], operands[1]);
21036 DONE;
21037 })
21038
21039 (define_expand "atanh<mode>2"
21040 [(use (match_operand:MODEF 0 "register_operand"))
21041 (use (match_operand:MODEF 1 "general_operand"))]
21042 "TARGET_USE_FANCY_MATH_387
21043 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21044 || TARGET_MIX_SSE_I387)
21045 && flag_unsafe_math_optimizations"
21046 {
21047 rtx op0 = gen_reg_rtx (XFmode);
21048 rtx op1 = gen_reg_rtx (XFmode);
21049
21050 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21051 emit_insn (gen_atanhxf2 (op0, op1));
21052 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21053 DONE;
21054 })
21055
21056 (define_insn "fyl2xxf3_i387"
21057 [(set (match_operand:XF 0 "register_operand" "=f")
21058 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21059 (match_operand:XF 2 "register_operand" "f")]
21060 UNSPEC_FYL2X))
21061 (clobber (match_scratch:XF 3 "=2"))]
21062 "TARGET_USE_FANCY_MATH_387
21063 && flag_unsafe_math_optimizations"
21064 "fyl2x"
21065 [(set_attr "type" "fpspc")
21066 (set_attr "znver1_decode" "vector")
21067 (set_attr "mode" "XF")])
21068
21069 (define_expand "logxf2"
21070 [(parallel [(set (match_operand:XF 0 "register_operand")
21071 (unspec:XF [(match_operand:XF 1 "register_operand")
21072 (match_dup 2)] UNSPEC_FYL2X))
21073 (clobber (scratch:XF))])]
21074 "TARGET_USE_FANCY_MATH_387
21075 && flag_unsafe_math_optimizations"
21076 {
21077 operands[2]
21078 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
21079 })
21080
21081 (define_expand "log<mode>2"
21082 [(use (match_operand:MODEF 0 "register_operand"))
21083 (use (match_operand:MODEF 1 "general_operand"))]
21084 "TARGET_USE_FANCY_MATH_387
21085 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21086 || TARGET_MIX_SSE_I387)
21087 && flag_unsafe_math_optimizations"
21088 {
21089 rtx op0 = gen_reg_rtx (XFmode);
21090 rtx op1 = gen_reg_rtx (XFmode);
21091
21092 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21093 emit_insn (gen_logxf2 (op0, op1));
21094 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21095 DONE;
21096 })
21097
21098 (define_expand "log10xf2"
21099 [(parallel [(set (match_operand:XF 0 "register_operand")
21100 (unspec:XF [(match_operand:XF 1 "register_operand")
21101 (match_dup 2)] UNSPEC_FYL2X))
21102 (clobber (scratch:XF))])]
21103 "TARGET_USE_FANCY_MATH_387
21104 && flag_unsafe_math_optimizations"
21105 {
21106 operands[2]
21107 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
21108 })
21109
21110 (define_expand "log10<mode>2"
21111 [(use (match_operand:MODEF 0 "register_operand"))
21112 (use (match_operand:MODEF 1 "general_operand"))]
21113 "TARGET_USE_FANCY_MATH_387
21114 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21115 || TARGET_MIX_SSE_I387)
21116 && flag_unsafe_math_optimizations"
21117 {
21118 rtx op0 = gen_reg_rtx (XFmode);
21119 rtx op1 = gen_reg_rtx (XFmode);
21120
21121 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21122 emit_insn (gen_log10xf2 (op0, op1));
21123 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21124 DONE;
21125 })
21126
21127 (define_expand "log2xf2"
21128 [(parallel [(set (match_operand:XF 0 "register_operand")
21129 (unspec:XF [(match_operand:XF 1 "register_operand")
21130 (match_dup 2)] UNSPEC_FYL2X))
21131 (clobber (scratch:XF))])]
21132 "TARGET_USE_FANCY_MATH_387
21133 && flag_unsafe_math_optimizations"
21134 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21135
21136 (define_expand "log2<mode>2"
21137 [(use (match_operand:MODEF 0 "register_operand"))
21138 (use (match_operand:MODEF 1 "general_operand"))]
21139 "TARGET_USE_FANCY_MATH_387
21140 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21141 || TARGET_MIX_SSE_I387)
21142 && flag_unsafe_math_optimizations"
21143 {
21144 rtx op0 = gen_reg_rtx (XFmode);
21145 rtx op1 = gen_reg_rtx (XFmode);
21146
21147 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21148 emit_insn (gen_log2xf2 (op0, op1));
21149 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21150 DONE;
21151 })
21152
21153 (define_insn "fyl2xp1xf3_i387"
21154 [(set (match_operand:XF 0 "register_operand" "=f")
21155 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21156 (match_operand:XF 2 "register_operand" "f")]
21157 UNSPEC_FYL2XP1))
21158 (clobber (match_scratch:XF 3 "=2"))]
21159 "TARGET_USE_FANCY_MATH_387
21160 && flag_unsafe_math_optimizations"
21161 "fyl2xp1"
21162 [(set_attr "type" "fpspc")
21163 (set_attr "znver1_decode" "vector")
21164 (set_attr "mode" "XF")])
21165
21166 (define_expand "log1pxf2"
21167 [(use (match_operand:XF 0 "register_operand"))
21168 (use (match_operand:XF 1 "register_operand"))]
21169 "TARGET_USE_FANCY_MATH_387
21170 && flag_unsafe_math_optimizations"
21171 {
21172 ix86_emit_i387_log1p (operands[0], operands[1]);
21173 DONE;
21174 })
21175
21176 (define_expand "log1p<mode>2"
21177 [(use (match_operand:MODEF 0 "register_operand"))
21178 (use (match_operand:MODEF 1 "general_operand"))]
21179 "TARGET_USE_FANCY_MATH_387
21180 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21181 || TARGET_MIX_SSE_I387)
21182 && flag_unsafe_math_optimizations"
21183 {
21184 rtx op0 = gen_reg_rtx (XFmode);
21185 rtx op1 = gen_reg_rtx (XFmode);
21186
21187 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21188 emit_insn (gen_log1pxf2 (op0, op1));
21189 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21190 DONE;
21191 })
21192
21193 (define_insn "fxtractxf3_i387"
21194 [(set (match_operand:XF 0 "register_operand" "=f")
21195 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21196 UNSPEC_XTRACT_FRACT))
21197 (set (match_operand:XF 1 "register_operand" "=f")
21198 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21199 "TARGET_USE_FANCY_MATH_387
21200 && flag_unsafe_math_optimizations"
21201 "fxtract"
21202 [(set_attr "type" "fpspc")
21203 (set_attr "znver1_decode" "vector")
21204 (set_attr "mode" "XF")])
21205
21206 (define_expand "logbxf2"
21207 [(parallel [(set (match_dup 2)
21208 (unspec:XF [(match_operand:XF 1 "register_operand")]
21209 UNSPEC_XTRACT_FRACT))
21210 (set (match_operand:XF 0 "register_operand")
21211 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21212 "TARGET_USE_FANCY_MATH_387
21213 && flag_unsafe_math_optimizations"
21214 "operands[2] = gen_reg_rtx (XFmode);")
21215
21216 (define_expand "logb<mode>2"
21217 [(use (match_operand:MODEF 0 "register_operand"))
21218 (use (match_operand:MODEF 1 "general_operand"))]
21219 "TARGET_USE_FANCY_MATH_387
21220 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21221 || TARGET_MIX_SSE_I387)
21222 && flag_unsafe_math_optimizations"
21223 {
21224 rtx op0 = gen_reg_rtx (XFmode);
21225 rtx op1 = gen_reg_rtx (XFmode);
21226
21227 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21228 emit_insn (gen_logbxf2 (op0, op1));
21229 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21230 DONE;
21231 })
21232
21233 (define_expand "ilogbxf2"
21234 [(use (match_operand:SI 0 "register_operand"))
21235 (use (match_operand:XF 1 "register_operand"))]
21236 "TARGET_USE_FANCY_MATH_387
21237 && flag_unsafe_math_optimizations"
21238 {
21239 rtx op0, op1;
21240
21241 if (optimize_insn_for_size_p ())
21242 FAIL;
21243
21244 op0 = gen_reg_rtx (XFmode);
21245 op1 = gen_reg_rtx (XFmode);
21246
21247 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21248 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21249 DONE;
21250 })
21251
21252 (define_expand "ilogb<mode>2"
21253 [(use (match_operand:SI 0 "register_operand"))
21254 (use (match_operand:MODEF 1 "general_operand"))]
21255 "TARGET_USE_FANCY_MATH_387
21256 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21257 || TARGET_MIX_SSE_I387)
21258 && flag_unsafe_math_optimizations"
21259 {
21260 rtx op0, op1, op2;
21261
21262 if (optimize_insn_for_size_p ())
21263 FAIL;
21264
21265 op0 = gen_reg_rtx (XFmode);
21266 op1 = gen_reg_rtx (XFmode);
21267 op2 = gen_reg_rtx (XFmode);
21268
21269 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21270 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21271 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21272 DONE;
21273 })
21274
21275 (define_insn "*f2xm1xf2_i387"
21276 [(set (match_operand:XF 0 "register_operand" "=f")
21277 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21278 UNSPEC_F2XM1))]
21279 "TARGET_USE_FANCY_MATH_387
21280 && flag_unsafe_math_optimizations"
21281 "f2xm1"
21282 [(set_attr "type" "fpspc")
21283 (set_attr "znver1_decode" "vector")
21284 (set_attr "mode" "XF")])
21285
21286 (define_insn "fscalexf4_i387"
21287 [(set (match_operand:XF 0 "register_operand" "=f")
21288 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21289 (match_operand:XF 3 "register_operand" "1")]
21290 UNSPEC_FSCALE_FRACT))
21291 (set (match_operand:XF 1 "register_operand" "=f")
21292 (unspec:XF [(match_dup 2) (match_dup 3)]
21293 UNSPEC_FSCALE_EXP))]
21294 "TARGET_USE_FANCY_MATH_387
21295 && flag_unsafe_math_optimizations"
21296 "fscale"
21297 [(set_attr "type" "fpspc")
21298 (set_attr "znver1_decode" "vector")
21299 (set_attr "mode" "XF")])
21300
21301 (define_expand "expNcorexf3"
21302 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21303 (match_operand:XF 2 "register_operand")))
21304 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21305 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21306 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21307 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21308 (parallel [(set (match_operand:XF 0 "register_operand")
21309 (unspec:XF [(match_dup 8) (match_dup 4)]
21310 UNSPEC_FSCALE_FRACT))
21311 (set (match_dup 9)
21312 (unspec:XF [(match_dup 8) (match_dup 4)]
21313 UNSPEC_FSCALE_EXP))])]
21314 "TARGET_USE_FANCY_MATH_387
21315 && flag_unsafe_math_optimizations"
21316 {
21317 int i;
21318
21319 for (i = 3; i < 10; i++)
21320 operands[i] = gen_reg_rtx (XFmode);
21321
21322 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21323 })
21324
21325 (define_expand "expxf2"
21326 [(use (match_operand:XF 0 "register_operand"))
21327 (use (match_operand:XF 1 "register_operand"))]
21328 "TARGET_USE_FANCY_MATH_387
21329 && flag_unsafe_math_optimizations"
21330 {
21331 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21332
21333 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21334 DONE;
21335 })
21336
21337 (define_expand "exp<mode>2"
21338 [(use (match_operand:MODEF 0 "register_operand"))
21339 (use (match_operand:MODEF 1 "general_operand"))]
21340 "TARGET_USE_FANCY_MATH_387
21341 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21342 || TARGET_MIX_SSE_I387)
21343 && flag_unsafe_math_optimizations"
21344 {
21345 rtx op0 = gen_reg_rtx (XFmode);
21346 rtx op1 = gen_reg_rtx (XFmode);
21347
21348 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21349 emit_insn (gen_expxf2 (op0, op1));
21350 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21351 DONE;
21352 })
21353
21354 (define_expand "exp10xf2"
21355 [(use (match_operand:XF 0 "register_operand"))
21356 (use (match_operand:XF 1 "register_operand"))]
21357 "TARGET_USE_FANCY_MATH_387
21358 && flag_unsafe_math_optimizations"
21359 {
21360 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21361
21362 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21363 DONE;
21364 })
21365
21366 (define_expand "exp10<mode>2"
21367 [(use (match_operand:MODEF 0 "register_operand"))
21368 (use (match_operand:MODEF 1 "general_operand"))]
21369 "TARGET_USE_FANCY_MATH_387
21370 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21371 || TARGET_MIX_SSE_I387)
21372 && flag_unsafe_math_optimizations"
21373 {
21374 rtx op0 = gen_reg_rtx (XFmode);
21375 rtx op1 = gen_reg_rtx (XFmode);
21376
21377 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21378 emit_insn (gen_exp10xf2 (op0, op1));
21379 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21380 DONE;
21381 })
21382
21383 (define_expand "exp2xf2"
21384 [(use (match_operand:XF 0 "register_operand"))
21385 (use (match_operand:XF 1 "register_operand"))]
21386 "TARGET_USE_FANCY_MATH_387
21387 && flag_unsafe_math_optimizations"
21388 {
21389 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21390
21391 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21392 DONE;
21393 })
21394
21395 (define_expand "exp2<mode>2"
21396 [(use (match_operand:MODEF 0 "register_operand"))
21397 (use (match_operand:MODEF 1 "general_operand"))]
21398 "TARGET_USE_FANCY_MATH_387
21399 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21400 || TARGET_MIX_SSE_I387)
21401 && flag_unsafe_math_optimizations"
21402 {
21403 rtx op0 = gen_reg_rtx (XFmode);
21404 rtx op1 = gen_reg_rtx (XFmode);
21405
21406 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21407 emit_insn (gen_exp2xf2 (op0, op1));
21408 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21409 DONE;
21410 })
21411
21412 (define_expand "expm1xf2"
21413 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21414 (match_dup 2)))
21415 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21416 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21417 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21418 (parallel [(set (match_dup 7)
21419 (unspec:XF [(match_dup 6) (match_dup 4)]
21420 UNSPEC_FSCALE_FRACT))
21421 (set (match_dup 8)
21422 (unspec:XF [(match_dup 6) (match_dup 4)]
21423 UNSPEC_FSCALE_EXP))])
21424 (parallel [(set (match_dup 10)
21425 (unspec:XF [(match_dup 9) (match_dup 8)]
21426 UNSPEC_FSCALE_FRACT))
21427 (set (match_dup 11)
21428 (unspec:XF [(match_dup 9) (match_dup 8)]
21429 UNSPEC_FSCALE_EXP))])
21430 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21431 (set (match_operand:XF 0 "register_operand")
21432 (plus:XF (match_dup 12) (match_dup 7)))]
21433 "TARGET_USE_FANCY_MATH_387
21434 && flag_unsafe_math_optimizations"
21435 {
21436 int i;
21437
21438 for (i = 2; i < 13; i++)
21439 operands[i] = gen_reg_rtx (XFmode);
21440
21441 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21442 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21443 })
21444
21445 (define_expand "expm1<mode>2"
21446 [(use (match_operand:MODEF 0 "register_operand"))
21447 (use (match_operand:MODEF 1 "general_operand"))]
21448 "TARGET_USE_FANCY_MATH_387
21449 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21450 || TARGET_MIX_SSE_I387)
21451 && flag_unsafe_math_optimizations"
21452 {
21453 rtx op0 = gen_reg_rtx (XFmode);
21454 rtx op1 = gen_reg_rtx (XFmode);
21455
21456 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21457 emit_insn (gen_expm1xf2 (op0, op1));
21458 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21459 DONE;
21460 })
21461
21462 (define_insn "avx512f_scalef<mode>2"
21463 [(set (match_operand:MODEF 0 "register_operand" "=v")
21464 (unspec:MODEF
21465 [(match_operand:MODEF 1 "register_operand" "v")
21466 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21467 UNSPEC_SCALEF))]
21468 "TARGET_AVX512F"
21469 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21470 [(set_attr "prefix" "evex")
21471 (set_attr "mode" "<MODE>")])
21472
21473 (define_expand "ldexpxf3"
21474 [(match_operand:XF 0 "register_operand")
21475 (match_operand:XF 1 "register_operand")
21476 (match_operand:SI 2 "register_operand")]
21477 "TARGET_USE_FANCY_MATH_387
21478 && flag_unsafe_math_optimizations"
21479 {
21480 rtx tmp1 = gen_reg_rtx (XFmode);
21481 rtx tmp2 = gen_reg_rtx (XFmode);
21482
21483 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21484 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21485 operands[1], tmp1));
21486 DONE;
21487 })
21488
21489 (define_expand "ldexp<mode>3"
21490 [(use (match_operand:MODEF 0 "register_operand"))
21491 (use (match_operand:MODEF 1 "general_operand"))
21492 (use (match_operand:SI 2 "register_operand"))]
21493 "((TARGET_USE_FANCY_MATH_387
21494 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21495 || TARGET_MIX_SSE_I387))
21496 || (TARGET_AVX512F && TARGET_SSE_MATH))
21497 && flag_unsafe_math_optimizations"
21498 {
21499 /* Prefer avx512f version. */
21500 if (TARGET_AVX512F && TARGET_SSE_MATH)
21501 {
21502 rtx op2 = gen_reg_rtx (<MODE>mode);
21503 operands[1] = force_reg (<MODE>mode, operands[1]);
21504
21505 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21506 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21507 }
21508 else
21509 {
21510 rtx op0 = gen_reg_rtx (XFmode);
21511 rtx op1 = gen_reg_rtx (XFmode);
21512
21513 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21514 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21515 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21516 }
21517 DONE;
21518 })
21519
21520 (define_expand "scalbxf3"
21521 [(parallel [(set (match_operand:XF 0 " register_operand")
21522 (unspec:XF [(match_operand:XF 1 "register_operand")
21523 (match_operand:XF 2 "register_operand")]
21524 UNSPEC_FSCALE_FRACT))
21525 (set (match_dup 3)
21526 (unspec:XF [(match_dup 1) (match_dup 2)]
21527 UNSPEC_FSCALE_EXP))])]
21528 "TARGET_USE_FANCY_MATH_387
21529 && flag_unsafe_math_optimizations"
21530 "operands[3] = gen_reg_rtx (XFmode);")
21531
21532 (define_expand "scalb<mode>3"
21533 [(use (match_operand:MODEF 0 "register_operand"))
21534 (use (match_operand:MODEF 1 "general_operand"))
21535 (use (match_operand:MODEF 2 "general_operand"))]
21536 "TARGET_USE_FANCY_MATH_387
21537 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21538 || TARGET_MIX_SSE_I387)
21539 && flag_unsafe_math_optimizations"
21540 {
21541 rtx op0 = gen_reg_rtx (XFmode);
21542 rtx op1 = gen_reg_rtx (XFmode);
21543 rtx op2 = gen_reg_rtx (XFmode);
21544
21545 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21546 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21547 emit_insn (gen_scalbxf3 (op0, op1, op2));
21548 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21549 DONE;
21550 })
21551
21552 (define_expand "significandxf2"
21553 [(parallel [(set (match_operand:XF 0 "register_operand")
21554 (unspec:XF [(match_operand:XF 1 "register_operand")]
21555 UNSPEC_XTRACT_FRACT))
21556 (set (match_dup 2)
21557 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21558 "TARGET_USE_FANCY_MATH_387
21559 && flag_unsafe_math_optimizations"
21560 "operands[2] = gen_reg_rtx (XFmode);")
21561
21562 (define_expand "significand<mode>2"
21563 [(use (match_operand:MODEF 0 "register_operand"))
21564 (use (match_operand:MODEF 1 "general_operand"))]
21565 "TARGET_USE_FANCY_MATH_387
21566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21567 || TARGET_MIX_SSE_I387)
21568 && flag_unsafe_math_optimizations"
21569 {
21570 rtx op0 = gen_reg_rtx (XFmode);
21571 rtx op1 = gen_reg_rtx (XFmode);
21572
21573 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21574 emit_insn (gen_significandxf2 (op0, op1));
21575 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21576 DONE;
21577 })
21578 \f
21579
21580 (define_insn "sse4_1_round<mode>2"
21581 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21582 (unspec:MODEFH
21583 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,m,v,m")
21584 (match_operand:SI 2 "const_0_to_15_operand")]
21585 UNSPEC_ROUND))]
21586 "TARGET_SSE4_1"
21587 "@
21588 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21589 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21590 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21591 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21592 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21593 [(set_attr "type" "ssecvt")
21594 (set_attr "prefix_extra" "1,1,1,*,*")
21595 (set_attr "length_immediate" "*,*,*,1,1")
21596 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21597 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21598 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21599 (set_attr "mode" "<MODE>")
21600 (set (attr "preferred_for_speed")
21601 (cond [(match_test "TARGET_AVX")
21602 (symbol_ref "true")
21603 (eq_attr "alternative" "1,2")
21604 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21605 ]
21606 (symbol_ref "true")))])
21607
21608 (define_insn "rintxf2"
21609 [(set (match_operand:XF 0 "register_operand" "=f")
21610 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21611 UNSPEC_FRNDINT))]
21612 "TARGET_USE_FANCY_MATH_387"
21613 "frndint"
21614 [(set_attr "type" "fpspc")
21615 (set_attr "znver1_decode" "vector")
21616 (set_attr "mode" "XF")])
21617
21618 (define_expand "rinthf2"
21619 [(match_operand:HF 0 "register_operand")
21620 (match_operand:HF 1 "nonimmediate_operand")]
21621 "TARGET_AVX512FP16"
21622 {
21623 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21624 operands[1],
21625 GEN_INT (ROUND_MXCSR)));
21626 DONE;
21627 })
21628
21629 (define_expand "rint<mode>2"
21630 [(use (match_operand:MODEF 0 "register_operand"))
21631 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21632 "TARGET_USE_FANCY_MATH_387
21633 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21634 {
21635 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21636 {
21637 if (TARGET_SSE4_1)
21638 emit_insn (gen_sse4_1_round<mode>2
21639 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
21640 else
21641 ix86_expand_rint (operands[0], operands[1]);
21642 }
21643 else
21644 {
21645 rtx op0 = gen_reg_rtx (XFmode);
21646 rtx op1 = gen_reg_rtx (XFmode);
21647
21648 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21649 emit_insn (gen_rintxf2 (op0, op1));
21650 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21651 }
21652 DONE;
21653 })
21654
21655 (define_expand "nearbyintxf2"
21656 [(set (match_operand:XF 0 "register_operand")
21657 (unspec:XF [(match_operand:XF 1 "register_operand")]
21658 UNSPEC_FRNDINT))]
21659 "TARGET_USE_FANCY_MATH_387
21660 && !flag_trapping_math")
21661
21662 (define_expand "nearbyinthf2"
21663 [(match_operand:HF 0 "register_operand")
21664 (match_operand:HF 1 "nonimmediate_operand")]
21665 "TARGET_AVX512FP16"
21666 {
21667 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21668 operands[1],
21669 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
21670 DONE;
21671 })
21672
21673 (define_expand "nearbyint<mode>2"
21674 [(use (match_operand:MODEF 0 "register_operand"))
21675 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21676 "(TARGET_USE_FANCY_MATH_387
21677 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21678 || TARGET_MIX_SSE_I387)
21679 && !flag_trapping_math)
21680 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
21681 {
21682 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
21683 emit_insn (gen_sse4_1_round<mode>2
21684 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
21685 | ROUND_NO_EXC)));
21686 else
21687 {
21688 rtx op0 = gen_reg_rtx (XFmode);
21689 rtx op1 = gen_reg_rtx (XFmode);
21690
21691 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21692 emit_insn (gen_nearbyintxf2 (op0, op1));
21693 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21694 }
21695 DONE;
21696 })
21697
21698 (define_expand "round<mode>2"
21699 [(match_operand:X87MODEF 0 "register_operand")
21700 (match_operand:X87MODEF 1 "nonimmediate_operand")]
21701 "(TARGET_USE_FANCY_MATH_387
21702 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21703 || TARGET_MIX_SSE_I387)
21704 && flag_unsafe_math_optimizations
21705 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21706 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21707 && !flag_trapping_math && !flag_rounding_math)"
21708 {
21709 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21710 && !flag_trapping_math && !flag_rounding_math)
21711 {
21712 if (TARGET_SSE4_1)
21713 {
21714 operands[1] = force_reg (<MODE>mode, operands[1]);
21715 ix86_expand_round_sse4 (operands[0], operands[1]);
21716 }
21717 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21718 ix86_expand_round (operands[0], operands[1]);
21719 else
21720 ix86_expand_rounddf_32 (operands[0], operands[1]);
21721 }
21722 else
21723 {
21724 operands[1] = force_reg (<MODE>mode, operands[1]);
21725 ix86_emit_i387_round (operands[0], operands[1]);
21726 }
21727 DONE;
21728 })
21729
21730 (define_insn "lrintxfdi2"
21731 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21732 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21733 UNSPEC_FIST))
21734 (clobber (match_scratch:XF 2 "=&f"))]
21735 "TARGET_USE_FANCY_MATH_387"
21736 "* return output_fix_trunc (insn, operands, false);"
21737 [(set_attr "type" "fpspc")
21738 (set_attr "mode" "DI")])
21739
21740 (define_insn "lrintxf<mode>2"
21741 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21742 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21743 UNSPEC_FIST))]
21744 "TARGET_USE_FANCY_MATH_387"
21745 "* return output_fix_trunc (insn, operands, false);"
21746 [(set_attr "type" "fpspc")
21747 (set_attr "mode" "<MODE>")])
21748
21749 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
21750 [(set (match_operand:SWI48 0 "register_operand")
21751 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
21752 UNSPEC_FIX_NOTRUNC))]
21753 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
21754
21755 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
21756 [(match_operand:SWI248x 0 "nonimmediate_operand")
21757 (match_operand:X87MODEF 1 "register_operand")]
21758 "(TARGET_USE_FANCY_MATH_387
21759 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
21760 || TARGET_MIX_SSE_I387)
21761 && flag_unsafe_math_optimizations)
21762 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21763 && <SWI248x:MODE>mode != HImode
21764 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21765 && !flag_trapping_math && !flag_rounding_math)"
21766 {
21767 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21768 && <SWI248x:MODE>mode != HImode
21769 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21770 && !flag_trapping_math && !flag_rounding_math)
21771 ix86_expand_lround (operands[0], operands[1]);
21772 else
21773 ix86_emit_i387_round (operands[0], operands[1]);
21774 DONE;
21775 })
21776
21777 (define_int_iterator FRNDINT_ROUNDING
21778 [UNSPEC_FRNDINT_ROUNDEVEN
21779 UNSPEC_FRNDINT_FLOOR
21780 UNSPEC_FRNDINT_CEIL
21781 UNSPEC_FRNDINT_TRUNC])
21782
21783 (define_int_iterator FIST_ROUNDING
21784 [UNSPEC_FIST_FLOOR
21785 UNSPEC_FIST_CEIL])
21786
21787 ;; Base name for define_insn
21788 (define_int_attr rounding_insn
21789 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21790 (UNSPEC_FRNDINT_FLOOR "floor")
21791 (UNSPEC_FRNDINT_CEIL "ceil")
21792 (UNSPEC_FRNDINT_TRUNC "btrunc")
21793 (UNSPEC_FIST_FLOOR "floor")
21794 (UNSPEC_FIST_CEIL "ceil")])
21795
21796 (define_int_attr rounding
21797 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21798 (UNSPEC_FRNDINT_FLOOR "floor")
21799 (UNSPEC_FRNDINT_CEIL "ceil")
21800 (UNSPEC_FRNDINT_TRUNC "trunc")
21801 (UNSPEC_FIST_FLOOR "floor")
21802 (UNSPEC_FIST_CEIL "ceil")])
21803
21804 (define_int_attr ROUNDING
21805 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
21806 (UNSPEC_FRNDINT_FLOOR "FLOOR")
21807 (UNSPEC_FRNDINT_CEIL "CEIL")
21808 (UNSPEC_FRNDINT_TRUNC "TRUNC")
21809 (UNSPEC_FIST_FLOOR "FLOOR")
21810 (UNSPEC_FIST_CEIL "CEIL")])
21811
21812 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21813 (define_insn_and_split "frndintxf2_<rounding>"
21814 [(set (match_operand:XF 0 "register_operand")
21815 (unspec:XF [(match_operand:XF 1 "register_operand")]
21816 FRNDINT_ROUNDING))
21817 (clobber (reg:CC FLAGS_REG))]
21818 "TARGET_USE_FANCY_MATH_387
21819 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
21820 && ix86_pre_reload_split ()"
21821 "#"
21822 "&& 1"
21823 [(const_int 0)]
21824 {
21825 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
21826
21827 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
21828 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
21829
21830 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
21831 operands[2], operands[3]));
21832 DONE;
21833 }
21834 [(set_attr "type" "frndint")
21835 (set_attr "i387_cw" "<rounding>")
21836 (set_attr "mode" "XF")])
21837
21838 (define_insn "frndintxf2_<rounding>_i387"
21839 [(set (match_operand:XF 0 "register_operand" "=f")
21840 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21841 FRNDINT_ROUNDING))
21842 (use (match_operand:HI 2 "memory_operand" "m"))
21843 (use (match_operand:HI 3 "memory_operand" "m"))]
21844 "TARGET_USE_FANCY_MATH_387
21845 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
21846 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
21847 [(set_attr "type" "frndint")
21848 (set_attr "i387_cw" "<rounding>")
21849 (set_attr "mode" "XF")])
21850
21851 (define_expand "<rounding_insn>xf2"
21852 [(parallel [(set (match_operand:XF 0 "register_operand")
21853 (unspec:XF [(match_operand:XF 1 "register_operand")]
21854 FRNDINT_ROUNDING))
21855 (clobber (reg:CC FLAGS_REG))])]
21856 "TARGET_USE_FANCY_MATH_387
21857 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
21858
21859 (define_expand "<rounding_insn>hf2"
21860 [(parallel [(set (match_operand:HF 0 "register_operand")
21861 (unspec:HF [(match_operand:HF 1 "register_operand")]
21862 FRNDINT_ROUNDING))
21863 (clobber (reg:CC FLAGS_REG))])]
21864 "TARGET_AVX512FP16"
21865 {
21866 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
21867 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
21868 DONE;
21869 })
21870
21871 (define_expand "<rounding_insn><mode>2"
21872 [(parallel [(set (match_operand:MODEF 0 "register_operand")
21873 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
21874 FRNDINT_ROUNDING))
21875 (clobber (reg:CC FLAGS_REG))])]
21876 "(TARGET_USE_FANCY_MATH_387
21877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21878 || TARGET_MIX_SSE_I387)
21879 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21880 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21881 && (TARGET_SSE4_1
21882 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
21883 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
21884 {
21885 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21886 && (TARGET_SSE4_1
21887 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
21888 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
21889 {
21890 if (TARGET_SSE4_1)
21891 emit_insn (gen_sse4_1_round<mode>2
21892 (operands[0], operands[1],
21893 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
21894 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21895 {
21896 if (ROUND_<ROUNDING> == ROUND_FLOOR)
21897 ix86_expand_floorceil (operands[0], operands[1], true);
21898 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21899 ix86_expand_floorceil (operands[0], operands[1], false);
21900 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
21901 ix86_expand_trunc (operands[0], operands[1]);
21902 else
21903 gcc_unreachable ();
21904 }
21905 else
21906 {
21907 if (ROUND_<ROUNDING> == ROUND_FLOOR)
21908 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
21909 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21910 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
21911 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
21912 ix86_expand_truncdf_32 (operands[0], operands[1]);
21913 else
21914 gcc_unreachable ();
21915 }
21916 }
21917 else
21918 {
21919 rtx op0 = gen_reg_rtx (XFmode);
21920 rtx op1 = gen_reg_rtx (XFmode);
21921
21922 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21923 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
21924 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21925 }
21926 DONE;
21927 })
21928
21929 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21930 (define_insn_and_split "*fist<mode>2_<rounding>_1"
21931 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
21932 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
21933 FIST_ROUNDING))
21934 (clobber (reg:CC FLAGS_REG))]
21935 "TARGET_USE_FANCY_MATH_387
21936 && flag_unsafe_math_optimizations
21937 && ix86_pre_reload_split ()"
21938 "#"
21939 "&& 1"
21940 [(const_int 0)]
21941 {
21942 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
21943
21944 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
21945 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
21946
21947 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
21948 operands[2], operands[3]));
21949 DONE;
21950 }
21951 [(set_attr "type" "fistp")
21952 (set_attr "i387_cw" "<rounding>")
21953 (set_attr "mode" "<MODE>")])
21954
21955 (define_insn "fistdi2_<rounding>"
21956 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21957 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21958 FIST_ROUNDING))
21959 (use (match_operand:HI 2 "memory_operand" "m"))
21960 (use (match_operand:HI 3 "memory_operand" "m"))
21961 (clobber (match_scratch:XF 4 "=&f"))]
21962 "TARGET_USE_FANCY_MATH_387
21963 && flag_unsafe_math_optimizations"
21964 "* return output_fix_trunc (insn, operands, false);"
21965 [(set_attr "type" "fistp")
21966 (set_attr "i387_cw" "<rounding>")
21967 (set_attr "mode" "DI")])
21968
21969 (define_insn "fist<mode>2_<rounding>"
21970 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21971 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21972 FIST_ROUNDING))
21973 (use (match_operand:HI 2 "memory_operand" "m"))
21974 (use (match_operand:HI 3 "memory_operand" "m"))]
21975 "TARGET_USE_FANCY_MATH_387
21976 && flag_unsafe_math_optimizations"
21977 "* return output_fix_trunc (insn, operands, false);"
21978 [(set_attr "type" "fistp")
21979 (set_attr "i387_cw" "<rounding>")
21980 (set_attr "mode" "<MODE>")])
21981
21982 (define_expand "l<rounding_insn>xf<mode>2"
21983 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
21984 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
21985 FIST_ROUNDING))
21986 (clobber (reg:CC FLAGS_REG))])]
21987 "TARGET_USE_FANCY_MATH_387
21988 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
21989 && flag_unsafe_math_optimizations")
21990
21991 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
21992 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
21993 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
21994 FIST_ROUNDING))
21995 (clobber (reg:CC FLAGS_REG))])]
21996 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
21997 && (TARGET_SSE4_1 || !flag_trapping_math)"
21998 {
21999 if (TARGET_SSE4_1)
22000 {
22001 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
22002
22003 emit_insn (gen_sse4_1_round<MODEF:mode>2
22004 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
22005 | ROUND_NO_EXC)));
22006 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
22007 (operands[0], tmp));
22008 }
22009 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
22010 ix86_expand_lfloorceil (operands[0], operands[1], true);
22011 else if (ROUND_<ROUNDING> == ROUND_CEIL)
22012 ix86_expand_lfloorceil (operands[0], operands[1], false);
22013 else
22014 gcc_unreachable ();
22015
22016 DONE;
22017 })
22018
22019 (define_insn "fxam<mode>2_i387"
22020 [(set (match_operand:HI 0 "register_operand" "=a")
22021 (unspec:HI
22022 [(match_operand:X87MODEF 1 "register_operand" "f")]
22023 UNSPEC_FXAM))]
22024 "TARGET_USE_FANCY_MATH_387"
22025 "fxam\n\tfnstsw\t%0"
22026 [(set_attr "type" "multi")
22027 (set_attr "length" "4")
22028 (set_attr "unit" "i387")
22029 (set_attr "mode" "<MODE>")])
22030
22031 (define_expand "signbittf2"
22032 [(use (match_operand:SI 0 "register_operand"))
22033 (use (match_operand:TF 1 "register_operand"))]
22034 "TARGET_SSE"
22035 {
22036 if (TARGET_SSE4_1)
22037 {
22038 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
22039 rtx scratch = gen_reg_rtx (QImode);
22040
22041 emit_insn (gen_ptesttf2 (operands[1], mask));
22042 ix86_expand_setcc (scratch, NE,
22043 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
22044
22045 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
22046 }
22047 else
22048 {
22049 emit_insn (gen_sse_movmskps (operands[0],
22050 gen_lowpart (V4SFmode, operands[1])));
22051 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
22052 }
22053 DONE;
22054 })
22055
22056 (define_expand "signbitxf2"
22057 [(use (match_operand:SI 0 "register_operand"))
22058 (use (match_operand:XF 1 "register_operand"))]
22059 "TARGET_USE_FANCY_MATH_387"
22060 {
22061 rtx scratch = gen_reg_rtx (HImode);
22062
22063 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
22064 emit_insn (gen_andsi3 (operands[0],
22065 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22066 DONE;
22067 })
22068
22069 (define_insn "movmsk_df"
22070 [(set (match_operand:SI 0 "register_operand" "=r")
22071 (unspec:SI
22072 [(match_operand:DF 1 "register_operand" "x")]
22073 UNSPEC_MOVMSK))]
22074 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
22075 "%vmovmskpd\t{%1, %0|%0, %1}"
22076 [(set_attr "type" "ssemov")
22077 (set_attr "prefix" "maybe_vex")
22078 (set_attr "mode" "DF")])
22079
22080 ;; Use movmskpd in SSE mode to avoid store forwarding stall
22081 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
22082 (define_expand "signbitdf2"
22083 [(use (match_operand:SI 0 "register_operand"))
22084 (use (match_operand:DF 1 "register_operand"))]
22085 "TARGET_USE_FANCY_MATH_387
22086 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
22087 {
22088 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
22089 {
22090 emit_insn (gen_movmsk_df (operands[0], operands[1]));
22091 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
22092 }
22093 else
22094 {
22095 rtx scratch = gen_reg_rtx (HImode);
22096
22097 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
22098 emit_insn (gen_andsi3 (operands[0],
22099 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22100 }
22101 DONE;
22102 })
22103
22104 (define_expand "signbitsf2"
22105 [(use (match_operand:SI 0 "register_operand"))
22106 (use (match_operand:SF 1 "register_operand"))]
22107 "TARGET_USE_FANCY_MATH_387
22108 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
22109 {
22110 rtx scratch = gen_reg_rtx (HImode);
22111
22112 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
22113 emit_insn (gen_andsi3 (operands[0],
22114 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
22115 DONE;
22116 })
22117 \f
22118 ;; Block operation instructions
22119
22120 (define_insn "cld"
22121 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
22122 ""
22123 "cld"
22124 [(set_attr "length" "1")
22125 (set_attr "length_immediate" "0")
22126 (set_attr "modrm" "0")])
22127
22128 (define_expand "cpymem<mode>"
22129 [(use (match_operand:BLK 0 "memory_operand"))
22130 (use (match_operand:BLK 1 "memory_operand"))
22131 (use (match_operand:SWI48 2 "nonmemory_operand"))
22132 (use (match_operand:SWI48 3 "const_int_operand"))
22133 (use (match_operand:SI 4 "const_int_operand"))
22134 (use (match_operand:SI 5 "const_int_operand"))
22135 (use (match_operand:SI 6 ""))
22136 (use (match_operand:SI 7 ""))
22137 (use (match_operand:SI 8 ""))]
22138 ""
22139 {
22140 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22141 operands[2], NULL, operands[3],
22142 operands[4], operands[5],
22143 operands[6], operands[7],
22144 operands[8], false))
22145 DONE;
22146 else
22147 FAIL;
22148 })
22149
22150 ;; Most CPUs don't like single string operations
22151 ;; Handle this case here to simplify previous expander.
22152
22153 (define_expand "strmov"
22154 [(set (match_dup 4) (match_operand 3 "memory_operand"))
22155 (set (match_operand 1 "memory_operand") (match_dup 4))
22156 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22157 (clobber (reg:CC FLAGS_REG))])
22158 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22159 (clobber (reg:CC FLAGS_REG))])]
22160 ""
22161 {
22162 /* Can't use this for non-default address spaces. */
22163 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22164 FAIL;
22165
22166 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22167
22168 /* If .md ever supports :P for Pmode, these can be directly
22169 in the pattern above. */
22170 operands[5] = plus_constant (Pmode, operands[0], piece_size);
22171 operands[6] = plus_constant (Pmode, operands[2], piece_size);
22172
22173 /* Can't use this if the user has appropriated esi or edi. */
22174 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22175 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22176 {
22177 emit_insn (gen_strmov_singleop (operands[0], operands[1],
22178 operands[2], operands[3],
22179 operands[5], operands[6]));
22180 DONE;
22181 }
22182
22183 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22184 })
22185
22186 (define_expand "strmov_singleop"
22187 [(parallel [(set (match_operand 1 "memory_operand")
22188 (match_operand 3 "memory_operand"))
22189 (set (match_operand 0 "register_operand")
22190 (match_operand 4))
22191 (set (match_operand 2 "register_operand")
22192 (match_operand 5))])]
22193 ""
22194 {
22195 if (TARGET_CLD)
22196 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22197 })
22198
22199 (define_insn "*strmovdi_rex_1"
22200 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22201 (mem:DI (match_operand:P 3 "register_operand" "1")))
22202 (set (match_operand:P 0 "register_operand" "=D")
22203 (plus:P (match_dup 2)
22204 (const_int 8)))
22205 (set (match_operand:P 1 "register_operand" "=S")
22206 (plus:P (match_dup 3)
22207 (const_int 8)))]
22208 "TARGET_64BIT
22209 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22210 && ix86_check_no_addr_space (insn)"
22211 "%^movsq"
22212 [(set_attr "type" "str")
22213 (set_attr "memory" "both")
22214 (set_attr "mode" "DI")])
22215
22216 (define_insn "*strmovsi_1"
22217 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22218 (mem:SI (match_operand:P 3 "register_operand" "1")))
22219 (set (match_operand:P 0 "register_operand" "=D")
22220 (plus:P (match_dup 2)
22221 (const_int 4)))
22222 (set (match_operand:P 1 "register_operand" "=S")
22223 (plus:P (match_dup 3)
22224 (const_int 4)))]
22225 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22226 && ix86_check_no_addr_space (insn)"
22227 "%^movs{l|d}"
22228 [(set_attr "type" "str")
22229 (set_attr "memory" "both")
22230 (set_attr "mode" "SI")])
22231
22232 (define_insn "*strmovhi_1"
22233 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22234 (mem:HI (match_operand:P 3 "register_operand" "1")))
22235 (set (match_operand:P 0 "register_operand" "=D")
22236 (plus:P (match_dup 2)
22237 (const_int 2)))
22238 (set (match_operand:P 1 "register_operand" "=S")
22239 (plus:P (match_dup 3)
22240 (const_int 2)))]
22241 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22242 && ix86_check_no_addr_space (insn)"
22243 "%^movsw"
22244 [(set_attr "type" "str")
22245 (set_attr "memory" "both")
22246 (set_attr "mode" "HI")])
22247
22248 (define_insn "*strmovqi_1"
22249 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22250 (mem:QI (match_operand:P 3 "register_operand" "1")))
22251 (set (match_operand:P 0 "register_operand" "=D")
22252 (plus:P (match_dup 2)
22253 (const_int 1)))
22254 (set (match_operand:P 1 "register_operand" "=S")
22255 (plus:P (match_dup 3)
22256 (const_int 1)))]
22257 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22258 && ix86_check_no_addr_space (insn)"
22259 "%^movsb"
22260 [(set_attr "type" "str")
22261 (set_attr "memory" "both")
22262 (set (attr "prefix_rex")
22263 (if_then_else
22264 (match_test "<P:MODE>mode == DImode")
22265 (const_string "0")
22266 (const_string "*")))
22267 (set_attr "mode" "QI")])
22268
22269 (define_expand "rep_mov"
22270 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22271 (set (match_operand 0 "register_operand")
22272 (match_operand 5))
22273 (set (match_operand 2 "register_operand")
22274 (match_operand 6))
22275 (set (match_operand 1 "memory_operand")
22276 (match_operand 3 "memory_operand"))
22277 (use (match_dup 4))])]
22278 ""
22279 {
22280 if (TARGET_CLD)
22281 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22282 })
22283
22284 (define_insn "*rep_movdi_rex64"
22285 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22286 (set (match_operand:P 0 "register_operand" "=D")
22287 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22288 (const_int 3))
22289 (match_operand:P 3 "register_operand" "0")))
22290 (set (match_operand:P 1 "register_operand" "=S")
22291 (plus:P (ashift:P (match_dup 5) (const_int 3))
22292 (match_operand:P 4 "register_operand" "1")))
22293 (set (mem:BLK (match_dup 3))
22294 (mem:BLK (match_dup 4)))
22295 (use (match_dup 5))]
22296 "TARGET_64BIT
22297 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22298 && ix86_check_no_addr_space (insn)"
22299 "%^rep{%;} movsq"
22300 [(set_attr "type" "str")
22301 (set_attr "prefix_rep" "1")
22302 (set_attr "memory" "both")
22303 (set_attr "mode" "DI")])
22304
22305 (define_insn "*rep_movsi"
22306 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22307 (set (match_operand:P 0 "register_operand" "=D")
22308 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22309 (const_int 2))
22310 (match_operand:P 3 "register_operand" "0")))
22311 (set (match_operand:P 1 "register_operand" "=S")
22312 (plus:P (ashift:P (match_dup 5) (const_int 2))
22313 (match_operand:P 4 "register_operand" "1")))
22314 (set (mem:BLK (match_dup 3))
22315 (mem:BLK (match_dup 4)))
22316 (use (match_dup 5))]
22317 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22318 && ix86_check_no_addr_space (insn)"
22319 "%^rep{%;} movs{l|d}"
22320 [(set_attr "type" "str")
22321 (set_attr "prefix_rep" "1")
22322 (set_attr "memory" "both")
22323 (set_attr "mode" "SI")])
22324
22325 (define_insn "*rep_movqi"
22326 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22327 (set (match_operand:P 0 "register_operand" "=D")
22328 (plus:P (match_operand:P 3 "register_operand" "0")
22329 (match_operand:P 5 "register_operand" "2")))
22330 (set (match_operand:P 1 "register_operand" "=S")
22331 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22332 (set (mem:BLK (match_dup 3))
22333 (mem:BLK (match_dup 4)))
22334 (use (match_dup 5))]
22335 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22336 && ix86_check_no_addr_space (insn)"
22337 "%^rep{%;} movsb"
22338 [(set_attr "type" "str")
22339 (set_attr "prefix_rep" "1")
22340 (set_attr "memory" "both")
22341 (set_attr "mode" "QI")])
22342
22343 (define_expand "setmem<mode>"
22344 [(use (match_operand:BLK 0 "memory_operand"))
22345 (use (match_operand:SWI48 1 "nonmemory_operand"))
22346 (use (match_operand:QI 2 "nonmemory_operand"))
22347 (use (match_operand 3 "const_int_operand"))
22348 (use (match_operand:SI 4 "const_int_operand"))
22349 (use (match_operand:SI 5 "const_int_operand"))
22350 (use (match_operand:SI 6 ""))
22351 (use (match_operand:SI 7 ""))
22352 (use (match_operand:SI 8 ""))]
22353 ""
22354 {
22355 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22356 operands[1], operands[2],
22357 operands[3], operands[4],
22358 operands[5], operands[6],
22359 operands[7], operands[8], true))
22360 DONE;
22361 else
22362 FAIL;
22363 })
22364
22365 ;; Most CPUs don't like single string operations
22366 ;; Handle this case here to simplify previous expander.
22367
22368 (define_expand "strset"
22369 [(set (match_operand 1 "memory_operand")
22370 (match_operand 2 "register_operand"))
22371 (parallel [(set (match_operand 0 "register_operand")
22372 (match_dup 3))
22373 (clobber (reg:CC FLAGS_REG))])]
22374 ""
22375 {
22376 /* Can't use this for non-default address spaces. */
22377 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22378 FAIL;
22379
22380 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22381 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22382
22383 /* If .md ever supports :P for Pmode, this can be directly
22384 in the pattern above. */
22385 operands[3] = plus_constant (Pmode, operands[0],
22386 GET_MODE_SIZE (GET_MODE (operands[2])));
22387
22388 /* Can't use this if the user has appropriated eax or edi. */
22389 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22390 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22391 {
22392 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22393 operands[3]));
22394 DONE;
22395 }
22396 })
22397
22398 (define_expand "strset_singleop"
22399 [(parallel [(set (match_operand 1 "memory_operand")
22400 (match_operand 2 "register_operand"))
22401 (set (match_operand 0 "register_operand")
22402 (match_operand 3))
22403 (unspec [(const_int 0)] UNSPEC_STOS)])]
22404 ""
22405 {
22406 if (TARGET_CLD)
22407 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22408 })
22409
22410 (define_insn "*strsetdi_rex_1"
22411 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22412 (match_operand:DI 2 "register_operand" "a"))
22413 (set (match_operand:P 0 "register_operand" "=D")
22414 (plus:P (match_dup 1)
22415 (const_int 8)))
22416 (unspec [(const_int 0)] UNSPEC_STOS)]
22417 "TARGET_64BIT
22418 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22419 && ix86_check_no_addr_space (insn)"
22420 "%^stosq"
22421 [(set_attr "type" "str")
22422 (set_attr "memory" "store")
22423 (set_attr "mode" "DI")])
22424
22425 (define_insn "*strsetsi_1"
22426 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22427 (match_operand:SI 2 "register_operand" "a"))
22428 (set (match_operand:P 0 "register_operand" "=D")
22429 (plus:P (match_dup 1)
22430 (const_int 4)))
22431 (unspec [(const_int 0)] UNSPEC_STOS)]
22432 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22433 && ix86_check_no_addr_space (insn)"
22434 "%^stos{l|d}"
22435 [(set_attr "type" "str")
22436 (set_attr "memory" "store")
22437 (set_attr "mode" "SI")])
22438
22439 (define_insn "*strsethi_1"
22440 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22441 (match_operand:HI 2 "register_operand" "a"))
22442 (set (match_operand:P 0 "register_operand" "=D")
22443 (plus:P (match_dup 1)
22444 (const_int 2)))
22445 (unspec [(const_int 0)] UNSPEC_STOS)]
22446 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22447 && ix86_check_no_addr_space (insn)"
22448 "%^stosw"
22449 [(set_attr "type" "str")
22450 (set_attr "memory" "store")
22451 (set_attr "mode" "HI")])
22452
22453 (define_insn "*strsetqi_1"
22454 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22455 (match_operand:QI 2 "register_operand" "a"))
22456 (set (match_operand:P 0 "register_operand" "=D")
22457 (plus:P (match_dup 1)
22458 (const_int 1)))
22459 (unspec [(const_int 0)] UNSPEC_STOS)]
22460 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22461 && ix86_check_no_addr_space (insn)"
22462 "%^stosb"
22463 [(set_attr "type" "str")
22464 (set_attr "memory" "store")
22465 (set (attr "prefix_rex")
22466 (if_then_else
22467 (match_test "<P:MODE>mode == DImode")
22468 (const_string "0")
22469 (const_string "*")))
22470 (set_attr "mode" "QI")])
22471
22472 (define_expand "rep_stos"
22473 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22474 (set (match_operand 0 "register_operand")
22475 (match_operand 4))
22476 (set (match_operand 2 "memory_operand") (const_int 0))
22477 (use (match_operand 3 "register_operand"))
22478 (use (match_dup 1))])]
22479 ""
22480 {
22481 if (TARGET_CLD)
22482 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22483 })
22484
22485 (define_insn "*rep_stosdi_rex64"
22486 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22487 (set (match_operand:P 0 "register_operand" "=D")
22488 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22489 (const_int 3))
22490 (match_operand:P 3 "register_operand" "0")))
22491 (set (mem:BLK (match_dup 3))
22492 (const_int 0))
22493 (use (match_operand:DI 2 "register_operand" "a"))
22494 (use (match_dup 4))]
22495 "TARGET_64BIT
22496 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22497 && ix86_check_no_addr_space (insn)"
22498 "%^rep{%;} stosq"
22499 [(set_attr "type" "str")
22500 (set_attr "prefix_rep" "1")
22501 (set_attr "memory" "store")
22502 (set_attr "mode" "DI")])
22503
22504 (define_insn "*rep_stossi"
22505 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22506 (set (match_operand:P 0 "register_operand" "=D")
22507 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22508 (const_int 2))
22509 (match_operand:P 3 "register_operand" "0")))
22510 (set (mem:BLK (match_dup 3))
22511 (const_int 0))
22512 (use (match_operand:SI 2 "register_operand" "a"))
22513 (use (match_dup 4))]
22514 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22515 && ix86_check_no_addr_space (insn)"
22516 "%^rep{%;} stos{l|d}"
22517 [(set_attr "type" "str")
22518 (set_attr "prefix_rep" "1")
22519 (set_attr "memory" "store")
22520 (set_attr "mode" "SI")])
22521
22522 (define_insn "*rep_stosqi"
22523 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22524 (set (match_operand:P 0 "register_operand" "=D")
22525 (plus:P (match_operand:P 3 "register_operand" "0")
22526 (match_operand:P 4 "register_operand" "1")))
22527 (set (mem:BLK (match_dup 3))
22528 (const_int 0))
22529 (use (match_operand:QI 2 "register_operand" "a"))
22530 (use (match_dup 4))]
22531 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22532 && ix86_check_no_addr_space (insn)"
22533 "%^rep{%;} stosb"
22534 [(set_attr "type" "str")
22535 (set_attr "prefix_rep" "1")
22536 (set_attr "memory" "store")
22537 (set (attr "prefix_rex")
22538 (if_then_else
22539 (match_test "<P:MODE>mode == DImode")
22540 (const_string "0")
22541 (const_string "*")))
22542 (set_attr "mode" "QI")])
22543
22544 (define_expand "cmpmemsi"
22545 [(set (match_operand:SI 0 "register_operand" "")
22546 (compare:SI (match_operand:BLK 1 "memory_operand" "")
22547 (match_operand:BLK 2 "memory_operand" "") ) )
22548 (use (match_operand 3 "general_operand"))
22549 (use (match_operand 4 "immediate_operand"))]
22550 ""
22551 {
22552 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22553 operands[2], operands[3],
22554 operands[4], false))
22555 DONE;
22556 else
22557 FAIL;
22558 })
22559
22560 (define_expand "cmpstrnsi"
22561 [(set (match_operand:SI 0 "register_operand")
22562 (compare:SI (match_operand:BLK 1 "general_operand")
22563 (match_operand:BLK 2 "general_operand")))
22564 (use (match_operand 3 "general_operand"))
22565 (use (match_operand 4 "immediate_operand"))]
22566 ""
22567 {
22568 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22569 operands[2], operands[3],
22570 operands[4], true))
22571 DONE;
22572 else
22573 FAIL;
22574 })
22575
22576 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
22577
22578 (define_expand "cmpintqi"
22579 [(set (match_dup 1)
22580 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22581 (set (match_dup 2)
22582 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22583 (parallel [(set (match_operand:QI 0 "register_operand")
22584 (minus:QI (match_dup 1)
22585 (match_dup 2)))
22586 (clobber (reg:CC FLAGS_REG))])]
22587 ""
22588 {
22589 operands[1] = gen_reg_rtx (QImode);
22590 operands[2] = gen_reg_rtx (QImode);
22591 })
22592
22593 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
22594 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
22595
22596 (define_expand "cmpstrnqi_nz_1"
22597 [(parallel [(set (reg:CC FLAGS_REG)
22598 (compare:CC (match_operand 4 "memory_operand")
22599 (match_operand 5 "memory_operand")))
22600 (use (match_operand 2 "register_operand"))
22601 (use (match_operand:SI 3 "immediate_operand"))
22602 (clobber (match_operand 0 "register_operand"))
22603 (clobber (match_operand 1 "register_operand"))
22604 (clobber (match_dup 2))])]
22605 ""
22606 {
22607 if (TARGET_CLD)
22608 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22609 })
22610
22611 (define_insn "*cmpstrnqi_nz_1"
22612 [(set (reg:CC FLAGS_REG)
22613 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22614 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
22615 (use (match_operand:P 6 "register_operand" "2"))
22616 (use (match_operand:SI 3 "immediate_operand" "i"))
22617 (clobber (match_operand:P 0 "register_operand" "=S"))
22618 (clobber (match_operand:P 1 "register_operand" "=D"))
22619 (clobber (match_operand:P 2 "register_operand" "=c"))]
22620 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22621 && ix86_check_no_addr_space (insn)"
22622 "%^repz{%;} cmpsb"
22623 [(set_attr "type" "str")
22624 (set_attr "mode" "QI")
22625 (set (attr "prefix_rex")
22626 (if_then_else
22627 (match_test "<P:MODE>mode == DImode")
22628 (const_string "0")
22629 (const_string "*")))
22630 (set_attr "prefix_rep" "1")])
22631
22632 ;; The same, but the count is not known to not be zero.
22633
22634 (define_expand "cmpstrnqi_1"
22635 [(parallel [(set (reg:CC FLAGS_REG)
22636 (if_then_else:CC (ne (match_operand 2 "register_operand")
22637 (const_int 0))
22638 (compare:CC (match_operand 4 "memory_operand")
22639 (match_operand 5 "memory_operand"))
22640 (const_int 0)))
22641 (use (match_operand:SI 3 "immediate_operand"))
22642 (use (reg:CC FLAGS_REG))
22643 (clobber (match_operand 0 "register_operand"))
22644 (clobber (match_operand 1 "register_operand"))
22645 (clobber (match_dup 2))])]
22646 ""
22647 {
22648 if (TARGET_CLD)
22649 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22650 })
22651
22652 (define_insn "*cmpstrnqi_1"
22653 [(set (reg:CC FLAGS_REG)
22654 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
22655 (const_int 0))
22656 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22657 (mem:BLK (match_operand:P 5 "register_operand" "1")))
22658 (const_int 0)))
22659 (use (match_operand:SI 3 "immediate_operand" "i"))
22660 (use (reg:CC FLAGS_REG))
22661 (clobber (match_operand:P 0 "register_operand" "=S"))
22662 (clobber (match_operand:P 1 "register_operand" "=D"))
22663 (clobber (match_operand:P 2 "register_operand" "=c"))]
22664 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22665 && ix86_check_no_addr_space (insn)"
22666 "%^repz{%;} cmpsb"
22667 [(set_attr "type" "str")
22668 (set_attr "mode" "QI")
22669 (set (attr "prefix_rex")
22670 (if_then_else
22671 (match_test "<P:MODE>mode == DImode")
22672 (const_string "0")
22673 (const_string "*")))
22674 (set_attr "prefix_rep" "1")])
22675
22676 (define_expand "strlen<mode>"
22677 [(set (match_operand:P 0 "register_operand")
22678 (unspec:P [(match_operand:BLK 1 "general_operand")
22679 (match_operand:QI 2 "immediate_operand")
22680 (match_operand 3 "immediate_operand")]
22681 UNSPEC_SCAS))]
22682 ""
22683 {
22684 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
22685 DONE;
22686 else
22687 FAIL;
22688 })
22689
22690 (define_expand "strlenqi_1"
22691 [(parallel [(set (match_operand 0 "register_operand")
22692 (match_operand 2))
22693 (clobber (match_operand 1 "register_operand"))
22694 (clobber (reg:CC FLAGS_REG))])]
22695 ""
22696 {
22697 if (TARGET_CLD)
22698 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22699 })
22700
22701 (define_insn "*strlenqi_1"
22702 [(set (match_operand:P 0 "register_operand" "=&c")
22703 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
22704 (match_operand:QI 2 "register_operand" "a")
22705 (match_operand:P 3 "immediate_operand" "i")
22706 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
22707 (clobber (match_operand:P 1 "register_operand" "=D"))
22708 (clobber (reg:CC FLAGS_REG))]
22709 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22710 && ix86_check_no_addr_space (insn)"
22711 "%^repnz{%;} scasb"
22712 [(set_attr "type" "str")
22713 (set_attr "mode" "QI")
22714 (set (attr "prefix_rex")
22715 (if_then_else
22716 (match_test "<P:MODE>mode == DImode")
22717 (const_string "0")
22718 (const_string "*")))
22719 (set_attr "prefix_rep" "1")])
22720
22721 ;; Peephole optimizations to clean up after cmpstrn*. This should be
22722 ;; handled in combine, but it is not currently up to the task.
22723 ;; When used for their truth value, the cmpstrn* expanders generate
22724 ;; code like this:
22725 ;;
22726 ;; repz cmpsb
22727 ;; seta %al
22728 ;; setb %dl
22729 ;; cmpb %al, %dl
22730 ;; jcc label
22731 ;;
22732 ;; The intermediate three instructions are unnecessary.
22733
22734 ;; This one handles cmpstrn*_nz_1...
22735 (define_peephole2
22736 [(parallel[
22737 (set (reg:CC FLAGS_REG)
22738 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22739 (mem:BLK (match_operand 5 "register_operand"))))
22740 (use (match_operand 6 "register_operand"))
22741 (use (match_operand:SI 3 "immediate_operand"))
22742 (clobber (match_operand 0 "register_operand"))
22743 (clobber (match_operand 1 "register_operand"))
22744 (clobber (match_operand 2 "register_operand"))])
22745 (set (match_operand:QI 7 "register_operand")
22746 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22747 (set (match_operand:QI 8 "register_operand")
22748 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22749 (set (reg FLAGS_REG)
22750 (compare (match_dup 7) (match_dup 8)))
22751 ]
22752 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22753 [(parallel[
22754 (set (reg:CC FLAGS_REG)
22755 (compare:CC (mem:BLK (match_dup 4))
22756 (mem:BLK (match_dup 5))))
22757 (use (match_dup 6))
22758 (use (match_dup 3))
22759 (clobber (match_dup 0))
22760 (clobber (match_dup 1))
22761 (clobber (match_dup 2))])])
22762
22763 ;; ...and this one handles cmpstrn*_1.
22764 (define_peephole2
22765 [(parallel[
22766 (set (reg:CC FLAGS_REG)
22767 (if_then_else:CC (ne (match_operand 6 "register_operand")
22768 (const_int 0))
22769 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22770 (mem:BLK (match_operand 5 "register_operand")))
22771 (const_int 0)))
22772 (use (match_operand:SI 3 "immediate_operand"))
22773 (use (reg:CC FLAGS_REG))
22774 (clobber (match_operand 0 "register_operand"))
22775 (clobber (match_operand 1 "register_operand"))
22776 (clobber (match_operand 2 "register_operand"))])
22777 (set (match_operand:QI 7 "register_operand")
22778 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22779 (set (match_operand:QI 8 "register_operand")
22780 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22781 (set (reg FLAGS_REG)
22782 (compare (match_dup 7) (match_dup 8)))
22783 ]
22784 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22785 [(parallel[
22786 (set (reg:CC FLAGS_REG)
22787 (if_then_else:CC (ne (match_dup 6)
22788 (const_int 0))
22789 (compare:CC (mem:BLK (match_dup 4))
22790 (mem:BLK (match_dup 5)))
22791 (const_int 0)))
22792 (use (match_dup 3))
22793 (use (reg:CC FLAGS_REG))
22794 (clobber (match_dup 0))
22795 (clobber (match_dup 1))
22796 (clobber (match_dup 2))])])
22797 \f
22798 ;; Conditional move instructions.
22799
22800 (define_expand "mov<mode>cc"
22801 [(set (match_operand:SWIM 0 "register_operand")
22802 (if_then_else:SWIM (match_operand 1 "comparison_operator")
22803 (match_operand:SWIM 2 "<general_operand>")
22804 (match_operand:SWIM 3 "<general_operand>")))]
22805 ""
22806 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
22807
22808 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
22809 ;; the register first winds up with `sbbl $0,reg', which is also weird.
22810 ;; So just document what we're doing explicitly.
22811
22812 (define_expand "x86_mov<mode>cc_0_m1"
22813 [(parallel
22814 [(set (match_operand:SWI48 0 "register_operand")
22815 (if_then_else:SWI48
22816 (match_operator:SWI48 2 "ix86_carry_flag_operator"
22817 [(match_operand 1 "flags_reg_operand")
22818 (const_int 0)])
22819 (const_int -1)
22820 (const_int 0)))
22821 (clobber (reg:CC FLAGS_REG))])])
22822
22823 (define_insn "*x86_mov<mode>cc_0_m1"
22824 [(set (match_operand:SWI48 0 "register_operand" "=r")
22825 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
22826 [(reg FLAGS_REG) (const_int 0)])
22827 (const_int -1)
22828 (const_int 0)))
22829 (clobber (reg:CC FLAGS_REG))]
22830 ""
22831 "sbb{<imodesuffix>}\t%0, %0"
22832 [(set_attr "type" "alu1")
22833 (set_attr "use_carry" "1")
22834 (set_attr "pent_pair" "pu")
22835 (set_attr "mode" "<MODE>")
22836 (set_attr "length_immediate" "0")])
22837
22838 (define_insn "*x86_mov<mode>cc_0_m1_se"
22839 [(set (match_operand:SWI48 0 "register_operand" "=r")
22840 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
22841 [(reg FLAGS_REG) (const_int 0)])
22842 (const_int 1)
22843 (const_int 0)))
22844 (clobber (reg:CC FLAGS_REG))]
22845 ""
22846 "sbb{<imodesuffix>}\t%0, %0"
22847 [(set_attr "type" "alu1")
22848 (set_attr "use_carry" "1")
22849 (set_attr "pent_pair" "pu")
22850 (set_attr "mode" "<MODE>")
22851 (set_attr "length_immediate" "0")])
22852
22853 (define_insn "*x86_mov<mode>cc_0_m1_neg"
22854 [(set (match_operand:SWI 0 "register_operand" "=<r>")
22855 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
22856 [(reg FLAGS_REG) (const_int 0)])))
22857 (clobber (reg:CC FLAGS_REG))]
22858 ""
22859 "sbb{<imodesuffix>}\t%0, %0"
22860 [(set_attr "type" "alu1")
22861 (set_attr "use_carry" "1")
22862 (set_attr "pent_pair" "pu")
22863 (set_attr "mode" "<MODE>")
22864 (set_attr "length_immediate" "0")])
22865
22866 (define_expand "x86_mov<mode>cc_0_m1_neg"
22867 [(parallel
22868 [(set (match_operand:SWI48 0 "register_operand")
22869 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
22870 (clobber (reg:CC FLAGS_REG))])])
22871
22872 (define_split
22873 [(set (match_operand:SWI48 0 "register_operand")
22874 (neg:SWI48
22875 (leu:SWI48
22876 (match_operand 1 "int_nonimmediate_operand")
22877 (match_operand 2 "const_int_operand"))))]
22878 "x86_64_immediate_operand (operands[2], VOIDmode)
22879 && INTVAL (operands[2]) != -1
22880 && INTVAL (operands[2]) != 2147483647"
22881 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
22882 (set (match_dup 0)
22883 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
22884 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
22885
22886 (define_split
22887 [(set (match_operand:SWI 0 "register_operand")
22888 (neg:SWI
22889 (eq:SWI
22890 (match_operand 1 "int_nonimmediate_operand")
22891 (const_int 0))))]
22892 ""
22893 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
22894 (set (match_dup 0)
22895 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
22896
22897 (define_split
22898 [(set (match_operand:SWI 0 "register_operand")
22899 (neg:SWI
22900 (ne:SWI
22901 (match_operand 1 "int_nonimmediate_operand")
22902 (const_int 0))))]
22903 ""
22904 [(set (reg:CCC FLAGS_REG)
22905 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
22906 (set (match_dup 0)
22907 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
22908
22909 (define_insn "*mov<mode>cc_noc"
22910 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
22911 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22912 [(reg FLAGS_REG) (const_int 0)])
22913 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
22914 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
22915 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22916 "@
22917 cmov%O2%C1\t{%2, %0|%0, %2}
22918 cmov%O2%c1\t{%3, %0|%0, %3}"
22919 [(set_attr "type" "icmov")
22920 (set_attr "mode" "<MODE>")])
22921
22922 (define_insn "*movsicc_noc_zext"
22923 [(set (match_operand:DI 0 "register_operand" "=r,r")
22924 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
22925 [(reg FLAGS_REG) (const_int 0)])
22926 (zero_extend:DI
22927 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
22928 (zero_extend:DI
22929 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
22930 "TARGET_64BIT
22931 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22932 "@
22933 cmov%O2%C1\t{%2, %k0|%k0, %2}
22934 cmov%O2%c1\t{%3, %k0|%k0, %3}"
22935 [(set_attr "type" "icmov")
22936 (set_attr "mode" "SI")])
22937
22938 (define_insn "*movsicc_noc_zext_1"
22939 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
22940 (zero_extend:DI
22941 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
22942 [(reg FLAGS_REG) (const_int 0)])
22943 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
22944 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
22945 "TARGET_64BIT
22946 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22947 "@
22948 cmov%O2%C1\t{%2, %k0|%k0, %2}
22949 cmov%O2%c1\t{%3, %k0|%k0, %3}"
22950 [(set_attr "type" "icmov")
22951 (set_attr "mode" "SI")])
22952
22953
22954 ;; Don't do conditional moves with memory inputs. This splitter helps
22955 ;; register starved x86_32 by forcing inputs into registers before reload.
22956 (define_split
22957 [(set (match_operand:SWI248 0 "register_operand")
22958 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22959 [(reg FLAGS_REG) (const_int 0)])
22960 (match_operand:SWI248 2 "nonimmediate_operand")
22961 (match_operand:SWI248 3 "nonimmediate_operand")))]
22962 "!TARGET_64BIT && TARGET_CMOVE
22963 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22964 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22965 && can_create_pseudo_p ()
22966 && optimize_insn_for_speed_p ()"
22967 [(set (match_dup 0)
22968 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
22969 {
22970 operands[2] = force_reg (<MODE>mode, operands[2]);
22971 operands[3] = force_reg (<MODE>mode, operands[3]);
22972 })
22973
22974 (define_insn "*movqicc_noc"
22975 [(set (match_operand:QI 0 "register_operand" "=r,r")
22976 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
22977 [(reg FLAGS_REG) (const_int 0)])
22978 (match_operand:QI 2 "register_operand" "r,0")
22979 (match_operand:QI 3 "register_operand" "0,r")))]
22980 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
22981 "#"
22982 [(set_attr "type" "icmov")
22983 (set_attr "mode" "QI")])
22984
22985 (define_split
22986 [(set (match_operand:SWI12 0 "register_operand")
22987 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
22988 [(reg FLAGS_REG) (const_int 0)])
22989 (match_operand:SWI12 2 "register_operand")
22990 (match_operand:SWI12 3 "register_operand")))]
22991 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
22992 && reload_completed"
22993 [(set (match_dup 0)
22994 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
22995 {
22996 operands[0] = gen_lowpart (SImode, operands[0]);
22997 operands[2] = gen_lowpart (SImode, operands[2]);
22998 operands[3] = gen_lowpart (SImode, operands[3]);
22999 })
23000
23001 ;; Don't do conditional moves with memory inputs
23002 (define_peephole2
23003 [(match_scratch:SWI248 4 "r")
23004 (set (match_operand:SWI248 0 "register_operand")
23005 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
23006 [(reg FLAGS_REG) (const_int 0)])
23007 (match_operand:SWI248 2 "nonimmediate_operand")
23008 (match_operand:SWI248 3 "nonimmediate_operand")))]
23009 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23010 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23011 && optimize_insn_for_speed_p ()"
23012 [(set (match_dup 4) (match_dup 5))
23013 (set (match_dup 0)
23014 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
23015 {
23016 if (MEM_P (operands[2]))
23017 {
23018 operands[5] = operands[2];
23019 operands[2] = operands[4];
23020 }
23021 else if (MEM_P (operands[3]))
23022 {
23023 operands[5] = operands[3];
23024 operands[3] = operands[4];
23025 }
23026 else
23027 gcc_unreachable ();
23028 })
23029
23030 (define_peephole2
23031 [(match_scratch:SI 4 "r")
23032 (set (match_operand:DI 0 "register_operand")
23033 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
23034 [(reg FLAGS_REG) (const_int 0)])
23035 (zero_extend:DI
23036 (match_operand:SI 2 "nonimmediate_operand"))
23037 (zero_extend:DI
23038 (match_operand:SI 3 "nonimmediate_operand"))))]
23039 "TARGET_64BIT
23040 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23041 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23042 && optimize_insn_for_speed_p ()"
23043 [(set (match_dup 4) (match_dup 5))
23044 (set (match_dup 0)
23045 (if_then_else:DI (match_dup 1)
23046 (zero_extend:DI (match_dup 2))
23047 (zero_extend:DI (match_dup 3))))]
23048 {
23049 if (MEM_P (operands[2]))
23050 {
23051 operands[5] = operands[2];
23052 operands[2] = operands[4];
23053 }
23054 else if (MEM_P (operands[3]))
23055 {
23056 operands[5] = operands[3];
23057 operands[3] = operands[4];
23058 }
23059 else
23060 gcc_unreachable ();
23061 })
23062
23063 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
23064 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23065 (define_peephole2
23066 [(set (match_operand:SWI248 0 "general_reg_operand")
23067 (match_operand:SWI248 1 "general_reg_operand"))
23068 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23069 (set (match_dup 0) (match_operand:SWI248 6))])
23070 (set (match_operand:SWI248 2 "general_reg_operand")
23071 (match_operand:SWI248 3 "general_gr_operand"))
23072 (set (match_dup 0)
23073 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23074 [(reg FLAGS_REG) (const_int 0)])
23075 (match_dup 0)
23076 (match_dup 2)))]
23077 "TARGET_CMOVE
23078 && REGNO (operands[2]) != REGNO (operands[0])
23079 && REGNO (operands[2]) != REGNO (operands[1])
23080 && peep2_reg_dead_p (1, operands[1])
23081 && peep2_reg_dead_p (4, operands[2])
23082 && !reg_overlap_mentioned_p (operands[0], operands[3])"
23083 [(parallel [(set (match_dup 7) (match_dup 8))
23084 (set (match_dup 1) (match_dup 9))])
23085 (set (match_dup 0) (match_dup 3))
23086 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23087 (match_dup 1)
23088 (match_dup 0)))]
23089 {
23090 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
23091 operands[8]
23092 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23093 operands[9]
23094 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23095 })
23096
23097 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
23098 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
23099 (define_peephole2
23100 [(set (match_operand:SWI248 2 "general_reg_operand")
23101 (match_operand:SWI248 3 "general_gr_operand"))
23102 (set (match_operand:SWI248 0 "general_reg_operand")
23103 (match_operand:SWI248 1 "general_reg_operand"))
23104 (parallel [(set (reg FLAGS_REG) (match_operand 5))
23105 (set (match_dup 0) (match_operand:SWI248 6))])
23106 (set (match_dup 0)
23107 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
23108 [(reg FLAGS_REG) (const_int 0)])
23109 (match_dup 0)
23110 (match_dup 2)))]
23111 "TARGET_CMOVE
23112 && REGNO (operands[2]) != REGNO (operands[0])
23113 && REGNO (operands[2]) != REGNO (operands[1])
23114 && peep2_reg_dead_p (2, operands[1])
23115 && peep2_reg_dead_p (4, operands[2])
23116 && !reg_overlap_mentioned_p (operands[0], operands[3])
23117 && !reg_mentioned_p (operands[2], operands[6])"
23118 [(parallel [(set (match_dup 7) (match_dup 8))
23119 (set (match_dup 1) (match_dup 9))])
23120 (set (match_dup 0) (match_dup 3))
23121 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
23122 (match_dup 1)
23123 (match_dup 0)))]
23124 {
23125 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23126 operands[8]
23127 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23128 operands[9]
23129 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23130 })
23131
23132 (define_insn "movhf_mask"
23133 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23134 (unspec:HF
23135 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23136 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23137 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23138 UNSPEC_MOVCC_MASK))]
23139 "TARGET_AVX512FP16"
23140 "@
23141 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23142 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23143 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23144 [(set_attr "type" "ssemov")
23145 (set_attr "prefix" "evex")
23146 (set_attr "mode" "HF")])
23147
23148 (define_expand "movhfcc"
23149 [(set (match_operand:HF 0 "register_operand")
23150 (if_then_else:HF
23151 (match_operand 1 "comparison_operator")
23152 (match_operand:HF 2 "register_operand")
23153 (match_operand:HF 3 "register_operand")))]
23154 "TARGET_AVX512FP16"
23155 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23156
23157 (define_expand "mov<mode>cc"
23158 [(set (match_operand:X87MODEF 0 "register_operand")
23159 (if_then_else:X87MODEF
23160 (match_operand 1 "comparison_operator")
23161 (match_operand:X87MODEF 2 "register_operand")
23162 (match_operand:X87MODEF 3 "register_operand")))]
23163 "(TARGET_80387 && TARGET_CMOVE)
23164 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23165 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23166
23167 (define_insn "*movxfcc_1"
23168 [(set (match_operand:XF 0 "register_operand" "=f,f")
23169 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23170 [(reg FLAGS_REG) (const_int 0)])
23171 (match_operand:XF 2 "register_operand" "f,0")
23172 (match_operand:XF 3 "register_operand" "0,f")))]
23173 "TARGET_80387 && TARGET_CMOVE"
23174 "@
23175 fcmov%F1\t{%2, %0|%0, %2}
23176 fcmov%f1\t{%3, %0|%0, %3}"
23177 [(set_attr "type" "fcmov")
23178 (set_attr "mode" "XF")])
23179
23180 (define_insn "*movdfcc_1"
23181 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23182 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23183 [(reg FLAGS_REG) (const_int 0)])
23184 (match_operand:DF 2 "nonimmediate_operand"
23185 "f ,0,rm,0 ,rm,0")
23186 (match_operand:DF 3 "nonimmediate_operand"
23187 "0 ,f,0 ,rm,0, rm")))]
23188 "TARGET_80387 && TARGET_CMOVE
23189 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23190 "@
23191 fcmov%F1\t{%2, %0|%0, %2}
23192 fcmov%f1\t{%3, %0|%0, %3}
23193 #
23194 #
23195 cmov%O2%C1\t{%2, %0|%0, %2}
23196 cmov%O2%c1\t{%3, %0|%0, %3}"
23197 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23198 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23199 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23200
23201 (define_split
23202 [(set (match_operand:DF 0 "general_reg_operand")
23203 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23204 [(reg FLAGS_REG) (const_int 0)])
23205 (match_operand:DF 2 "nonimmediate_operand")
23206 (match_operand:DF 3 "nonimmediate_operand")))]
23207 "!TARGET_64BIT && reload_completed"
23208 [(set (match_dup 2)
23209 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23210 (set (match_dup 3)
23211 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23212 {
23213 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23214 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23215 })
23216
23217 (define_insn "*movsfcc_1_387"
23218 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23219 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23220 [(reg FLAGS_REG) (const_int 0)])
23221 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23222 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23223 "TARGET_80387 && TARGET_CMOVE
23224 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23225 "@
23226 fcmov%F1\t{%2, %0|%0, %2}
23227 fcmov%f1\t{%3, %0|%0, %3}
23228 cmov%O2%C1\t{%2, %0|%0, %2}
23229 cmov%O2%c1\t{%3, %0|%0, %3}"
23230 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23231 (set_attr "mode" "SF,SF,SI,SI")])
23232
23233 ;; Don't do conditional moves with memory inputs. This splitter helps
23234 ;; register starved x86_32 by forcing inputs into registers before reload.
23235 (define_split
23236 [(set (match_operand:MODEF 0 "register_operand")
23237 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23238 [(reg FLAGS_REG) (const_int 0)])
23239 (match_operand:MODEF 2 "nonimmediate_operand")
23240 (match_operand:MODEF 3 "nonimmediate_operand")))]
23241 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23242 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23243 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23244 && can_create_pseudo_p ()
23245 && optimize_insn_for_speed_p ()"
23246 [(set (match_dup 0)
23247 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23248 {
23249 operands[2] = force_reg (<MODE>mode, operands[2]);
23250 operands[3] = force_reg (<MODE>mode, operands[3]);
23251 })
23252
23253 ;; Don't do conditional moves with memory inputs
23254 (define_peephole2
23255 [(match_scratch:MODEF 4 "r")
23256 (set (match_operand:MODEF 0 "general_reg_operand")
23257 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23258 [(reg FLAGS_REG) (const_int 0)])
23259 (match_operand:MODEF 2 "nonimmediate_operand")
23260 (match_operand:MODEF 3 "nonimmediate_operand")))]
23261 "(<MODE>mode != DFmode || TARGET_64BIT)
23262 && TARGET_80387 && TARGET_CMOVE
23263 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23264 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23265 && optimize_insn_for_speed_p ()"
23266 [(set (match_dup 4) (match_dup 5))
23267 (set (match_dup 0)
23268 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23269 {
23270 if (MEM_P (operands[2]))
23271 {
23272 operands[5] = operands[2];
23273 operands[2] = operands[4];
23274 }
23275 else if (MEM_P (operands[3]))
23276 {
23277 operands[5] = operands[3];
23278 operands[3] = operands[4];
23279 }
23280 else
23281 gcc_unreachable ();
23282 })
23283
23284 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23285 ;; the scalar versions to have only XMM registers as operands.
23286
23287 ;; XOP conditional move
23288 (define_insn "*xop_pcmov_<mode>"
23289 [(set (match_operand:MODEF 0 "register_operand" "=x")
23290 (if_then_else:MODEF
23291 (match_operand:MODEF 1 "register_operand" "x")
23292 (match_operand:MODEF 2 "register_operand" "x")
23293 (match_operand:MODEF 3 "register_operand" "x")))]
23294 "TARGET_XOP"
23295 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23296 [(set_attr "type" "sse4arg")])
23297
23298 ;; These versions of the min/max patterns are intentionally ignorant of
23299 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23300 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23301 ;; are undefined in this condition, we're certain this is correct.
23302
23303 (define_insn "<code><mode>3"
23304 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23305 (smaxmin:MODEF
23306 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23307 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23308 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23309 "@
23310 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23311 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23312 [(set_attr "isa" "noavx,avx")
23313 (set_attr "prefix" "orig,vex")
23314 (set_attr "type" "sseadd")
23315 (set_attr "mode" "<MODE>")])
23316
23317 (define_insn "<code>hf3"
23318 [(set (match_operand:HF 0 "register_operand" "=v")
23319 (smaxmin:HF
23320 (match_operand:HF 1 "nonimmediate_operand" "%v")
23321 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23322 "TARGET_AVX512FP16"
23323 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23324 [(set_attr "prefix" "evex")
23325 (set_attr "type" "sseadd")
23326 (set_attr "mode" "HF")])
23327
23328 ;; These versions of the min/max patterns implement exactly the operations
23329 ;; min = (op1 < op2 ? op1 : op2)
23330 ;; max = (!(op1 < op2) ? op1 : op2)
23331 ;; Their operands are not commutative, and thus they may be used in the
23332 ;; presence of -0.0 and NaN.
23333
23334 (define_insn "*ieee_s<ieee_maxmin>hf3"
23335 [(set (match_operand:HF 0 "register_operand" "=v")
23336 (unspec:HF
23337 [(match_operand:HF 1 "register_operand" "v")
23338 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23339 IEEE_MAXMIN))]
23340 "TARGET_AVX512FP16"
23341 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23342 [(set_attr "prefix" "evex")
23343 (set_attr "type" "sseadd")
23344 (set_attr "mode" "HF")])
23345
23346 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23347 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23348 (unspec:MODEF
23349 [(match_operand:MODEF 1 "register_operand" "0,v")
23350 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23351 IEEE_MAXMIN))]
23352 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23353 "@
23354 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23355 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23356 [(set_attr "isa" "noavx,avx")
23357 (set_attr "prefix" "orig,maybe_evex")
23358 (set_attr "type" "sseadd")
23359 (set_attr "mode" "<MODE>")])
23360
23361 ;; Operands order in min/max instruction matters for signed zero and NANs.
23362 (define_insn_and_split "*ieee_max<mode>3_1"
23363 [(set (match_operand:MODEF 0 "register_operand")
23364 (unspec:MODEF
23365 [(match_operand:MODEF 1 "register_operand")
23366 (match_operand:MODEF 2 "register_operand")
23367 (lt:MODEF
23368 (match_operand:MODEF 3 "register_operand")
23369 (match_operand:MODEF 4 "register_operand"))]
23370 UNSPEC_BLENDV))]
23371 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23372 && (rtx_equal_p (operands[1], operands[3])
23373 && rtx_equal_p (operands[2], operands[4]))
23374 && ix86_pre_reload_split ()"
23375 "#"
23376 "&& 1"
23377 [(set (match_dup 0)
23378 (unspec:MODEF
23379 [(match_dup 2)
23380 (match_dup 1)]
23381 UNSPEC_IEEE_MAX))])
23382
23383 (define_insn_and_split "*ieee_min<mode>3_1"
23384 [(set (match_operand:MODEF 0 "register_operand")
23385 (unspec:MODEF
23386 [(match_operand:MODEF 1 "register_operand")
23387 (match_operand:MODEF 2 "register_operand")
23388 (lt:MODEF
23389 (match_operand:MODEF 3 "register_operand")
23390 (match_operand:MODEF 4 "register_operand"))]
23391 UNSPEC_BLENDV))]
23392 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23393 && (rtx_equal_p (operands[1], operands[4])
23394 && rtx_equal_p (operands[2], operands[3]))
23395 && ix86_pre_reload_split ()"
23396 "#"
23397 "&& 1"
23398 [(set (match_dup 0)
23399 (unspec:MODEF
23400 [(match_dup 2)
23401 (match_dup 1)]
23402 UNSPEC_IEEE_MIN))])
23403
23404 ;; Make two stack loads independent:
23405 ;; fld aa fld aa
23406 ;; fld %st(0) -> fld bb
23407 ;; fmul bb fmul %st(1), %st
23408 ;;
23409 ;; Actually we only match the last two instructions for simplicity.
23410
23411 (define_peephole2
23412 [(set (match_operand 0 "fp_register_operand")
23413 (match_operand 1 "fp_register_operand"))
23414 (set (match_dup 0)
23415 (match_operator 2 "binary_fp_operator"
23416 [(match_dup 0)
23417 (match_operand 3 "memory_operand")]))]
23418 "REGNO (operands[0]) != REGNO (operands[1])"
23419 [(set (match_dup 0) (match_dup 3))
23420 (set (match_dup 0)
23421 (match_op_dup 2
23422 [(match_dup 5) (match_dup 4)]))]
23423 {
23424 operands[4] = operands[0];
23425 operands[5] = operands[1];
23426
23427 /* The % modifier is not operational anymore in peephole2's, so we have to
23428 swap the operands manually in the case of addition and multiplication. */
23429 if (COMMUTATIVE_ARITH_P (operands[2]))
23430 std::swap (operands[4], operands[5]);
23431 })
23432
23433 (define_peephole2
23434 [(set (match_operand 0 "fp_register_operand")
23435 (match_operand 1 "fp_register_operand"))
23436 (set (match_dup 0)
23437 (match_operator 2 "binary_fp_operator"
23438 [(match_operand 3 "memory_operand")
23439 (match_dup 0)]))]
23440 "REGNO (operands[0]) != REGNO (operands[1])"
23441 [(set (match_dup 0) (match_dup 3))
23442 (set (match_dup 0)
23443 (match_op_dup 2
23444 [(match_dup 4) (match_dup 5)]))]
23445 {
23446 operands[4] = operands[0];
23447 operands[5] = operands[1];
23448
23449 /* The % modifier is not operational anymore in peephole2's, so we have to
23450 swap the operands manually in the case of addition and multiplication. */
23451 if (COMMUTATIVE_ARITH_P (operands[2]))
23452 std::swap (operands[4], operands[5]);
23453 })
23454
23455 ;; Conditional addition patterns
23456 (define_expand "add<mode>cc"
23457 [(match_operand:SWI 0 "register_operand")
23458 (match_operand 1 "ordered_comparison_operator")
23459 (match_operand:SWI 2 "register_operand")
23460 (match_operand:SWI 3 "const_int_operand")]
23461 ""
23462 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23463
23464 ;; min/max patterns
23465
23466 (define_code_attr maxmin_rel
23467 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23468
23469 (define_expand "<code><mode>3"
23470 [(parallel
23471 [(set (match_operand:SDWIM 0 "register_operand")
23472 (maxmin:SDWIM
23473 (match_operand:SDWIM 1 "register_operand")
23474 (match_operand:SDWIM 2 "general_operand")))
23475 (clobber (reg:CC FLAGS_REG))])]
23476 "TARGET_CMOVE
23477 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23478
23479 (define_insn_and_split "*<code><dwi>3_doubleword"
23480 [(set (match_operand:<DWI> 0 "register_operand")
23481 (maxmin:<DWI>
23482 (match_operand:<DWI> 1 "register_operand")
23483 (match_operand:<DWI> 2 "general_operand")))
23484 (clobber (reg:CC FLAGS_REG))]
23485 "TARGET_CMOVE
23486 && ix86_pre_reload_split ()"
23487 "#"
23488 "&& 1"
23489 [(set (match_dup 0)
23490 (if_then_else:DWIH (match_dup 6)
23491 (match_dup 1)
23492 (match_dup 2)))
23493 (set (match_dup 3)
23494 (if_then_else:DWIH (match_dup 6)
23495 (match_dup 4)
23496 (match_dup 5)))]
23497 {
23498 operands[2] = force_reg (<DWI>mode, operands[2]);
23499
23500 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23501
23502 rtx cmplo[2] = { operands[1], operands[2] };
23503 rtx cmphi[2] = { operands[4], operands[5] };
23504
23505 enum rtx_code code = <maxmin_rel>;
23506
23507 switch (code)
23508 {
23509 case LE: case LEU:
23510 std::swap (cmplo[0], cmplo[1]);
23511 std::swap (cmphi[0], cmphi[1]);
23512 code = swap_condition (code);
23513 /* FALLTHRU */
23514
23515 case GE: case GEU:
23516 {
23517 bool uns = (code == GEU);
23518 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23519 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23520
23521 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23522
23523 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23524 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23525
23526 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23527 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23528
23529 break;
23530 }
23531
23532 default:
23533 gcc_unreachable ();
23534 }
23535 })
23536
23537 (define_insn_and_split "*<code><mode>3_1"
23538 [(set (match_operand:SWI 0 "register_operand")
23539 (maxmin:SWI
23540 (match_operand:SWI 1 "register_operand")
23541 (match_operand:SWI 2 "general_operand")))
23542 (clobber (reg:CC FLAGS_REG))]
23543 "TARGET_CMOVE
23544 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23545 && ix86_pre_reload_split ()"
23546 "#"
23547 "&& 1"
23548 [(set (match_dup 0)
23549 (if_then_else:SWI (match_dup 3)
23550 (match_dup 1)
23551 (match_dup 2)))]
23552 {
23553 machine_mode mode = <MODE>mode;
23554 rtx cmp_op = operands[2];
23555
23556 operands[2] = force_reg (mode, cmp_op);
23557
23558 enum rtx_code code = <maxmin_rel>;
23559
23560 if (cmp_op == const1_rtx)
23561 {
23562 /* Convert smax (x, 1) into (x > 0 ? x : 1).
23563 Convert umax (x, 1) into (x != 0 ? x : 1).
23564 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
23565 cmp_op = const0_rtx;
23566 if (code == GE)
23567 code = GT;
23568 else if (code == GEU)
23569 code = NE;
23570 }
23571 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
23572 else if (cmp_op == constm1_rtx && code == LE)
23573 {
23574 cmp_op = const0_rtx;
23575 code = LT;
23576 }
23577 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
23578 else if (cmp_op == constm1_rtx && code == GE)
23579 cmp_op = const0_rtx;
23580 else if (cmp_op != const0_rtx)
23581 cmp_op = operands[2];
23582
23583 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
23584 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
23585
23586 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
23587 emit_insn (gen_rtx_SET (flags, tmp));
23588
23589 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23590 })
23591
23592 ;; Avoid clearing a register between a flags setting comparison and its use,
23593 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
23594 (define_peephole2
23595 [(set (reg FLAGS_REG) (match_operand 0))
23596 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
23597 "peep2_regno_dead_p (0, FLAGS_REG)
23598 && !reg_overlap_mentioned_p (operands[1], operands[0])"
23599 [(set (match_dup 2) (match_dup 0))]
23600 {
23601 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
23602 ix86_expand_clear (operands[1]);
23603 })
23604
23605 ;; When optimizing for size, zeroing memory should use a register.
23606 (define_peephole2
23607 [(match_scratch:SWI48 0 "r")
23608 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23609 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23610 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23611 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23612 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23613 [(const_int 0)]
23614 {
23615 ix86_expand_clear (operands[0]);
23616 emit_move_insn (operands[1], operands[0]);
23617 emit_move_insn (operands[2], operands[0]);
23618 emit_move_insn (operands[3], operands[0]);
23619 ix86_last_zero_store_uid
23620 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23621 DONE;
23622 })
23623
23624 (define_peephole2
23625 [(match_scratch:SWI48 0 "r")
23626 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23627 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23628 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23629 [(const_int 0)]
23630 {
23631 ix86_expand_clear (operands[0]);
23632 emit_move_insn (operands[1], operands[0]);
23633 ix86_last_zero_store_uid
23634 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23635 DONE;
23636 })
23637
23638 (define_peephole2
23639 [(match_scratch:SWI48 0 "r")
23640 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23641 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23642 [(const_int 0)]
23643 {
23644 ix86_expand_clear (operands[0]);
23645 ix86_last_zero_store_uid
23646 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23647 DONE;
23648 })
23649
23650 (define_peephole2
23651 [(set (match_operand:SWI48 5 "memory_operand")
23652 (match_operand:SWI48 0 "general_reg_operand"))
23653 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23654 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23655 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23656 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23657 "optimize_insn_for_size_p ()
23658 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23659 [(const_int 0)]
23660 {
23661 emit_move_insn (operands[5], operands[0]);
23662 emit_move_insn (operands[1], operands[0]);
23663 emit_move_insn (operands[2], operands[0]);
23664 emit_move_insn (operands[3], operands[0]);
23665 ix86_last_zero_store_uid
23666 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23667 DONE;
23668 })
23669
23670 (define_peephole2
23671 [(set (match_operand:SWI48 3 "memory_operand")
23672 (match_operand:SWI48 0 "general_reg_operand"))
23673 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23674 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23675 "optimize_insn_for_size_p ()
23676 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23677 [(const_int 0)]
23678 {
23679 emit_move_insn (operands[3], operands[0]);
23680 emit_move_insn (operands[1], operands[0]);
23681 ix86_last_zero_store_uid
23682 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23683 DONE;
23684 })
23685
23686 (define_peephole2
23687 [(set (match_operand:SWI48 2 "memory_operand")
23688 (match_operand:SWI48 0 "general_reg_operand"))
23689 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23690 "optimize_insn_for_size_p ()
23691 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23692 [(const_int 0)]
23693 {
23694 emit_move_insn (operands[2], operands[0]);
23695 ix86_last_zero_store_uid
23696 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23697 DONE;
23698 })
23699
23700 ;; Reload dislikes loading constants directly into class_likely_spilled
23701 ;; hard registers. Try to tidy things up here.
23702 (define_peephole2
23703 [(set (match_operand:SWI 0 "general_reg_operand")
23704 (match_operand:SWI 1 "x86_64_general_operand"))
23705 (set (match_operand:SWI 2 "general_reg_operand")
23706 (match_dup 0))]
23707 "peep2_reg_dead_p (2, operands[0])"
23708 [(set (match_dup 2) (match_dup 1))])
23709 \f
23710 ;; Misc patterns (?)
23711
23712 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
23713 ;; Otherwise there will be nothing to keep
23714 ;;
23715 ;; [(set (reg ebp) (reg esp))]
23716 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
23717 ;; (clobber (eflags)]
23718 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
23719 ;;
23720 ;; in proper program order.
23721
23722 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
23723 [(set (match_operand:P 0 "register_operand" "=r,r")
23724 (plus:P (match_operand:P 1 "register_operand" "0,r")
23725 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
23726 (clobber (reg:CC FLAGS_REG))
23727 (clobber (mem:BLK (scratch)))]
23728 ""
23729 {
23730 switch (get_attr_type (insn))
23731 {
23732 case TYPE_IMOV:
23733 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
23734
23735 case TYPE_ALU:
23736 gcc_assert (rtx_equal_p (operands[0], operands[1]));
23737 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
23738 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
23739
23740 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
23741
23742 default:
23743 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
23744 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
23745 }
23746 }
23747 [(set (attr "type")
23748 (cond [(and (eq_attr "alternative" "0")
23749 (not (match_test "TARGET_OPT_AGU")))
23750 (const_string "alu")
23751 (match_operand:<MODE> 2 "const0_operand")
23752 (const_string "imov")
23753 ]
23754 (const_string "lea")))
23755 (set (attr "length_immediate")
23756 (cond [(eq_attr "type" "imov")
23757 (const_string "0")
23758 (and (eq_attr "type" "alu")
23759 (match_operand 2 "const128_operand"))
23760 (const_string "1")
23761 ]
23762 (const_string "*")))
23763 (set_attr "mode" "<MODE>")])
23764
23765 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
23766 [(set (match_operand:P 0 "register_operand" "=r")
23767 (minus:P (match_operand:P 1 "register_operand" "0")
23768 (match_operand:P 2 "register_operand" "r")))
23769 (clobber (reg:CC FLAGS_REG))
23770 (clobber (mem:BLK (scratch)))]
23771 ""
23772 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
23773 [(set_attr "type" "alu")
23774 (set_attr "mode" "<MODE>")])
23775
23776 (define_insn "@allocate_stack_worker_probe_<mode>"
23777 [(set (match_operand:P 0 "register_operand" "=a")
23778 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23779 UNSPECV_STACK_PROBE))
23780 (clobber (reg:CC FLAGS_REG))]
23781 "ix86_target_stack_probe ()"
23782 "call\t___chkstk_ms"
23783 [(set_attr "type" "multi")
23784 (set_attr "length" "5")])
23785
23786 (define_expand "allocate_stack"
23787 [(match_operand 0 "register_operand")
23788 (match_operand 1 "general_operand")]
23789 "ix86_target_stack_probe ()"
23790 {
23791 rtx x;
23792
23793 #ifndef CHECK_STACK_LIMIT
23794 #define CHECK_STACK_LIMIT 0
23795 #endif
23796
23797 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
23798 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
23799 x = operands[1];
23800 else
23801 {
23802 x = copy_to_mode_reg (Pmode, operands[1]);
23803
23804 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
23805 }
23806
23807 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
23808 stack_pointer_rtx, 0, OPTAB_DIRECT);
23809
23810 if (x != stack_pointer_rtx)
23811 emit_move_insn (stack_pointer_rtx, x);
23812
23813 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
23814 DONE;
23815 })
23816
23817 (define_expand "probe_stack"
23818 [(match_operand 0 "memory_operand")]
23819 ""
23820 {
23821 emit_insn (gen_probe_stack_1
23822 (word_mode, operands[0], const0_rtx));
23823 DONE;
23824 })
23825
23826 ;; Use OR for stack probes, this is shorter.
23827 (define_insn "@probe_stack_1_<mode>"
23828 [(set (match_operand:W 0 "memory_operand" "=m")
23829 (unspec:W [(match_operand:W 1 "const0_operand")]
23830 UNSPEC_PROBE_STACK))
23831 (clobber (reg:CC FLAGS_REG))]
23832 ""
23833 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
23834 [(set_attr "type" "alu1")
23835 (set_attr "mode" "<MODE>")
23836 (set_attr "length_immediate" "1")])
23837
23838 (define_insn "@adjust_stack_and_probe_<mode>"
23839 [(set (match_operand:P 0 "register_operand" "=r")
23840 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23841 UNSPECV_PROBE_STACK_RANGE))
23842 (set (reg:P SP_REG)
23843 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
23844 (clobber (reg:CC FLAGS_REG))
23845 (clobber (mem:BLK (scratch)))]
23846 ""
23847 "* return output_adjust_stack_and_probe (operands[0]);"
23848 [(set_attr "type" "multi")])
23849
23850 (define_insn "@probe_stack_range_<mode>"
23851 [(set (match_operand:P 0 "register_operand" "=r")
23852 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
23853 (match_operand:P 2 "const_int_operand")]
23854 UNSPECV_PROBE_STACK_RANGE))
23855 (clobber (reg:CC FLAGS_REG))]
23856 ""
23857 "* return output_probe_stack_range (operands[0], operands[2]);"
23858 [(set_attr "type" "multi")])
23859
23860 (define_expand "builtin_setjmp_receiver"
23861 [(label_ref (match_operand 0))]
23862 "!TARGET_64BIT && flag_pic"
23863 {
23864 #if TARGET_MACHO
23865 if (TARGET_MACHO)
23866 {
23867 rtx xops[3];
23868 rtx_code_label *label_rtx = gen_label_rtx ();
23869 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
23870 xops[0] = xops[1] = pic_offset_table_rtx;
23871 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
23872 ix86_expand_binary_operator (MINUS, SImode, xops);
23873 }
23874 else
23875 #endif
23876 emit_insn (gen_set_got (pic_offset_table_rtx));
23877 DONE;
23878 })
23879
23880 (define_expand "save_stack_nonlocal"
23881 [(set (match_operand 0 "memory_operand")
23882 (match_operand 1 "register_operand"))]
23883 ""
23884 {
23885 rtx stack_slot;
23886
23887 if (flag_cf_protection & CF_RETURN)
23888 {
23889 /* Copy shadow stack pointer to the first slot
23890 and stack pointer to the second slot. */
23891 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
23892 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
23893
23894 rtx reg_ssp = force_reg (word_mode, const0_rtx);
23895 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
23896 emit_move_insn (ssp_slot, reg_ssp);
23897 }
23898 else
23899 stack_slot = adjust_address (operands[0], Pmode, 0);
23900 emit_move_insn (stack_slot, operands[1]);
23901 DONE;
23902 })
23903
23904 (define_expand "restore_stack_nonlocal"
23905 [(set (match_operand 0 "register_operand" "")
23906 (match_operand 1 "memory_operand" ""))]
23907 ""
23908 {
23909 rtx stack_slot;
23910
23911 if (flag_cf_protection & CF_RETURN)
23912 {
23913 /* Restore shadow stack pointer from the first slot
23914 and stack pointer from the second slot. */
23915 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
23916 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
23917
23918 /* Get the current shadow stack pointer. The code below will check if
23919 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
23920 is a NOP. */
23921 rtx reg_ssp = force_reg (word_mode, const0_rtx);
23922 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
23923
23924 /* Compare through subtraction the saved and the current ssp
23925 to decide if ssp has to be adjusted. */
23926 reg_ssp = expand_simple_binop (word_mode, MINUS,
23927 reg_ssp, ssp_slot,
23928 reg_ssp, 1, OPTAB_DIRECT);
23929
23930 /* Compare and jump over adjustment code. */
23931 rtx noadj_label = gen_label_rtx ();
23932 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
23933 word_mode, 1, noadj_label);
23934
23935 /* Compute the number of frames to adjust. */
23936 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
23937 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
23938 NULL_RTX, 1);
23939
23940 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
23941 GEN_INT (exact_log2 (UNITS_PER_WORD)),
23942 reg_adj, 1, OPTAB_DIRECT);
23943
23944 /* Check if number of frames <= 255 so no loop is needed. */
23945 rtx inc_label = gen_label_rtx ();
23946 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
23947 ptr_mode, 1, inc_label);
23948
23949 /* Adjust the ssp in a loop. */
23950 rtx loop_label = gen_label_rtx ();
23951 emit_label (loop_label);
23952 LABEL_NUSES (loop_label) = 1;
23953
23954 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
23955 emit_insn (gen_incssp (word_mode, reg_255));
23956
23957 reg_adj = expand_simple_binop (ptr_mode, MINUS,
23958 reg_adj, GEN_INT (255),
23959 reg_adj, 1, OPTAB_DIRECT);
23960
23961 /* Compare and jump to the loop label. */
23962 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
23963 ptr_mode, 1, loop_label);
23964
23965 emit_label (inc_label);
23966 LABEL_NUSES (inc_label) = 1;
23967
23968 emit_insn (gen_incssp (word_mode, reg_ssp));
23969
23970 emit_label (noadj_label);
23971 LABEL_NUSES (noadj_label) = 1;
23972 }
23973 else
23974 stack_slot = adjust_address (operands[1], Pmode, 0);
23975 emit_move_insn (operands[0], stack_slot);
23976 DONE;
23977 })
23978
23979
23980 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
23981 ;; Do not split instructions with mask registers.
23982 (define_split
23983 [(set (match_operand 0 "general_reg_operand")
23984 (match_operator 3 "promotable_binary_operator"
23985 [(match_operand 1 "general_reg_operand")
23986 (match_operand 2 "aligned_operand")]))
23987 (clobber (reg:CC FLAGS_REG))]
23988 "! TARGET_PARTIAL_REG_STALL && reload_completed
23989 && ((GET_MODE (operands[0]) == HImode
23990 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
23991 /* ??? next two lines just !satisfies_constraint_K (...) */
23992 || !CONST_INT_P (operands[2])
23993 || satisfies_constraint_K (operands[2])))
23994 || (GET_MODE (operands[0]) == QImode
23995 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
23996 [(parallel [(set (match_dup 0)
23997 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
23998 (clobber (reg:CC FLAGS_REG))])]
23999 {
24000 operands[0] = gen_lowpart (SImode, operands[0]);
24001 operands[1] = gen_lowpart (SImode, operands[1]);
24002 if (GET_CODE (operands[3]) != ASHIFT)
24003 operands[2] = gen_lowpart (SImode, operands[2]);
24004 operands[3] = shallow_copy_rtx (operands[3]);
24005 PUT_MODE (operands[3], SImode);
24006 })
24007
24008 ; Promote the QImode tests, as i386 has encoding of the AND
24009 ; instruction with 32-bit sign-extended immediate and thus the
24010 ; instruction size is unchanged, except in the %eax case for
24011 ; which it is increased by one byte, hence the ! optimize_size.
24012 (define_split
24013 [(set (match_operand 0 "flags_reg_operand")
24014 (match_operator 2 "compare_operator"
24015 [(and (match_operand 3 "aligned_operand")
24016 (match_operand 4 "const_int_operand"))
24017 (const_int 0)]))
24018 (set (match_operand 1 "register_operand")
24019 (and (match_dup 3) (match_dup 4)))]
24020 "! TARGET_PARTIAL_REG_STALL && reload_completed
24021 && optimize_insn_for_speed_p ()
24022 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
24023 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
24024 /* Ensure that the operand will remain sign-extended immediate. */
24025 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
24026 [(parallel [(set (match_dup 0)
24027 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
24028 (const_int 0)]))
24029 (set (match_dup 1)
24030 (and:SI (match_dup 3) (match_dup 4)))])]
24031 {
24032 operands[4]
24033 = gen_int_mode (INTVAL (operands[4])
24034 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
24035 operands[1] = gen_lowpart (SImode, operands[1]);
24036 operands[3] = gen_lowpart (SImode, operands[3]);
24037 })
24038
24039 ; Don't promote the QImode tests, as i386 doesn't have encoding of
24040 ; the TEST instruction with 32-bit sign-extended immediate and thus
24041 ; the instruction size would at least double, which is not what we
24042 ; want even with ! optimize_size.
24043 (define_split
24044 [(set (match_operand 0 "flags_reg_operand")
24045 (match_operator 1 "compare_operator"
24046 [(and (match_operand:HI 2 "aligned_operand")
24047 (match_operand:HI 3 "const_int_operand"))
24048 (const_int 0)]))]
24049 "! TARGET_PARTIAL_REG_STALL && reload_completed
24050 && ! TARGET_FAST_PREFIX
24051 && optimize_insn_for_speed_p ()
24052 /* Ensure that the operand will remain sign-extended immediate. */
24053 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
24054 [(set (match_dup 0)
24055 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24056 (const_int 0)]))]
24057 {
24058 operands[3]
24059 = gen_int_mode (INTVAL (operands[3])
24060 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
24061 operands[2] = gen_lowpart (SImode, operands[2]);
24062 })
24063
24064 (define_split
24065 [(set (match_operand 0 "register_operand")
24066 (neg (match_operand 1 "register_operand")))
24067 (clobber (reg:CC FLAGS_REG))]
24068 "! TARGET_PARTIAL_REG_STALL && reload_completed
24069 && (GET_MODE (operands[0]) == HImode
24070 || (GET_MODE (operands[0]) == QImode
24071 && (TARGET_PROMOTE_QImode
24072 || optimize_insn_for_size_p ())))"
24073 [(parallel [(set (match_dup 0)
24074 (neg:SI (match_dup 1)))
24075 (clobber (reg:CC FLAGS_REG))])]
24076 {
24077 operands[0] = gen_lowpart (SImode, operands[0]);
24078 operands[1] = gen_lowpart (SImode, operands[1]);
24079 })
24080
24081 ;; Do not split instructions with mask regs.
24082 (define_split
24083 [(set (match_operand 0 "general_reg_operand")
24084 (not (match_operand 1 "general_reg_operand")))]
24085 "! TARGET_PARTIAL_REG_STALL && reload_completed
24086 && (GET_MODE (operands[0]) == HImode
24087 || (GET_MODE (operands[0]) == QImode
24088 && (TARGET_PROMOTE_QImode
24089 || optimize_insn_for_size_p ())))"
24090 [(set (match_dup 0)
24091 (not:SI (match_dup 1)))]
24092 {
24093 operands[0] = gen_lowpart (SImode, operands[0]);
24094 operands[1] = gen_lowpart (SImode, operands[1]);
24095 })
24096 \f
24097 ;; RTL Peephole optimizations, run before sched2. These primarily look to
24098 ;; transform a complex memory operation into two memory to register operations.
24099
24100 ;; Don't push memory operands
24101 (define_peephole2
24102 [(set (match_operand:SWI 0 "push_operand")
24103 (match_operand:SWI 1 "memory_operand"))
24104 (match_scratch:SWI 2 "<r>")]
24105 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24106 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24107 [(set (match_dup 2) (match_dup 1))
24108 (set (match_dup 0) (match_dup 2))])
24109
24110 ;; We need to handle SFmode only, because DFmode and XFmode are split to
24111 ;; SImode pushes.
24112 (define_peephole2
24113 [(set (match_operand:SF 0 "push_operand")
24114 (match_operand:SF 1 "memory_operand"))
24115 (match_scratch:SF 2 "r")]
24116 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
24117 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
24118 [(set (match_dup 2) (match_dup 1))
24119 (set (match_dup 0) (match_dup 2))])
24120
24121 ;; Don't move an immediate directly to memory when the instruction
24122 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24123 (define_peephole2
24124 [(match_scratch:SWI124 1 "<r>")
24125 (set (match_operand:SWI124 0 "memory_operand")
24126 (const_int 0))]
24127 "optimize_insn_for_speed_p ()
24128 && ((<MODE>mode == HImode
24129 && TARGET_LCP_STALL)
24130 || (!TARGET_USE_MOV0
24131 && TARGET_SPLIT_LONG_MOVES
24132 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24133 && peep2_regno_dead_p (0, FLAGS_REG)"
24134 [(parallel [(set (match_dup 2) (const_int 0))
24135 (clobber (reg:CC FLAGS_REG))])
24136 (set (match_dup 0) (match_dup 1))]
24137 "operands[2] = gen_lowpart (SImode, operands[1]);")
24138
24139 (define_peephole2
24140 [(match_scratch:SWI124 2 "<r>")
24141 (set (match_operand:SWI124 0 "memory_operand")
24142 (match_operand:SWI124 1 "immediate_operand"))]
24143 "optimize_insn_for_speed_p ()
24144 && ((<MODE>mode == HImode
24145 && TARGET_LCP_STALL)
24146 || (TARGET_SPLIT_LONG_MOVES
24147 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24148 [(set (match_dup 2) (match_dup 1))
24149 (set (match_dup 0) (match_dup 2))])
24150
24151 ;; Don't compare memory with zero, load and use a test instead.
24152 (define_peephole2
24153 [(set (match_operand 0 "flags_reg_operand")
24154 (match_operator 1 "compare_operator"
24155 [(match_operand:SI 2 "memory_operand")
24156 (const_int 0)]))
24157 (match_scratch:SI 3 "r")]
24158 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24159 [(set (match_dup 3) (match_dup 2))
24160 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24161
24162 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24163 ;; Don't split NOTs with a displacement operand, because resulting XOR
24164 ;; will not be pairable anyway.
24165 ;;
24166 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24167 ;; represented using a modRM byte. The XOR replacement is long decoded,
24168 ;; so this split helps here as well.
24169 ;;
24170 ;; Note: Can't do this as a regular split because we can't get proper
24171 ;; lifetime information then.
24172
24173 (define_peephole2
24174 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24175 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24176 "optimize_insn_for_speed_p ()
24177 && ((TARGET_NOT_UNPAIRABLE
24178 && (!MEM_P (operands[0])
24179 || !memory_displacement_operand (operands[0], <MODE>mode)))
24180 || (TARGET_NOT_VECTORMODE
24181 && long_memory_operand (operands[0], <MODE>mode)))
24182 && peep2_regno_dead_p (0, FLAGS_REG)"
24183 [(parallel [(set (match_dup 0)
24184 (xor:SWI124 (match_dup 1) (const_int -1)))
24185 (clobber (reg:CC FLAGS_REG))])])
24186
24187 ;; Non pairable "test imm, reg" instructions can be translated to
24188 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
24189 ;; byte opcode instead of two, have a short form for byte operands),
24190 ;; so do it for other CPUs as well. Given that the value was dead,
24191 ;; this should not create any new dependencies. Pass on the sub-word
24192 ;; versions if we're concerned about partial register stalls.
24193
24194 (define_peephole2
24195 [(set (match_operand 0 "flags_reg_operand")
24196 (match_operator 1 "compare_operator"
24197 [(and:SI (match_operand:SI 2 "register_operand")
24198 (match_operand:SI 3 "immediate_operand"))
24199 (const_int 0)]))]
24200 "ix86_match_ccmode (insn, CCNOmode)
24201 && (REGNO (operands[2]) != AX_REG
24202 || satisfies_constraint_K (operands[3]))
24203 && peep2_reg_dead_p (1, operands[2])"
24204 [(parallel
24205 [(set (match_dup 0)
24206 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24207 (const_int 0)]))
24208 (set (match_dup 2)
24209 (and:SI (match_dup 2) (match_dup 3)))])])
24210
24211 ;; We don't need to handle HImode case, because it will be promoted to SImode
24212 ;; on ! TARGET_PARTIAL_REG_STALL
24213
24214 (define_peephole2
24215 [(set (match_operand 0 "flags_reg_operand")
24216 (match_operator 1 "compare_operator"
24217 [(and:QI (match_operand:QI 2 "register_operand")
24218 (match_operand:QI 3 "immediate_operand"))
24219 (const_int 0)]))]
24220 "! TARGET_PARTIAL_REG_STALL
24221 && ix86_match_ccmode (insn, CCNOmode)
24222 && REGNO (operands[2]) != AX_REG
24223 && peep2_reg_dead_p (1, operands[2])"
24224 [(parallel
24225 [(set (match_dup 0)
24226 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24227 (const_int 0)]))
24228 (set (match_dup 2)
24229 (and:QI (match_dup 2) (match_dup 3)))])])
24230
24231 (define_peephole2
24232 [(set (match_operand 0 "flags_reg_operand")
24233 (match_operator 1 "compare_operator"
24234 [(and:QI
24235 (subreg:QI
24236 (match_operator:SWI248 4 "extract_operator"
24237 [(match_operand 2 "int248_register_operand")
24238 (const_int 8)
24239 (const_int 8)]) 0)
24240 (match_operand 3 "const_int_operand"))
24241 (const_int 0)]))]
24242 "! TARGET_PARTIAL_REG_STALL
24243 && ix86_match_ccmode (insn, CCNOmode)
24244 && REGNO (operands[2]) != AX_REG
24245 && peep2_reg_dead_p (1, operands[2])"
24246 [(parallel
24247 [(set (match_dup 0)
24248 (match_op_dup 1
24249 [(and:QI
24250 (subreg:QI
24251 (match_op_dup 4 [(match_dup 2)
24252 (const_int 8)
24253 (const_int 8)]) 0)
24254 (match_dup 3))
24255 (const_int 0)]))
24256 (set (zero_extract:SWI248 (match_dup 2)
24257 (const_int 8)
24258 (const_int 8))
24259 (subreg:SWI248
24260 (and:QI
24261 (subreg:QI
24262 (match_op_dup 4 [(match_dup 2)
24263 (const_int 8)
24264 (const_int 8)]) 0)
24265 (match_dup 3)) 0))])])
24266
24267 ;; Don't do logical operations with memory inputs.
24268 (define_peephole2
24269 [(match_scratch:SWI 2 "<r>")
24270 (parallel [(set (match_operand:SWI 0 "register_operand")
24271 (match_operator:SWI 3 "arith_or_logical_operator"
24272 [(match_dup 0)
24273 (match_operand:SWI 1 "memory_operand")]))
24274 (clobber (reg:CC FLAGS_REG))])]
24275 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24276 [(set (match_dup 2) (match_dup 1))
24277 (parallel [(set (match_dup 0)
24278 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24279 (clobber (reg:CC FLAGS_REG))])])
24280
24281 (define_peephole2
24282 [(match_scratch:SWI 2 "<r>")
24283 (parallel [(set (match_operand:SWI 0 "register_operand")
24284 (match_operator:SWI 3 "arith_or_logical_operator"
24285 [(match_operand:SWI 1 "memory_operand")
24286 (match_dup 0)]))
24287 (clobber (reg:CC FLAGS_REG))])]
24288 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24289 [(set (match_dup 2) (match_dup 1))
24290 (parallel [(set (match_dup 0)
24291 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24292 (clobber (reg:CC FLAGS_REG))])])
24293
24294 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
24295 ;; the memory address refers to the destination of the load!
24296
24297 (define_peephole2
24298 [(set (match_operand:SWI 0 "general_reg_operand")
24299 (match_operand:SWI 1 "general_reg_operand"))
24300 (parallel [(set (match_dup 0)
24301 (match_operator:SWI 3 "commutative_operator"
24302 [(match_dup 0)
24303 (match_operand:SWI 2 "memory_operand")]))
24304 (clobber (reg:CC FLAGS_REG))])]
24305 "REGNO (operands[0]) != REGNO (operands[1])
24306 && (<MODE>mode != QImode
24307 || any_QIreg_operand (operands[1], QImode))"
24308 [(set (match_dup 0) (match_dup 4))
24309 (parallel [(set (match_dup 0)
24310 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24311 (clobber (reg:CC FLAGS_REG))])]
24312 {
24313 operands[4]
24314 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24315 })
24316
24317 (define_peephole2
24318 [(set (match_operand 0 "mmx_reg_operand")
24319 (match_operand 1 "mmx_reg_operand"))
24320 (set (match_dup 0)
24321 (match_operator 3 "commutative_operator"
24322 [(match_dup 0)
24323 (match_operand 2 "memory_operand")]))]
24324 "REGNO (operands[0]) != REGNO (operands[1])"
24325 [(set (match_dup 0) (match_dup 2))
24326 (set (match_dup 0)
24327 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24328
24329 (define_peephole2
24330 [(set (match_operand 0 "sse_reg_operand")
24331 (match_operand 1 "sse_reg_operand"))
24332 (set (match_dup 0)
24333 (match_operator 3 "commutative_operator"
24334 [(match_dup 0)
24335 (match_operand 2 "memory_operand")]))]
24336 "REGNO (operands[0]) != REGNO (operands[1])
24337 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
24338 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
24339 instructions require AVX512BW and AVX512VL, but with the original
24340 instructions it might require just AVX512VL.
24341 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
24342 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
24343 || TARGET_AVX512BW
24344 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
24345 || logic_operator (operands[3], VOIDmode))"
24346 [(set (match_dup 0) (match_dup 2))
24347 (set (match_dup 0)
24348 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24349
24350 ; Don't do logical operations with memory outputs
24351 ;
24352 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
24353 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
24354 ; the same decoder scheduling characteristics as the original.
24355
24356 (define_peephole2
24357 [(match_scratch:SWI 2 "<r>")
24358 (parallel [(set (match_operand:SWI 0 "memory_operand")
24359 (match_operator:SWI 3 "arith_or_logical_operator"
24360 [(match_dup 0)
24361 (match_operand:SWI 1 "<nonmemory_operand>")]))
24362 (clobber (reg:CC FLAGS_REG))])]
24363 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24364 [(set (match_dup 2) (match_dup 0))
24365 (parallel [(set (match_dup 2)
24366 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
24367 (clobber (reg:CC FLAGS_REG))])
24368 (set (match_dup 0) (match_dup 2))])
24369
24370 (define_peephole2
24371 [(match_scratch:SWI 2 "<r>")
24372 (parallel [(set (match_operand:SWI 0 "memory_operand")
24373 (match_operator:SWI 3 "arith_or_logical_operator"
24374 [(match_operand:SWI 1 "<nonmemory_operand>")
24375 (match_dup 0)]))
24376 (clobber (reg:CC FLAGS_REG))])]
24377 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24378 [(set (match_dup 2) (match_dup 0))
24379 (parallel [(set (match_dup 2)
24380 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24381 (clobber (reg:CC FLAGS_REG))])
24382 (set (match_dup 0) (match_dup 2))])
24383
24384 ;; Attempt to use arith or logical operations with memory outputs with
24385 ;; setting of flags.
24386 (define_peephole2
24387 [(set (match_operand:SWI 0 "register_operand")
24388 (match_operand:SWI 1 "memory_operand"))
24389 (parallel [(set (match_dup 0)
24390 (match_operator:SWI 3 "plusminuslogic_operator"
24391 [(match_dup 0)
24392 (match_operand:SWI 2 "<nonmemory_operand>")]))
24393 (clobber (reg:CC FLAGS_REG))])
24394 (set (match_dup 1) (match_dup 0))
24395 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24396 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24397 && peep2_reg_dead_p (4, operands[0])
24398 && !reg_overlap_mentioned_p (operands[0], operands[1])
24399 && !reg_overlap_mentioned_p (operands[0], operands[2])
24400 && (<MODE>mode != QImode
24401 || immediate_operand (operands[2], QImode)
24402 || any_QIreg_operand (operands[2], QImode))
24403 && ix86_match_ccmode (peep2_next_insn (3),
24404 (GET_CODE (operands[3]) == PLUS
24405 || GET_CODE (operands[3]) == MINUS)
24406 ? CCGOCmode : CCNOmode)"
24407 [(parallel [(set (match_dup 4) (match_dup 6))
24408 (set (match_dup 1) (match_dup 5))])]
24409 {
24410 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
24411 operands[5]
24412 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24413 copy_rtx (operands[1]),
24414 operands[2]);
24415 operands[6]
24416 = gen_rtx_COMPARE (GET_MODE (operands[4]),
24417 copy_rtx (operands[5]),
24418 const0_rtx);
24419 })
24420
24421 ;; Likewise for cmpelim optimized pattern.
24422 (define_peephole2
24423 [(set (match_operand:SWI 0 "register_operand")
24424 (match_operand:SWI 1 "memory_operand"))
24425 (parallel [(set (reg FLAGS_REG)
24426 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24427 [(match_dup 0)
24428 (match_operand:SWI 2 "<nonmemory_operand>")])
24429 (const_int 0)))
24430 (set (match_dup 0) (match_dup 3))])
24431 (set (match_dup 1) (match_dup 0))]
24432 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24433 && peep2_reg_dead_p (3, operands[0])
24434 && !reg_overlap_mentioned_p (operands[0], operands[1])
24435 && !reg_overlap_mentioned_p (operands[0], operands[2])
24436 && ix86_match_ccmode (peep2_next_insn (1),
24437 (GET_CODE (operands[3]) == PLUS
24438 || GET_CODE (operands[3]) == MINUS)
24439 ? CCGOCmode : CCNOmode)"
24440 [(parallel [(set (match_dup 4) (match_dup 6))
24441 (set (match_dup 1) (match_dup 5))])]
24442 {
24443 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24444 operands[5]
24445 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24446 copy_rtx (operands[1]), operands[2]);
24447 operands[6]
24448 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
24449 const0_rtx);
24450 })
24451
24452 ;; Likewise for instances where we have a lea pattern.
24453 (define_peephole2
24454 [(set (match_operand:SWI 0 "register_operand")
24455 (match_operand:SWI 1 "memory_operand"))
24456 (set (match_operand:<LEAMODE> 3 "register_operand")
24457 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
24458 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
24459 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
24460 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24461 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24462 && REGNO (operands[4]) == REGNO (operands[0])
24463 && REGNO (operands[5]) == REGNO (operands[3])
24464 && peep2_reg_dead_p (4, operands[3])
24465 && ((REGNO (operands[0]) == REGNO (operands[3]))
24466 || peep2_reg_dead_p (2, operands[0]))
24467 && !reg_overlap_mentioned_p (operands[0], operands[1])
24468 && !reg_overlap_mentioned_p (operands[3], operands[1])
24469 && !reg_overlap_mentioned_p (operands[0], operands[2])
24470 && (<MODE>mode != QImode
24471 || immediate_operand (operands[2], QImode)
24472 || any_QIreg_operand (operands[2], QImode))
24473 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
24474 [(parallel [(set (match_dup 6) (match_dup 8))
24475 (set (match_dup 1) (match_dup 7))])]
24476 {
24477 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
24478 operands[7]
24479 = gen_rtx_PLUS (<MODE>mode,
24480 copy_rtx (operands[1]),
24481 gen_lowpart (<MODE>mode, operands[2]));
24482 operands[8]
24483 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24484 copy_rtx (operands[7]),
24485 const0_rtx);
24486 })
24487
24488 (define_peephole2
24489 [(parallel [(set (match_operand:SWI 0 "register_operand")
24490 (match_operator:SWI 2 "plusminuslogic_operator"
24491 [(match_dup 0)
24492 (match_operand:SWI 1 "memory_operand")]))
24493 (clobber (reg:CC FLAGS_REG))])
24494 (set (match_dup 1) (match_dup 0))
24495 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24496 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24497 && COMMUTATIVE_ARITH_P (operands[2])
24498 && peep2_reg_dead_p (3, operands[0])
24499 && !reg_overlap_mentioned_p (operands[0], operands[1])
24500 && ix86_match_ccmode (peep2_next_insn (2),
24501 GET_CODE (operands[2]) == PLUS
24502 ? CCGOCmode : CCNOmode)"
24503 [(parallel [(set (match_dup 3) (match_dup 5))
24504 (set (match_dup 1) (match_dup 4))])]
24505 {
24506 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
24507 operands[4]
24508 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24509 copy_rtx (operands[1]),
24510 operands[0]);
24511 operands[5]
24512 = gen_rtx_COMPARE (GET_MODE (operands[3]),
24513 copy_rtx (operands[4]),
24514 const0_rtx);
24515 })
24516
24517 ;; Likewise for cmpelim optimized pattern.
24518 (define_peephole2
24519 [(parallel [(set (reg FLAGS_REG)
24520 (compare (match_operator:SWI 2 "plusminuslogic_operator"
24521 [(match_operand:SWI 0 "register_operand")
24522 (match_operand:SWI 1 "memory_operand")])
24523 (const_int 0)))
24524 (set (match_dup 0) (match_dup 2))])
24525 (set (match_dup 1) (match_dup 0))]
24526 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24527 && COMMUTATIVE_ARITH_P (operands[2])
24528 && peep2_reg_dead_p (2, operands[0])
24529 && !reg_overlap_mentioned_p (operands[0], operands[1])
24530 && ix86_match_ccmode (peep2_next_insn (0),
24531 GET_CODE (operands[2]) == PLUS
24532 ? CCGOCmode : CCNOmode)"
24533 [(parallel [(set (match_dup 3) (match_dup 5))
24534 (set (match_dup 1) (match_dup 4))])]
24535 {
24536 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
24537 operands[4]
24538 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24539 copy_rtx (operands[1]), operands[0]);
24540 operands[5]
24541 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
24542 const0_rtx);
24543 })
24544
24545 (define_peephole2
24546 [(set (match_operand:SWI12 0 "register_operand")
24547 (match_operand:SWI12 1 "memory_operand"))
24548 (parallel [(set (match_operand:SI 4 "register_operand")
24549 (match_operator:SI 3 "plusminuslogic_operator"
24550 [(match_dup 4)
24551 (match_operand:SI 2 "nonmemory_operand")]))
24552 (clobber (reg:CC FLAGS_REG))])
24553 (set (match_dup 1) (match_dup 0))
24554 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24555 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24556 && REGNO (operands[0]) == REGNO (operands[4])
24557 && peep2_reg_dead_p (4, operands[0])
24558 && (<MODE>mode != QImode
24559 || immediate_operand (operands[2], SImode)
24560 || any_QIreg_operand (operands[2], SImode))
24561 && !reg_overlap_mentioned_p (operands[0], operands[1])
24562 && !reg_overlap_mentioned_p (operands[0], operands[2])
24563 && ix86_match_ccmode (peep2_next_insn (3),
24564 (GET_CODE (operands[3]) == PLUS
24565 || GET_CODE (operands[3]) == MINUS)
24566 ? CCGOCmode : CCNOmode)"
24567 [(parallel [(set (match_dup 5) (match_dup 7))
24568 (set (match_dup 1) (match_dup 6))])]
24569 {
24570 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
24571 operands[6]
24572 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24573 copy_rtx (operands[1]),
24574 gen_lowpart (<MODE>mode, operands[2]));
24575 operands[7]
24576 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24577 copy_rtx (operands[6]),
24578 const0_rtx);
24579 })
24580
24581 ;; peephole2 comes before regcprop, so deal also with a case that
24582 ;; would be cleaned up by regcprop.
24583 (define_peephole2
24584 [(set (match_operand:SWI 0 "register_operand")
24585 (match_operand:SWI 1 "memory_operand"))
24586 (parallel [(set (match_dup 0)
24587 (match_operator:SWI 3 "plusminuslogic_operator"
24588 [(match_dup 0)
24589 (match_operand:SWI 2 "<nonmemory_operand>")]))
24590 (clobber (reg:CC FLAGS_REG))])
24591 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24592 (set (match_dup 1) (match_dup 4))
24593 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
24594 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24595 && peep2_reg_dead_p (3, operands[0])
24596 && peep2_reg_dead_p (5, operands[4])
24597 && !reg_overlap_mentioned_p (operands[0], operands[1])
24598 && !reg_overlap_mentioned_p (operands[0], operands[2])
24599 && !reg_overlap_mentioned_p (operands[4], operands[1])
24600 && (<MODE>mode != QImode
24601 || immediate_operand (operands[2], QImode)
24602 || any_QIreg_operand (operands[2], QImode))
24603 && ix86_match_ccmode (peep2_next_insn (4),
24604 (GET_CODE (operands[3]) == PLUS
24605 || GET_CODE (operands[3]) == MINUS)
24606 ? CCGOCmode : CCNOmode)"
24607 [(parallel [(set (match_dup 5) (match_dup 7))
24608 (set (match_dup 1) (match_dup 6))])]
24609 {
24610 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
24611 operands[6]
24612 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24613 copy_rtx (operands[1]),
24614 operands[2]);
24615 operands[7]
24616 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24617 copy_rtx (operands[6]),
24618 const0_rtx);
24619 })
24620
24621 (define_peephole2
24622 [(set (match_operand:SWI12 0 "register_operand")
24623 (match_operand:SWI12 1 "memory_operand"))
24624 (parallel [(set (match_operand:SI 4 "register_operand")
24625 (match_operator:SI 3 "plusminuslogic_operator"
24626 [(match_dup 4)
24627 (match_operand:SI 2 "nonmemory_operand")]))
24628 (clobber (reg:CC FLAGS_REG))])
24629 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
24630 (set (match_dup 1) (match_dup 5))
24631 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24632 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24633 && REGNO (operands[0]) == REGNO (operands[4])
24634 && peep2_reg_dead_p (3, operands[0])
24635 && peep2_reg_dead_p (5, operands[5])
24636 && (<MODE>mode != QImode
24637 || immediate_operand (operands[2], SImode)
24638 || any_QIreg_operand (operands[2], SImode))
24639 && !reg_overlap_mentioned_p (operands[0], operands[1])
24640 && !reg_overlap_mentioned_p (operands[0], operands[2])
24641 && !reg_overlap_mentioned_p (operands[5], operands[1])
24642 && ix86_match_ccmode (peep2_next_insn (4),
24643 (GET_CODE (operands[3]) == PLUS
24644 || GET_CODE (operands[3]) == MINUS)
24645 ? CCGOCmode : CCNOmode)"
24646 [(parallel [(set (match_dup 6) (match_dup 8))
24647 (set (match_dup 1) (match_dup 7))])]
24648 {
24649 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
24650 operands[7]
24651 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24652 copy_rtx (operands[1]),
24653 gen_lowpart (<MODE>mode, operands[2]));
24654 operands[8]
24655 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24656 copy_rtx (operands[7]),
24657 const0_rtx);
24658 })
24659
24660 ;; Likewise for cmpelim optimized pattern.
24661 (define_peephole2
24662 [(set (match_operand:SWI 0 "register_operand")
24663 (match_operand:SWI 1 "memory_operand"))
24664 (parallel [(set (reg FLAGS_REG)
24665 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24666 [(match_dup 0)
24667 (match_operand:SWI 2 "<nonmemory_operand>")])
24668 (const_int 0)))
24669 (set (match_dup 0) (match_dup 3))])
24670 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24671 (set (match_dup 1) (match_dup 4))]
24672 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24673 && peep2_reg_dead_p (3, operands[0])
24674 && peep2_reg_dead_p (4, operands[4])
24675 && !reg_overlap_mentioned_p (operands[0], operands[1])
24676 && !reg_overlap_mentioned_p (operands[0], operands[2])
24677 && !reg_overlap_mentioned_p (operands[4], operands[1])
24678 && ix86_match_ccmode (peep2_next_insn (1),
24679 (GET_CODE (operands[3]) == PLUS
24680 || GET_CODE (operands[3]) == MINUS)
24681 ? CCGOCmode : CCNOmode)"
24682 [(parallel [(set (match_dup 5) (match_dup 7))
24683 (set (match_dup 1) (match_dup 6))])]
24684 {
24685 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24686 operands[6]
24687 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24688 copy_rtx (operands[1]), operands[2]);
24689 operands[7]
24690 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
24691 const0_rtx);
24692 })
24693
24694 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
24695 ;; into x = z; x ^= y; x != z
24696 (define_peephole2
24697 [(set (match_operand:SWI 0 "register_operand")
24698 (match_operand:SWI 1 "memory_operand"))
24699 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
24700 (parallel [(set (match_operand:SWI 4 "register_operand")
24701 (xor:SWI (match_dup 4)
24702 (match_operand:SWI 2 "<nonmemory_operand>")))
24703 (clobber (reg:CC FLAGS_REG))])
24704 (set (match_dup 1) (match_dup 4))
24705 (set (reg:CCZ FLAGS_REG)
24706 (compare:CCZ (match_operand:SWI 5 "register_operand")
24707 (match_operand:SWI 6 "<nonmemory_operand>")))]
24708 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24709 && (REGNO (operands[4]) == REGNO (operands[0])
24710 || REGNO (operands[4]) == REGNO (operands[3]))
24711 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
24712 ? 3 : 0], operands[5])
24713 ? rtx_equal_p (operands[2], operands[6])
24714 : rtx_equal_p (operands[2], operands[5])
24715 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
24716 ? 3 : 0], operands[6]))
24717 && peep2_reg_dead_p (4, operands[4])
24718 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
24719 ? 3 : 0])
24720 && !reg_overlap_mentioned_p (operands[0], operands[1])
24721 && !reg_overlap_mentioned_p (operands[0], operands[2])
24722 && !reg_overlap_mentioned_p (operands[3], operands[0])
24723 && !reg_overlap_mentioned_p (operands[3], operands[1])
24724 && !reg_overlap_mentioned_p (operands[3], operands[2])
24725 && (<MODE>mode != QImode
24726 || immediate_operand (operands[2], QImode)
24727 || any_QIreg_operand (operands[2], QImode))"
24728 [(parallel [(set (match_dup 7) (match_dup 9))
24729 (set (match_dup 1) (match_dup 8))])]
24730 {
24731 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
24732 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
24733 operands[2]);
24734 operands[9]
24735 = gen_rtx_COMPARE (GET_MODE (operands[7]),
24736 copy_rtx (operands[8]),
24737 const0_rtx);
24738 })
24739
24740 (define_peephole2
24741 [(set (match_operand:SWI12 0 "register_operand")
24742 (match_operand:SWI12 1 "memory_operand"))
24743 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
24744 (parallel [(set (match_operand:SI 4 "register_operand")
24745 (xor:SI (match_dup 4)
24746 (match_operand:SI 2 "<nonmemory_operand>")))
24747 (clobber (reg:CC FLAGS_REG))])
24748 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
24749 (set (reg:CCZ FLAGS_REG)
24750 (compare:CCZ (match_operand:SWI12 6 "register_operand")
24751 (match_operand:SWI12 7 "<nonmemory_operand>")))]
24752 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24753 && (REGNO (operands[5]) == REGNO (operands[0])
24754 || REGNO (operands[5]) == REGNO (operands[3]))
24755 && REGNO (operands[5]) == REGNO (operands[4])
24756 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
24757 ? 3 : 0], operands[6])
24758 ? (REG_P (operands[2])
24759 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
24760 : rtx_equal_p (operands[2], operands[7]))
24761 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
24762 ? 3 : 0], operands[7])
24763 && REG_P (operands[2])
24764 && REGNO (operands[2]) == REGNO (operands[6])))
24765 && peep2_reg_dead_p (4, operands[5])
24766 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
24767 ? 3 : 0])
24768 && !reg_overlap_mentioned_p (operands[0], operands[1])
24769 && !reg_overlap_mentioned_p (operands[0], operands[2])
24770 && !reg_overlap_mentioned_p (operands[3], operands[0])
24771 && !reg_overlap_mentioned_p (operands[3], operands[1])
24772 && !reg_overlap_mentioned_p (operands[3], operands[2])
24773 && (<MODE>mode != QImode
24774 || immediate_operand (operands[2], SImode)
24775 || any_QIreg_operand (operands[2], SImode))"
24776 [(parallel [(set (match_dup 8) (match_dup 10))
24777 (set (match_dup 1) (match_dup 9))])]
24778 {
24779 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
24780 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
24781 gen_lowpart (<MODE>mode, operands[2]));
24782 operands[10]
24783 = gen_rtx_COMPARE (GET_MODE (operands[8]),
24784 copy_rtx (operands[9]),
24785 const0_rtx);
24786 })
24787
24788 ;; Attempt to optimize away memory stores of values the memory already
24789 ;; has. See PR79593.
24790 (define_peephole2
24791 [(set (match_operand 0 "register_operand")
24792 (match_operand 1 "memory_operand"))
24793 (set (match_operand 2 "memory_operand") (match_dup 0))]
24794 "!MEM_VOLATILE_P (operands[1])
24795 && !MEM_VOLATILE_P (operands[2])
24796 && rtx_equal_p (operands[1], operands[2])
24797 && !reg_overlap_mentioned_p (operands[0], operands[2])"
24798 [(set (match_dup 0) (match_dup 1))])
24799
24800 ;; Attempt to always use XOR for zeroing registers (including FP modes).
24801 (define_peephole2
24802 [(set (match_operand 0 "general_reg_operand")
24803 (match_operand 1 "const0_operand"))]
24804 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
24805 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24806 && peep2_regno_dead_p (0, FLAGS_REG)"
24807 [(parallel [(set (match_dup 0) (const_int 0))
24808 (clobber (reg:CC FLAGS_REG))])]
24809 "operands[0] = gen_lowpart (word_mode, operands[0]);")
24810
24811 (define_peephole2
24812 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
24813 (const_int 0))]
24814 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24815 && peep2_regno_dead_p (0, FLAGS_REG)"
24816 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
24817 (clobber (reg:CC FLAGS_REG))])])
24818
24819 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
24820 (define_peephole2
24821 [(set (match_operand:SWI248 0 "general_reg_operand")
24822 (const_int -1))]
24823 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
24824 && peep2_regno_dead_p (0, FLAGS_REG)"
24825 [(parallel [(set (match_dup 0) (const_int -1))
24826 (clobber (reg:CC FLAGS_REG))])]
24827 {
24828 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
24829 operands[0] = gen_lowpart (SImode, operands[0]);
24830 })
24831
24832 ;; Attempt to convert simple lea to add/shift.
24833 ;; These can be created by move expanders.
24834 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
24835 ;; relevant lea instructions were already split.
24836
24837 (define_peephole2
24838 [(set (match_operand:SWI48 0 "register_operand")
24839 (plus:SWI48 (match_dup 0)
24840 (match_operand:SWI48 1 "<nonmemory_operand>")))]
24841 "!TARGET_OPT_AGU
24842 && peep2_regno_dead_p (0, FLAGS_REG)"
24843 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
24844 (clobber (reg:CC FLAGS_REG))])])
24845
24846 (define_peephole2
24847 [(set (match_operand:SWI48 0 "register_operand")
24848 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
24849 (match_dup 0)))]
24850 "!TARGET_OPT_AGU
24851 && peep2_regno_dead_p (0, FLAGS_REG)"
24852 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
24853 (clobber (reg:CC FLAGS_REG))])])
24854
24855 (define_peephole2
24856 [(set (match_operand:DI 0 "register_operand")
24857 (zero_extend:DI
24858 (plus:SI (match_operand:SI 1 "register_operand")
24859 (match_operand:SI 2 "nonmemory_operand"))))]
24860 "TARGET_64BIT && !TARGET_OPT_AGU
24861 && REGNO (operands[0]) == REGNO (operands[1])
24862 && peep2_regno_dead_p (0, FLAGS_REG)"
24863 [(parallel [(set (match_dup 0)
24864 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
24865 (clobber (reg:CC FLAGS_REG))])])
24866
24867 (define_peephole2
24868 [(set (match_operand:DI 0 "register_operand")
24869 (zero_extend:DI
24870 (plus:SI (match_operand:SI 1 "nonmemory_operand")
24871 (match_operand:SI 2 "register_operand"))))]
24872 "TARGET_64BIT && !TARGET_OPT_AGU
24873 && REGNO (operands[0]) == REGNO (operands[2])
24874 && peep2_regno_dead_p (0, FLAGS_REG)"
24875 [(parallel [(set (match_dup 0)
24876 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
24877 (clobber (reg:CC FLAGS_REG))])])
24878
24879 (define_peephole2
24880 [(set (match_operand:SWI48 0 "register_operand")
24881 (mult:SWI48 (match_dup 0)
24882 (match_operand:SWI48 1 "const_int_operand")))]
24883 "pow2p_hwi (INTVAL (operands[1]))
24884 && peep2_regno_dead_p (0, FLAGS_REG)"
24885 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
24886 (clobber (reg:CC FLAGS_REG))])]
24887 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
24888
24889 (define_peephole2
24890 [(set (match_operand:DI 0 "register_operand")
24891 (zero_extend:DI
24892 (mult:SI (match_operand:SI 1 "register_operand")
24893 (match_operand:SI 2 "const_int_operand"))))]
24894 "TARGET_64BIT
24895 && pow2p_hwi (INTVAL (operands[2]))
24896 && REGNO (operands[0]) == REGNO (operands[1])
24897 && peep2_regno_dead_p (0, FLAGS_REG)"
24898 [(parallel [(set (match_dup 0)
24899 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
24900 (clobber (reg:CC FLAGS_REG))])]
24901 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
24902
24903 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
24904 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
24905 ;; On many CPUs it is also faster, since special hardware to avoid esp
24906 ;; dependencies is present.
24907
24908 ;; While some of these conversions may be done using splitters, we use
24909 ;; peepholes in order to allow combine_stack_adjustments pass to see
24910 ;; nonobfuscated RTL.
24911
24912 ;; Convert prologue esp subtractions to push.
24913 ;; We need register to push. In order to keep verify_flow_info happy we have
24914 ;; two choices
24915 ;; - use scratch and clobber it in order to avoid dependencies
24916 ;; - use already live register
24917 ;; We can't use the second way right now, since there is no reliable way how to
24918 ;; verify that given register is live. First choice will also most likely in
24919 ;; fewer dependencies. On the place of esp adjustments it is very likely that
24920 ;; call clobbered registers are dead. We may want to use base pointer as an
24921 ;; alternative when no register is available later.
24922
24923 (define_peephole2
24924 [(match_scratch:W 1 "r")
24925 (parallel [(set (reg:P SP_REG)
24926 (plus:P (reg:P SP_REG)
24927 (match_operand:P 0 "const_int_operand")))
24928 (clobber (reg:CC FLAGS_REG))
24929 (clobber (mem:BLK (scratch)))])]
24930 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
24931 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
24932 && !ix86_red_zone_used"
24933 [(clobber (match_dup 1))
24934 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24935 (clobber (mem:BLK (scratch)))])])
24936
24937 (define_peephole2
24938 [(match_scratch:W 1 "r")
24939 (parallel [(set (reg:P SP_REG)
24940 (plus:P (reg:P SP_REG)
24941 (match_operand:P 0 "const_int_operand")))
24942 (clobber (reg:CC FLAGS_REG))
24943 (clobber (mem:BLK (scratch)))])]
24944 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
24945 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
24946 && !ix86_red_zone_used"
24947 [(clobber (match_dup 1))
24948 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24949 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24950 (clobber (mem:BLK (scratch)))])])
24951
24952 ;; Convert esp subtractions to push.
24953 (define_peephole2
24954 [(match_scratch:W 1 "r")
24955 (parallel [(set (reg:P SP_REG)
24956 (plus:P (reg:P SP_REG)
24957 (match_operand:P 0 "const_int_operand")))
24958 (clobber (reg:CC FLAGS_REG))])]
24959 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
24960 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
24961 && !ix86_red_zone_used"
24962 [(clobber (match_dup 1))
24963 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
24964
24965 (define_peephole2
24966 [(match_scratch:W 1 "r")
24967 (parallel [(set (reg:P SP_REG)
24968 (plus:P (reg:P SP_REG)
24969 (match_operand:P 0 "const_int_operand")))
24970 (clobber (reg:CC FLAGS_REG))])]
24971 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
24972 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
24973 && !ix86_red_zone_used"
24974 [(clobber (match_dup 1))
24975 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24976 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
24977
24978 ;; Convert epilogue deallocator to pop.
24979 (define_peephole2
24980 [(match_scratch:W 1 "r")
24981 (parallel [(set (reg:P SP_REG)
24982 (plus:P (reg:P SP_REG)
24983 (match_operand:P 0 "const_int_operand")))
24984 (clobber (reg:CC FLAGS_REG))
24985 (clobber (mem:BLK (scratch)))])]
24986 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
24987 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
24988 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24989 (clobber (mem:BLK (scratch)))])])
24990
24991 ;; Two pops case is tricky, since pop causes dependency
24992 ;; on destination register. We use two registers if available.
24993 (define_peephole2
24994 [(match_scratch:W 1 "r")
24995 (match_scratch:W 2 "r")
24996 (parallel [(set (reg:P SP_REG)
24997 (plus:P (reg:P SP_REG)
24998 (match_operand:P 0 "const_int_operand")))
24999 (clobber (reg:CC FLAGS_REG))
25000 (clobber (mem:BLK (scratch)))])]
25001 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
25002 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25003 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25004 (clobber (mem:BLK (scratch)))])
25005 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25006
25007 (define_peephole2
25008 [(match_scratch:W 1 "r")
25009 (parallel [(set (reg:P SP_REG)
25010 (plus:P (reg:P SP_REG)
25011 (match_operand:P 0 "const_int_operand")))
25012 (clobber (reg:CC FLAGS_REG))
25013 (clobber (mem:BLK (scratch)))])]
25014 "optimize_insn_for_size_p ()
25015 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25016 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25017 (clobber (mem:BLK (scratch)))])
25018 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25019
25020 ;; Convert esp additions to pop.
25021 (define_peephole2
25022 [(match_scratch:W 1 "r")
25023 (parallel [(set (reg:P SP_REG)
25024 (plus:P (reg:P SP_REG)
25025 (match_operand:P 0 "const_int_operand")))
25026 (clobber (reg:CC FLAGS_REG))])]
25027 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
25028 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25029
25030 ;; Two pops case is tricky, since pop causes dependency
25031 ;; on destination register. We use two registers if available.
25032 (define_peephole2
25033 [(match_scratch:W 1 "r")
25034 (match_scratch:W 2 "r")
25035 (parallel [(set (reg:P SP_REG)
25036 (plus:P (reg:P SP_REG)
25037 (match_operand:P 0 "const_int_operand")))
25038 (clobber (reg:CC FLAGS_REG))])]
25039 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25040 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25041 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
25042
25043 (define_peephole2
25044 [(match_scratch:W 1 "r")
25045 (parallel [(set (reg:P SP_REG)
25046 (plus:P (reg:P SP_REG)
25047 (match_operand:P 0 "const_int_operand")))
25048 (clobber (reg:CC FLAGS_REG))])]
25049 "optimize_insn_for_size_p ()
25050 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
25051 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
25052 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
25053 \f
25054 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
25055 ;; required and register dies. Similarly for 128 to -128.
25056 (define_peephole2
25057 [(set (match_operand 0 "flags_reg_operand")
25058 (match_operator 1 "compare_operator"
25059 [(match_operand 2 "register_operand")
25060 (match_operand 3 "const_int_operand")]))]
25061 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
25062 && incdec_operand (operands[3], GET_MODE (operands[3])))
25063 || (!TARGET_FUSE_CMP_AND_BRANCH
25064 && INTVAL (operands[3]) == 128))
25065 && ix86_match_ccmode (insn, CCGCmode)
25066 && peep2_reg_dead_p (1, operands[2])"
25067 [(parallel [(set (match_dup 0)
25068 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
25069 (clobber (match_dup 2))])])
25070 \f
25071 ;; Convert imul by three, five and nine into lea
25072 (define_peephole2
25073 [(parallel
25074 [(set (match_operand:SWI48 0 "register_operand")
25075 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
25076 (match_operand:SWI48 2 "const359_operand")))
25077 (clobber (reg:CC FLAGS_REG))])]
25078 "!TARGET_PARTIAL_REG_STALL
25079 || <MODE>mode == SImode
25080 || optimize_function_for_size_p (cfun)"
25081 [(set (match_dup 0)
25082 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
25083 (match_dup 1)))]
25084 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25085
25086 (define_peephole2
25087 [(parallel
25088 [(set (match_operand:SWI48 0 "register_operand")
25089 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
25090 (match_operand:SWI48 2 "const359_operand")))
25091 (clobber (reg:CC FLAGS_REG))])]
25092 "optimize_insn_for_speed_p ()
25093 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
25094 [(set (match_dup 0) (match_dup 1))
25095 (set (match_dup 0)
25096 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
25097 (match_dup 0)))]
25098 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
25099
25100 ;; imul $32bit_imm, mem, reg is vector decoded, while
25101 ;; imul $32bit_imm, reg, reg is direct decoded.
25102 (define_peephole2
25103 [(match_scratch:SWI48 3 "r")
25104 (parallel [(set (match_operand:SWI48 0 "register_operand")
25105 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
25106 (match_operand:SWI48 2 "immediate_operand")))
25107 (clobber (reg:CC FLAGS_REG))])]
25108 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25109 && !satisfies_constraint_K (operands[2])"
25110 [(set (match_dup 3) (match_dup 1))
25111 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
25112 (clobber (reg:CC FLAGS_REG))])])
25113
25114 (define_peephole2
25115 [(match_scratch:SI 3 "r")
25116 (parallel [(set (match_operand:DI 0 "register_operand")
25117 (zero_extend:DI
25118 (mult:SI (match_operand:SI 1 "memory_operand")
25119 (match_operand:SI 2 "immediate_operand"))))
25120 (clobber (reg:CC FLAGS_REG))])]
25121 "TARGET_64BIT
25122 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25123 && !satisfies_constraint_K (operands[2])"
25124 [(set (match_dup 3) (match_dup 1))
25125 (parallel [(set (match_dup 0)
25126 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25127 (clobber (reg:CC FLAGS_REG))])])
25128
25129 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25130 ;; Convert it into imul reg, reg
25131 ;; It would be better to force assembler to encode instruction using long
25132 ;; immediate, but there is apparently no way to do so.
25133 (define_peephole2
25134 [(parallel [(set (match_operand:SWI248 0 "register_operand")
25135 (mult:SWI248
25136 (match_operand:SWI248 1 "nonimmediate_operand")
25137 (match_operand:SWI248 2 "const_int_operand")))
25138 (clobber (reg:CC FLAGS_REG))])
25139 (match_scratch:SWI248 3 "r")]
25140 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25141 && satisfies_constraint_K (operands[2])"
25142 [(set (match_dup 3) (match_dup 2))
25143 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25144 (clobber (reg:CC FLAGS_REG))])]
25145 {
25146 if (!rtx_equal_p (operands[0], operands[1]))
25147 emit_move_insn (operands[0], operands[1]);
25148 })
25149
25150 ;; After splitting up read-modify operations, array accesses with memory
25151 ;; operands might end up in form:
25152 ;; sall $2, %eax
25153 ;; movl 4(%esp), %edx
25154 ;; addl %edx, %eax
25155 ;; instead of pre-splitting:
25156 ;; sall $2, %eax
25157 ;; addl 4(%esp), %eax
25158 ;; Turn it into:
25159 ;; movl 4(%esp), %edx
25160 ;; leal (%edx,%eax,4), %eax
25161
25162 (define_peephole2
25163 [(match_scratch:W 5 "r")
25164 (parallel [(set (match_operand 0 "register_operand")
25165 (ashift (match_operand 1 "register_operand")
25166 (match_operand 2 "const_int_operand")))
25167 (clobber (reg:CC FLAGS_REG))])
25168 (parallel [(set (match_operand 3 "register_operand")
25169 (plus (match_dup 0)
25170 (match_operand 4 "x86_64_general_operand")))
25171 (clobber (reg:CC FLAGS_REG))])]
25172 "IN_RANGE (INTVAL (operands[2]), 1, 3)
25173 /* Validate MODE for lea. */
25174 && ((!TARGET_PARTIAL_REG_STALL
25175 && (GET_MODE (operands[0]) == QImode
25176 || GET_MODE (operands[0]) == HImode))
25177 || GET_MODE (operands[0]) == SImode
25178 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25179 && (rtx_equal_p (operands[0], operands[3])
25180 || peep2_reg_dead_p (2, operands[0]))
25181 /* We reorder load and the shift. */
25182 && !reg_overlap_mentioned_p (operands[0], operands[4])"
25183 [(set (match_dup 5) (match_dup 4))
25184 (set (match_dup 0) (match_dup 1))]
25185 {
25186 machine_mode op1mode = GET_MODE (operands[1]);
25187 machine_mode mode = op1mode == DImode ? DImode : SImode;
25188 int scale = 1 << INTVAL (operands[2]);
25189 rtx index = gen_lowpart (word_mode, operands[1]);
25190 rtx base = gen_lowpart (word_mode, operands[5]);
25191 rtx dest = gen_lowpart (mode, operands[3]);
25192
25193 operands[1] = gen_rtx_PLUS (word_mode, base,
25194 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25195 if (mode != word_mode)
25196 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25197
25198 operands[5] = base;
25199 if (op1mode != word_mode)
25200 operands[5] = gen_lowpart (op1mode, operands[5]);
25201
25202 operands[0] = dest;
25203 })
25204 \f
25205 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25206 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25207 ;; caught for use by garbage collectors and the like. Using an insn that
25208 ;; maps to SIGILL makes it more likely the program will rightfully die.
25209 ;; Keeping with tradition, "6" is in honor of #UD.
25210 (define_insn "trap"
25211 [(trap_if (const_int 1) (const_int 6))]
25212 ""
25213 {
25214 #ifdef HAVE_AS_IX86_UD2
25215 return "ud2";
25216 #else
25217 return ASM_SHORT "0x0b0f";
25218 #endif
25219 }
25220 [(set_attr "length" "2")])
25221
25222 (define_insn "ud2"
25223 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25224 ""
25225 {
25226 #ifdef HAVE_AS_IX86_UD2
25227 return "ud2";
25228 #else
25229 return ASM_SHORT "0x0b0f";
25230 #endif
25231 }
25232 [(set_attr "length" "2")])
25233
25234 (define_expand "prefetch"
25235 [(prefetch (match_operand 0 "address_operand")
25236 (match_operand:SI 1 "const_int_operand")
25237 (match_operand:SI 2 "const_int_operand"))]
25238 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25239 {
25240 bool write = operands[1] != const0_rtx;
25241 int locality = INTVAL (operands[2]);
25242
25243 gcc_assert (IN_RANGE (locality, 0, 3));
25244
25245 /* Use 3dNOW prefetch in case we are asking for write prefetch not
25246 supported by SSE counterpart (non-SSE2 athlon machines) or the
25247 SSE prefetch is not available (K6 machines). Otherwise use SSE
25248 prefetch as it allows specifying of locality. */
25249
25250 if (write)
25251 {
25252 if (TARGET_PREFETCHWT1)
25253 operands[2] = GEN_INT (MAX (locality, 2));
25254 else if (TARGET_PRFCHW)
25255 operands[2] = GEN_INT (3);
25256 else if (TARGET_3DNOW && !TARGET_SSE2)
25257 operands[2] = GEN_INT (3);
25258 else if (TARGET_PREFETCH_SSE)
25259 operands[1] = const0_rtx;
25260 else
25261 {
25262 gcc_assert (TARGET_3DNOW);
25263 operands[2] = GEN_INT (3);
25264 }
25265 }
25266 else
25267 {
25268 if (TARGET_PREFETCH_SSE)
25269 ;
25270 else
25271 {
25272 gcc_assert (TARGET_3DNOW);
25273 operands[2] = GEN_INT (3);
25274 }
25275 }
25276 })
25277
25278 (define_insn "*prefetch_sse"
25279 [(prefetch (match_operand 0 "address_operand" "p")
25280 (const_int 0)
25281 (match_operand:SI 1 "const_int_operand"))]
25282 "TARGET_PREFETCH_SSE"
25283 {
25284 static const char * const patterns[4] = {
25285 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25286 };
25287
25288 int locality = INTVAL (operands[1]);
25289 gcc_assert (IN_RANGE (locality, 0, 3));
25290
25291 return patterns[locality];
25292 }
25293 [(set_attr "type" "sse")
25294 (set_attr "atom_sse_attr" "prefetch")
25295 (set (attr "length_address")
25296 (symbol_ref "memory_address_length (operands[0], false)"))
25297 (set_attr "memory" "none")])
25298
25299 (define_insn "*prefetch_3dnow"
25300 [(prefetch (match_operand 0 "address_operand" "p")
25301 (match_operand:SI 1 "const_int_operand")
25302 (const_int 3))]
25303 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25304 {
25305 if (operands[1] == const0_rtx)
25306 return "prefetch\t%a0";
25307 else
25308 return "prefetchw\t%a0";
25309 }
25310 [(set_attr "type" "mmx")
25311 (set (attr "length_address")
25312 (symbol_ref "memory_address_length (operands[0], false)"))
25313 (set_attr "memory" "none")])
25314
25315 (define_insn "*prefetch_prefetchwt1"
25316 [(prefetch (match_operand 0 "address_operand" "p")
25317 (const_int 1)
25318 (const_int 2))]
25319 "TARGET_PREFETCHWT1"
25320 "prefetchwt1\t%a0";
25321 [(set_attr "type" "sse")
25322 (set (attr "length_address")
25323 (symbol_ref "memory_address_length (operands[0], false)"))
25324 (set_attr "memory" "none")])
25325
25326 (define_insn "prefetchi"
25327 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
25328 (match_operand:SI 1 "const_int_operand")]
25329 UNSPECV_PREFETCHI)]
25330 "TARGET_PREFETCHI && TARGET_64BIT"
25331 {
25332 static const char * const patterns[2] = {
25333 "prefetchit1\t%0", "prefetchit0\t%0"
25334 };
25335
25336 int locality = INTVAL (operands[1]);
25337 gcc_assert (IN_RANGE (locality, 2, 3));
25338
25339 return patterns[locality - 2];
25340 }
25341 [(set_attr "type" "sse")
25342 (set (attr "length_address")
25343 (symbol_ref "memory_address_length (operands[0], false)"))
25344 (set_attr "memory" "none")])
25345
25346 (define_expand "stack_protect_set"
25347 [(match_operand 0 "memory_operand")
25348 (match_operand 1 "memory_operand")]
25349 ""
25350 {
25351 emit_insn (gen_stack_protect_set_1
25352 (ptr_mode, operands[0], operands[1]));
25353 DONE;
25354 })
25355
25356 (define_insn "@stack_protect_set_1_<mode>"
25357 [(set (match_operand:PTR 0 "memory_operand" "=m")
25358 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
25359 UNSPEC_SP_SET))
25360 (set (match_scratch:PTR 2 "=&r") (const_int 0))
25361 (clobber (reg:CC FLAGS_REG))]
25362 ""
25363 {
25364 output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
25365 output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
25366 return "xor{l}\t%k2, %k2";
25367 }
25368 [(set_attr "type" "multi")])
25369
25370 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
25371 ;; immediately followed by *mov{s,d}i_internal to the same register,
25372 ;; where we can avoid the xor{l} above. We don't split this, so that
25373 ;; scheduling or anything else doesn't separate the *stack_protect_set*
25374 ;; pattern from the set of the register that overwrites the register
25375 ;; with a new value.
25376 (define_insn "*stack_protect_set_2_<mode>"
25377 [(set (match_operand:PTR 0 "memory_operand" "=m")
25378 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25379 UNSPEC_SP_SET))
25380 (set (match_operand:SI 1 "register_operand" "=&r")
25381 (match_operand:SI 2 "general_operand" "g"))
25382 (clobber (reg:CC FLAGS_REG))]
25383 "reload_completed
25384 && !reg_overlap_mentioned_p (operands[1], operands[2])"
25385 {
25386 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25387 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25388 if (pic_32bit_operand (operands[2], SImode)
25389 || ix86_use_lea_for_mov (insn, operands + 1))
25390 return "lea{l}\t{%E2, %1|%1, %E2}";
25391 else
25392 return "mov{l}\t{%2, %1|%1, %2}";
25393 }
25394 [(set_attr "type" "multi")
25395 (set_attr "length" "24")])
25396
25397 (define_peephole2
25398 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25399 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25400 UNSPEC_SP_SET))
25401 (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
25402 (clobber (reg:CC FLAGS_REG))])
25403 (set (match_operand:SI 3 "general_reg_operand")
25404 (match_operand:SI 4))]
25405 "REGNO (operands[2]) == REGNO (operands[3])
25406 && general_operand (operands[4], SImode)
25407 && (general_reg_operand (operands[4], SImode)
25408 || memory_operand (operands[4], SImode)
25409 || immediate_operand (operands[4], SImode))
25410 && !reg_overlap_mentioned_p (operands[3], operands[4])"
25411 [(parallel [(set (match_dup 0)
25412 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25413 (set (match_dup 3) (match_dup 4))
25414 (clobber (reg:CC FLAGS_REG))])])
25415
25416 (define_insn "*stack_protect_set_3"
25417 [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
25418 (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
25419 UNSPEC_SP_SET))
25420 (set (match_operand:DI 1 "register_operand" "=&r,r,r")
25421 (match_operand:DI 2 "general_operand" "Z,rem,i"))
25422 (clobber (reg:CC FLAGS_REG))]
25423 "TARGET_64BIT
25424 && reload_completed
25425 && !reg_overlap_mentioned_p (operands[1], operands[2])"
25426 {
25427 output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
25428 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
25429 if (pic_32bit_operand (operands[2], DImode))
25430 return "lea{q}\t{%E2, %1|%1, %E2}";
25431 else if (which_alternative == 0)
25432 return "mov{l}\t{%k2, %k1|%k1, %k2}";
25433 else if (which_alternative == 2)
25434 return "movabs{q}\t{%2, %1|%1, %2}";
25435 else if (ix86_use_lea_for_mov (insn, operands + 1))
25436 return "lea{q}\t{%E2, %1|%1, %E2}";
25437 else
25438 return "mov{q}\t{%2, %1|%1, %2}";
25439 }
25440 [(set_attr "type" "multi")
25441 (set_attr "length" "24")])
25442
25443 (define_peephole2
25444 [(parallel [(set (match_operand:DI 0 "memory_operand")
25445 (unspec:DI [(match_operand:DI 1 "memory_operand")]
25446 UNSPEC_SP_SET))
25447 (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
25448 (clobber (reg:CC FLAGS_REG))])
25449 (set (match_dup 2) (match_operand:DI 3))]
25450 "TARGET_64BIT
25451 && general_operand (operands[3], DImode)
25452 && (general_reg_operand (operands[3], DImode)
25453 || memory_operand (operands[3], DImode)
25454 || x86_64_zext_immediate_operand (operands[3], DImode)
25455 || x86_64_immediate_operand (operands[3], DImode)
25456 || (CONSTANT_P (operands[3])
25457 && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
25458 && !reg_overlap_mentioned_p (operands[2], operands[3])"
25459 [(parallel [(set (match_dup 0)
25460 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25461 (set (match_dup 2) (match_dup 3))
25462 (clobber (reg:CC FLAGS_REG))])])
25463
25464 (define_expand "stack_protect_test"
25465 [(match_operand 0 "memory_operand")
25466 (match_operand 1 "memory_operand")
25467 (match_operand 2)]
25468 ""
25469 {
25470 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
25471
25472 emit_insn (gen_stack_protect_test_1
25473 (ptr_mode, flags, operands[0], operands[1]));
25474
25475 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
25476 flags, const0_rtx, operands[2]));
25477 DONE;
25478 })
25479
25480 (define_insn "@stack_protect_test_1_<mode>"
25481 [(set (match_operand:CCZ 0 "flags_reg_operand")
25482 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
25483 (match_operand:PTR 2 "memory_operand" "m")]
25484 UNSPEC_SP_TEST))
25485 (clobber (match_scratch:PTR 3 "=&r"))]
25486 ""
25487 {
25488 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
25489 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
25490 }
25491 [(set_attr "type" "multi")])
25492
25493 (define_insn "sse4_2_crc32<mode>"
25494 [(set (match_operand:SI 0 "register_operand" "=r")
25495 (unspec:SI
25496 [(match_operand:SI 1 "register_operand" "0")
25497 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
25498 UNSPEC_CRC32))]
25499 "TARGET_CRC32"
25500 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
25501 [(set_attr "type" "sselog1")
25502 (set_attr "prefix_rep" "1")
25503 (set_attr "prefix_extra" "1")
25504 (set (attr "prefix_data16")
25505 (if_then_else (match_operand:HI 2)
25506 (const_string "1")
25507 (const_string "*")))
25508 (set (attr "prefix_rex")
25509 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
25510 (const_string "1")
25511 (const_string "*")))
25512 (set_attr "mode" "SI")])
25513
25514 (define_insn "sse4_2_crc32di"
25515 [(set (match_operand:DI 0 "register_operand" "=r")
25516 (zero_extend:DI
25517 (unspec:SI
25518 [(match_operand:SI 1 "register_operand" "0")
25519 (match_operand:DI 2 "nonimmediate_operand" "rm")]
25520 UNSPEC_CRC32)))]
25521 "TARGET_64BIT && TARGET_CRC32"
25522 "crc32{q}\t{%2, %0|%0, %2}"
25523 [(set_attr "type" "sselog1")
25524 (set_attr "prefix_rep" "1")
25525 (set_attr "prefix_extra" "1")
25526 (set_attr "mode" "DI")])
25527
25528 (define_insn "rdpmc"
25529 [(set (match_operand:DI 0 "register_operand" "=A")
25530 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25531 UNSPECV_RDPMC))]
25532 "!TARGET_64BIT"
25533 "rdpmc"
25534 [(set_attr "type" "other")
25535 (set_attr "length" "2")])
25536
25537 (define_insn "rdpmc_rex64"
25538 [(set (match_operand:DI 0 "register_operand" "=a")
25539 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25540 UNSPECV_RDPMC))
25541 (set (match_operand:DI 1 "register_operand" "=d")
25542 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
25543 "TARGET_64BIT"
25544 "rdpmc"
25545 [(set_attr "type" "other")
25546 (set_attr "length" "2")])
25547
25548 (define_insn "rdtsc"
25549 [(set (match_operand:DI 0 "register_operand" "=A")
25550 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25551 "!TARGET_64BIT"
25552 "rdtsc"
25553 [(set_attr "type" "other")
25554 (set_attr "length" "2")])
25555
25556 (define_insn "rdtsc_rex64"
25557 [(set (match_operand:DI 0 "register_operand" "=a")
25558 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
25559 (set (match_operand:DI 1 "register_operand" "=d")
25560 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25561 "TARGET_64BIT"
25562 "rdtsc"
25563 [(set_attr "type" "other")
25564 (set_attr "length" "2")])
25565
25566 (define_insn "rdtscp"
25567 [(set (match_operand:DI 0 "register_operand" "=A")
25568 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25569 (set (match_operand:SI 1 "register_operand" "=c")
25570 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25571 "!TARGET_64BIT"
25572 "rdtscp"
25573 [(set_attr "type" "other")
25574 (set_attr "length" "3")])
25575
25576 (define_insn "rdtscp_rex64"
25577 [(set (match_operand:DI 0 "register_operand" "=a")
25578 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25579 (set (match_operand:DI 1 "register_operand" "=d")
25580 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25581 (set (match_operand:SI 2 "register_operand" "=c")
25582 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25583 "TARGET_64BIT"
25584 "rdtscp"
25585 [(set_attr "type" "other")
25586 (set_attr "length" "3")])
25587
25588 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25589 ;;
25590 ;; FXSR, XSAVE and XSAVEOPT instructions
25591 ;;
25592 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25593
25594 (define_insn "fxsave"
25595 [(set (match_operand:BLK 0 "memory_operand" "=m")
25596 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
25597 "TARGET_FXSR"
25598 "fxsave\t%0"
25599 [(set_attr "type" "other")
25600 (set_attr "memory" "store")
25601 (set (attr "length")
25602 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25603
25604 (define_insn "fxsave64"
25605 [(set (match_operand:BLK 0 "memory_operand" "=m")
25606 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
25607 "TARGET_64BIT && TARGET_FXSR"
25608 "fxsave64\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) + 4"))])
25613
25614 (define_insn "fxrstor"
25615 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25616 UNSPECV_FXRSTOR)]
25617 "TARGET_FXSR"
25618 "fxrstor\t%0"
25619 [(set_attr "type" "other")
25620 (set_attr "memory" "load")
25621 (set (attr "length")
25622 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25623
25624 (define_insn "fxrstor64"
25625 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25626 UNSPECV_FXRSTOR64)]
25627 "TARGET_64BIT && TARGET_FXSR"
25628 "fxrstor64\t%0"
25629 [(set_attr "type" "other")
25630 (set_attr "memory" "load")
25631 (set (attr "length")
25632 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25633
25634 (define_int_iterator ANY_XSAVE
25635 [UNSPECV_XSAVE
25636 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
25637 (UNSPECV_XSAVEC "TARGET_XSAVEC")
25638 (UNSPECV_XSAVES "TARGET_XSAVES")])
25639
25640 (define_int_iterator ANY_XSAVE64
25641 [UNSPECV_XSAVE64
25642 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
25643 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
25644 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
25645
25646 (define_int_attr xsave
25647 [(UNSPECV_XSAVE "xsave")
25648 (UNSPECV_XSAVE64 "xsave64")
25649 (UNSPECV_XSAVEOPT "xsaveopt")
25650 (UNSPECV_XSAVEOPT64 "xsaveopt64")
25651 (UNSPECV_XSAVEC "xsavec")
25652 (UNSPECV_XSAVEC64 "xsavec64")
25653 (UNSPECV_XSAVES "xsaves")
25654 (UNSPECV_XSAVES64 "xsaves64")])
25655
25656 (define_int_iterator ANY_XRSTOR
25657 [UNSPECV_XRSTOR
25658 (UNSPECV_XRSTORS "TARGET_XSAVES")])
25659
25660 (define_int_iterator ANY_XRSTOR64
25661 [UNSPECV_XRSTOR64
25662 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
25663
25664 (define_int_attr xrstor
25665 [(UNSPECV_XRSTOR "xrstor")
25666 (UNSPECV_XRSTOR64 "xrstor")
25667 (UNSPECV_XRSTORS "xrstors")
25668 (UNSPECV_XRSTORS64 "xrstors")])
25669
25670 (define_insn "<xsave>"
25671 [(set (match_operand:BLK 0 "memory_operand" "=m")
25672 (unspec_volatile:BLK
25673 [(match_operand:DI 1 "register_operand" "A")]
25674 ANY_XSAVE))]
25675 "!TARGET_64BIT && TARGET_XSAVE"
25676 "<xsave>\t%0"
25677 [(set_attr "type" "other")
25678 (set_attr "memory" "store")
25679 (set (attr "length")
25680 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25681
25682 (define_insn "<xsave>_rex64"
25683 [(set (match_operand:BLK 0 "memory_operand" "=m")
25684 (unspec_volatile:BLK
25685 [(match_operand:SI 1 "register_operand" "a")
25686 (match_operand:SI 2 "register_operand" "d")]
25687 ANY_XSAVE))]
25688 "TARGET_64BIT && TARGET_XSAVE"
25689 "<xsave>\t%0"
25690 [(set_attr "type" "other")
25691 (set_attr "memory" "store")
25692 (set (attr "length")
25693 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25694
25695 (define_insn "<xsave>"
25696 [(set (match_operand:BLK 0 "memory_operand" "=m")
25697 (unspec_volatile:BLK
25698 [(match_operand:SI 1 "register_operand" "a")
25699 (match_operand:SI 2 "register_operand" "d")]
25700 ANY_XSAVE64))]
25701 "TARGET_64BIT && TARGET_XSAVE"
25702 "<xsave>\t%0"
25703 [(set_attr "type" "other")
25704 (set_attr "memory" "store")
25705 (set (attr "length")
25706 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25707
25708 (define_insn "<xrstor>"
25709 [(unspec_volatile:BLK
25710 [(match_operand:BLK 0 "memory_operand" "m")
25711 (match_operand:DI 1 "register_operand" "A")]
25712 ANY_XRSTOR)]
25713 "!TARGET_64BIT && TARGET_XSAVE"
25714 "<xrstor>\t%0"
25715 [(set_attr "type" "other")
25716 (set_attr "memory" "load")
25717 (set (attr "length")
25718 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25719
25720 (define_insn "<xrstor>_rex64"
25721 [(unspec_volatile:BLK
25722 [(match_operand:BLK 0 "memory_operand" "m")
25723 (match_operand:SI 1 "register_operand" "a")
25724 (match_operand:SI 2 "register_operand" "d")]
25725 ANY_XRSTOR)]
25726 "TARGET_64BIT && TARGET_XSAVE"
25727 "<xrstor>\t%0"
25728 [(set_attr "type" "other")
25729 (set_attr "memory" "load")
25730 (set (attr "length")
25731 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25732
25733 (define_insn "<xrstor>64"
25734 [(unspec_volatile:BLK
25735 [(match_operand:BLK 0 "memory_operand" "m")
25736 (match_operand:SI 1 "register_operand" "a")
25737 (match_operand:SI 2 "register_operand" "d")]
25738 ANY_XRSTOR64)]
25739 "TARGET_64BIT && TARGET_XSAVE"
25740 "<xrstor>64\t%0"
25741 [(set_attr "type" "other")
25742 (set_attr "memory" "load")
25743 (set (attr "length")
25744 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25745
25746 (define_insn "xsetbv"
25747 [(unspec_volatile:SI
25748 [(match_operand:SI 0 "register_operand" "c")
25749 (match_operand:DI 1 "register_operand" "A")]
25750 UNSPECV_XSETBV)]
25751 "!TARGET_64BIT && TARGET_XSAVE"
25752 "xsetbv"
25753 [(set_attr "type" "other")])
25754
25755 (define_insn "xsetbv_rex64"
25756 [(unspec_volatile:SI
25757 [(match_operand:SI 0 "register_operand" "c")
25758 (match_operand:SI 1 "register_operand" "a")
25759 (match_operand:SI 2 "register_operand" "d")]
25760 UNSPECV_XSETBV)]
25761 "TARGET_64BIT && TARGET_XSAVE"
25762 "xsetbv"
25763 [(set_attr "type" "other")])
25764
25765 (define_insn "xgetbv"
25766 [(set (match_operand:DI 0 "register_operand" "=A")
25767 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25768 UNSPECV_XGETBV))]
25769 "!TARGET_64BIT && TARGET_XSAVE"
25770 "xgetbv"
25771 [(set_attr "type" "other")])
25772
25773 (define_insn "xgetbv_rex64"
25774 [(set (match_operand:DI 0 "register_operand" "=a")
25775 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25776 UNSPECV_XGETBV))
25777 (set (match_operand:DI 1 "register_operand" "=d")
25778 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
25779 "TARGET_64BIT && TARGET_XSAVE"
25780 "xgetbv"
25781 [(set_attr "type" "other")])
25782
25783 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25784 ;;
25785 ;; Floating-point instructions for atomic compound assignments
25786 ;;
25787 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25788
25789 ; Clobber all floating-point registers on environment save and restore
25790 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
25791 (define_insn "fnstenv"
25792 [(set (match_operand:BLK 0 "memory_operand" "=m")
25793 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
25794 (clobber (reg:XF ST0_REG))
25795 (clobber (reg:XF ST1_REG))
25796 (clobber (reg:XF ST2_REG))
25797 (clobber (reg:XF ST3_REG))
25798 (clobber (reg:XF ST4_REG))
25799 (clobber (reg:XF ST5_REG))
25800 (clobber (reg:XF ST6_REG))
25801 (clobber (reg:XF ST7_REG))]
25802 "TARGET_80387"
25803 "fnstenv\t%0"
25804 [(set_attr "type" "other")
25805 (set_attr "memory" "store")
25806 (set (attr "length")
25807 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25808
25809 (define_insn "fldenv"
25810 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25811 UNSPECV_FLDENV)
25812 (clobber (reg:XF ST0_REG))
25813 (clobber (reg:XF ST1_REG))
25814 (clobber (reg:XF ST2_REG))
25815 (clobber (reg:XF ST3_REG))
25816 (clobber (reg:XF ST4_REG))
25817 (clobber (reg:XF ST5_REG))
25818 (clobber (reg:XF ST6_REG))
25819 (clobber (reg:XF ST7_REG))]
25820 "TARGET_80387"
25821 "fldenv\t%0"
25822 [(set_attr "type" "other")
25823 (set_attr "memory" "load")
25824 (set (attr "length")
25825 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25826
25827 (define_insn "fnstsw"
25828 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
25829 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
25830 "TARGET_80387"
25831 "fnstsw\t%0"
25832 [(set_attr "type" "other,other")
25833 (set_attr "memory" "none,store")
25834 (set (attr "length")
25835 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25836
25837 (define_insn "fnclex"
25838 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
25839 "TARGET_80387"
25840 "fnclex"
25841 [(set_attr "type" "other")
25842 (set_attr "memory" "none")
25843 (set_attr "length" "2")])
25844
25845 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25846 ;;
25847 ;; LWP instructions
25848 ;;
25849 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25850
25851 (define_insn "@lwp_llwpcb<mode>"
25852 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
25853 UNSPECV_LLWP_INTRINSIC)]
25854 "TARGET_LWP"
25855 "llwpcb\t%0"
25856 [(set_attr "type" "lwp")
25857 (set_attr "mode" "<MODE>")
25858 (set_attr "length" "5")])
25859
25860 (define_insn "@lwp_slwpcb<mode>"
25861 [(set (match_operand:P 0 "register_operand" "=r")
25862 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
25863 "TARGET_LWP"
25864 "slwpcb\t%0"
25865 [(set_attr "type" "lwp")
25866 (set_attr "mode" "<MODE>")
25867 (set_attr "length" "5")])
25868
25869 (define_insn "@lwp_lwpval<mode>"
25870 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25871 (match_operand:SI 1 "nonimmediate_operand" "rm")
25872 (match_operand:SI 2 "const_int_operand")]
25873 UNSPECV_LWPVAL_INTRINSIC)]
25874 "TARGET_LWP"
25875 "lwpval\t{%2, %1, %0|%0, %1, %2}"
25876 [(set_attr "type" "lwp")
25877 (set_attr "mode" "<MODE>")
25878 (set (attr "length")
25879 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
25880
25881 (define_insn "@lwp_lwpins<mode>"
25882 [(set (reg:CCC FLAGS_REG)
25883 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
25884 (match_operand:SI 1 "nonimmediate_operand" "rm")
25885 (match_operand:SI 2 "const_int_operand")]
25886 UNSPECV_LWPINS_INTRINSIC))]
25887 "TARGET_LWP"
25888 "lwpins\t{%2, %1, %0|%0, %1, %2}"
25889 [(set_attr "type" "lwp")
25890 (set_attr "mode" "<MODE>")
25891 (set (attr "length")
25892 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
25893
25894 (define_int_iterator RDFSGSBASE
25895 [UNSPECV_RDFSBASE
25896 UNSPECV_RDGSBASE])
25897
25898 (define_int_iterator WRFSGSBASE
25899 [UNSPECV_WRFSBASE
25900 UNSPECV_WRGSBASE])
25901
25902 (define_int_attr fsgs
25903 [(UNSPECV_RDFSBASE "fs")
25904 (UNSPECV_RDGSBASE "gs")
25905 (UNSPECV_WRFSBASE "fs")
25906 (UNSPECV_WRGSBASE "gs")])
25907
25908 (define_insn "rd<fsgs>base<mode>"
25909 [(set (match_operand:SWI48 0 "register_operand" "=r")
25910 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
25911 "TARGET_64BIT && TARGET_FSGSBASE"
25912 "rd<fsgs>base\t%0"
25913 [(set_attr "type" "other")
25914 (set_attr "prefix_extra" "2")])
25915
25916 (define_insn "wr<fsgs>base<mode>"
25917 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
25918 WRFSGSBASE)]
25919 "TARGET_64BIT && TARGET_FSGSBASE"
25920 "wr<fsgs>base\t%0"
25921 [(set_attr "type" "other")
25922 (set_attr "prefix_extra" "2")])
25923
25924 (define_insn "ptwrite<mode>"
25925 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
25926 UNSPECV_PTWRITE)]
25927 "TARGET_PTWRITE"
25928 "ptwrite\t%0"
25929 [(set_attr "type" "other")
25930 (set_attr "prefix_extra" "2")])
25931
25932 (define_insn "@rdrand<mode>"
25933 [(set (match_operand:SWI248 0 "register_operand" "=r")
25934 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
25935 (set (reg:CCC FLAGS_REG)
25936 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
25937 "TARGET_RDRND"
25938 "rdrand\t%0"
25939 [(set_attr "type" "other")
25940 (set_attr "prefix_extra" "1")])
25941
25942 (define_insn "@rdseed<mode>"
25943 [(set (match_operand:SWI248 0 "register_operand" "=r")
25944 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
25945 (set (reg:CCC FLAGS_REG)
25946 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
25947 "TARGET_RDSEED"
25948 "rdseed\t%0"
25949 [(set_attr "type" "other")
25950 (set_attr "prefix_extra" "1")])
25951
25952 (define_expand "pause"
25953 [(set (match_dup 0)
25954 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
25955 ""
25956 {
25957 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
25958 MEM_VOLATILE_P (operands[0]) = 1;
25959 })
25960
25961 ;; Use "rep; nop", instead of "pause", to support older assemblers.
25962 ;; They have the same encoding.
25963 (define_insn "*pause"
25964 [(set (match_operand:BLK 0)
25965 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
25966 ""
25967 "rep%; nop"
25968 [(set_attr "length" "2")
25969 (set_attr "memory" "unknown")])
25970
25971 ;; CET instructions
25972 (define_insn "@rdssp<mode>"
25973 [(set (match_operand:SWI48 0 "register_operand" "=r")
25974 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
25975 UNSPECV_NOP_RDSSP))]
25976 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
25977 "rdssp<mskmodesuffix>\t%0"
25978 [(set_attr "length" "6")
25979 (set_attr "type" "other")])
25980
25981 (define_insn "@incssp<mode>"
25982 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
25983 UNSPECV_INCSSP)]
25984 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
25985 "incssp<mskmodesuffix>\t%0"
25986 [(set_attr "length" "4")
25987 (set_attr "type" "other")])
25988
25989 (define_insn "saveprevssp"
25990 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
25991 "TARGET_SHSTK"
25992 "saveprevssp"
25993 [(set_attr "length" "5")
25994 (set_attr "type" "other")])
25995
25996 (define_insn "rstorssp"
25997 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
25998 UNSPECV_RSTORSSP)]
25999 "TARGET_SHSTK"
26000 "rstorssp\t%0"
26001 [(set_attr "length" "5")
26002 (set_attr "type" "other")])
26003
26004 (define_insn "@wrss<mode>"
26005 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26006 (match_operand:SWI48 1 "memory_operand" "m")]
26007 UNSPECV_WRSS)]
26008 "TARGET_SHSTK"
26009 "wrss<mskmodesuffix>\t%0, %1"
26010 [(set_attr "length" "3")
26011 (set_attr "type" "other")])
26012
26013 (define_insn "@wruss<mode>"
26014 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
26015 (match_operand:SWI48 1 "memory_operand" "m")]
26016 UNSPECV_WRUSS)]
26017 "TARGET_SHSTK"
26018 "wruss<mskmodesuffix>\t%0, %1"
26019 [(set_attr "length" "4")
26020 (set_attr "type" "other")])
26021
26022 (define_insn "setssbsy"
26023 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
26024 "TARGET_SHSTK"
26025 "setssbsy"
26026 [(set_attr "length" "4")
26027 (set_attr "type" "other")])
26028
26029 (define_insn "clrssbsy"
26030 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
26031 UNSPECV_CLRSSBSY)]
26032 "TARGET_SHSTK"
26033 "clrssbsy\t%0"
26034 [(set_attr "length" "4")
26035 (set_attr "type" "other")])
26036
26037 (define_insn "nop_endbr"
26038 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
26039 "(flag_cf_protection & CF_BRANCH)"
26040 {
26041 return TARGET_64BIT ? "endbr64" : "endbr32";
26042 }
26043 [(set_attr "length" "4")
26044 (set_attr "length_immediate" "0")
26045 (set_attr "modrm" "0")])
26046
26047 ;; For RTM support
26048 (define_expand "xbegin"
26049 [(set (match_operand:SI 0 "register_operand")
26050 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
26051 "TARGET_RTM"
26052 {
26053 rtx_code_label *label = gen_label_rtx ();
26054
26055 /* xbegin is emitted as jump_insn, so reload won't be able
26056 to reload its operand. Force the value into AX hard register. */
26057 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
26058 emit_move_insn (ax_reg, constm1_rtx);
26059
26060 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
26061
26062 emit_label (label);
26063 LABEL_NUSES (label) = 1;
26064
26065 emit_move_insn (operands[0], ax_reg);
26066
26067 DONE;
26068 })
26069
26070 (define_insn "xbegin_1"
26071 [(set (pc)
26072 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
26073 (const_int 0))
26074 (label_ref (match_operand 1))
26075 (pc)))
26076 (set (match_operand:SI 0 "register_operand" "+a")
26077 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
26078 "TARGET_RTM"
26079 "xbegin\t%l1"
26080 [(set_attr "type" "other")
26081 (set_attr "length" "6")])
26082
26083 (define_insn "xend"
26084 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
26085 "TARGET_RTM"
26086 "xend"
26087 [(set_attr "type" "other")
26088 (set_attr "length" "3")])
26089
26090 (define_insn "xabort"
26091 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
26092 UNSPECV_XABORT)]
26093 "TARGET_RTM"
26094 "xabort\t%0"
26095 [(set_attr "type" "other")
26096 (set_attr "length" "3")])
26097
26098 (define_expand "xtest"
26099 [(set (match_operand:QI 0 "register_operand")
26100 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
26101 "TARGET_RTM"
26102 {
26103 emit_insn (gen_xtest_1 ());
26104
26105 ix86_expand_setcc (operands[0], NE,
26106 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
26107 DONE;
26108 })
26109
26110 (define_insn "xtest_1"
26111 [(set (reg:CCZ FLAGS_REG)
26112 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
26113 "TARGET_RTM"
26114 "xtest"
26115 [(set_attr "type" "other")
26116 (set_attr "length" "3")])
26117
26118 (define_insn "clwb"
26119 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26120 UNSPECV_CLWB)]
26121 "TARGET_CLWB"
26122 "clwb\t%a0"
26123 [(set_attr "type" "sse")
26124 (set_attr "atom_sse_attr" "fence")
26125 (set_attr "memory" "unknown")])
26126
26127 (define_insn "clflushopt"
26128 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26129 UNSPECV_CLFLUSHOPT)]
26130 "TARGET_CLFLUSHOPT"
26131 "clflushopt\t%a0"
26132 [(set_attr "type" "sse")
26133 (set_attr "atom_sse_attr" "fence")
26134 (set_attr "memory" "unknown")])
26135
26136 ;; MONITORX and MWAITX
26137 (define_insn "mwaitx"
26138 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26139 (match_operand:SI 1 "register_operand" "a")
26140 (match_operand:SI 2 "register_operand" "b")]
26141 UNSPECV_MWAITX)]
26142 "TARGET_MWAITX"
26143 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26144 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26145 ;; we only need to set up 32bit registers.
26146 "mwaitx"
26147 [(set_attr "length" "3")])
26148
26149 (define_insn "@monitorx_<mode>"
26150 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26151 (match_operand:SI 1 "register_operand" "c")
26152 (match_operand:SI 2 "register_operand" "d")]
26153 UNSPECV_MONITORX)]
26154 "TARGET_MWAITX"
26155 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26156 ;; RCX and RDX are used. Since 32bit register operands are implicitly
26157 ;; zero extended to 64bit, we only need to set up 32bit registers.
26158 "%^monitorx"
26159 [(set (attr "length")
26160 (symbol_ref ("(Pmode != word_mode) + 3")))])
26161
26162 ;; CLZERO
26163 (define_insn "@clzero_<mode>"
26164 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26165 UNSPECV_CLZERO)]
26166 "TARGET_CLZERO"
26167 "clzero"
26168 [(set_attr "length" "3")
26169 (set_attr "memory" "unknown")])
26170
26171 ;; RDPKRU and WRPKRU
26172
26173 (define_expand "rdpkru"
26174 [(parallel
26175 [(set (match_operand:SI 0 "register_operand")
26176 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26177 (set (match_dup 2) (const_int 0))])]
26178 "TARGET_PKU"
26179 {
26180 operands[1] = force_reg (SImode, const0_rtx);
26181 operands[2] = gen_reg_rtx (SImode);
26182 })
26183
26184 (define_insn "*rdpkru"
26185 [(set (match_operand:SI 0 "register_operand" "=a")
26186 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26187 UNSPECV_PKU))
26188 (set (match_operand:SI 1 "register_operand" "=d")
26189 (const_int 0))]
26190 "TARGET_PKU"
26191 "rdpkru"
26192 [(set_attr "type" "other")])
26193
26194 (define_expand "wrpkru"
26195 [(unspec_volatile:SI
26196 [(match_operand:SI 0 "register_operand")
26197 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26198 "TARGET_PKU"
26199 {
26200 operands[1] = force_reg (SImode, const0_rtx);
26201 operands[2] = force_reg (SImode, const0_rtx);
26202 })
26203
26204 (define_insn "*wrpkru"
26205 [(unspec_volatile:SI
26206 [(match_operand:SI 0 "register_operand" "a")
26207 (match_operand:SI 1 "register_operand" "d")
26208 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26209 "TARGET_PKU"
26210 "wrpkru"
26211 [(set_attr "type" "other")])
26212
26213 (define_insn "rdpid"
26214 [(set (match_operand:SI 0 "register_operand" "=r")
26215 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26216 "!TARGET_64BIT && TARGET_RDPID"
26217 "rdpid\t%0"
26218 [(set_attr "type" "other")])
26219
26220 (define_insn "rdpid_rex64"
26221 [(set (match_operand:DI 0 "register_operand" "=r")
26222 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26223 "TARGET_64BIT && TARGET_RDPID"
26224 "rdpid\t%0"
26225 [(set_attr "type" "other")])
26226
26227 ;; Intirinsics for > i486
26228
26229 (define_insn "wbinvd"
26230 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26231 ""
26232 "wbinvd"
26233 [(set_attr "type" "other")])
26234
26235 (define_insn "wbnoinvd"
26236 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26237 "TARGET_WBNOINVD"
26238 "wbnoinvd"
26239 [(set_attr "type" "other")])
26240
26241 ;; MOVDIRI and MOVDIR64B
26242
26243 (define_insn "movdiri<mode>"
26244 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26245 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26246 UNSPEC_MOVDIRI))]
26247 "TARGET_MOVDIRI"
26248 "movdiri\t{%1, %0|%0, %1}"
26249 [(set_attr "type" "other")])
26250
26251 (define_insn "@movdir64b_<mode>"
26252 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26253 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26254 UNSPEC_MOVDIR64B))]
26255 "TARGET_MOVDIR64B"
26256 "movdir64b\t{%1, %0|%0, %1}"
26257 [(set_attr "type" "other")])
26258
26259 ;; TSXLDTRK
26260 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26261 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26262 (UNSPECV_XRESLDTRK "xresldtrk")])
26263 (define_insn "<tsxldtrk>"
26264 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26265 "TARGET_TSXLDTRK"
26266 "<tsxldtrk>"
26267 [(set_attr "type" "other")
26268 (set_attr "length" "4")])
26269
26270 ;; ENQCMD and ENQCMDS
26271
26272 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26273 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26274
26275 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26276 [(set (reg:CCZ FLAGS_REG)
26277 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26278 (match_operand:XI 1 "memory_operand" "m")]
26279 ENQCMD))]
26280 "TARGET_ENQCMD"
26281 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26282 [(set_attr "type" "other")])
26283
26284 ;; UINTR
26285 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26286 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26287
26288 (define_insn "<uintr>"
26289 [(unspec_volatile [(const_int 0)] UINTR)]
26290 "TARGET_UINTR && TARGET_64BIT"
26291 "<uintr>"
26292 [(set_attr "type" "other")
26293 (set_attr "length" "4")])
26294
26295 (define_insn "testui"
26296 [(set (reg:CCC FLAGS_REG)
26297 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26298 "TARGET_UINTR && TARGET_64BIT"
26299 "testui"
26300 [(set_attr "type" "other")
26301 (set_attr "length" "4")])
26302
26303 (define_insn "senduipi"
26304 [(unspec_volatile
26305 [(match_operand:DI 0 "register_operand" "r")]
26306 UNSPECV_SENDUIPI)]
26307 "TARGET_UINTR && TARGET_64BIT"
26308 "senduipi\t%0"
26309 [(set_attr "type" "other")
26310 (set_attr "length" "4")])
26311
26312 ;; WAITPKG
26313
26314 (define_insn "umwait"
26315 [(set (reg:CCC FLAGS_REG)
26316 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26317 (match_operand:DI 1 "register_operand" "A")]
26318 UNSPECV_UMWAIT))]
26319 "!TARGET_64BIT && TARGET_WAITPKG"
26320 "umwait\t%0"
26321 [(set_attr "length" "3")])
26322
26323 (define_insn "umwait_rex64"
26324 [(set (reg:CCC FLAGS_REG)
26325 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26326 (match_operand:SI 1 "register_operand" "a")
26327 (match_operand:SI 2 "register_operand" "d")]
26328 UNSPECV_UMWAIT))]
26329 "TARGET_64BIT && TARGET_WAITPKG"
26330 "umwait\t%0"
26331 [(set_attr "length" "3")])
26332
26333 (define_insn "@umonitor_<mode>"
26334 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26335 UNSPECV_UMONITOR)]
26336 "TARGET_WAITPKG"
26337 "umonitor\t%0"
26338 [(set (attr "length")
26339 (symbol_ref ("(Pmode != word_mode) + 3")))])
26340
26341 (define_insn "tpause"
26342 [(set (reg:CCC FLAGS_REG)
26343 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26344 (match_operand:DI 1 "register_operand" "A")]
26345 UNSPECV_TPAUSE))]
26346 "!TARGET_64BIT && TARGET_WAITPKG"
26347 "tpause\t%0"
26348 [(set_attr "length" "3")])
26349
26350 (define_insn "tpause_rex64"
26351 [(set (reg:CCC FLAGS_REG)
26352 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26353 (match_operand:SI 1 "register_operand" "a")
26354 (match_operand:SI 2 "register_operand" "d")]
26355 UNSPECV_TPAUSE))]
26356 "TARGET_64BIT && TARGET_WAITPKG"
26357 "tpause\t%0"
26358 [(set_attr "length" "3")])
26359
26360 (define_insn "cldemote"
26361 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26362 UNSPECV_CLDEMOTE)]
26363 "TARGET_CLDEMOTE"
26364 "cldemote\t%a0"
26365 [(set_attr "type" "other")
26366 (set_attr "memory" "unknown")])
26367
26368 (define_insn "speculation_barrier"
26369 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26370 ""
26371 "lfence"
26372 [(set_attr "type" "other")
26373 (set_attr "length" "3")])
26374
26375 (define_insn "serialize"
26376 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26377 "TARGET_SERIALIZE"
26378 "serialize"
26379 [(set_attr "type" "other")
26380 (set_attr "length" "3")])
26381
26382 (define_insn "patchable_area"
26383 [(unspec_volatile [(match_operand 0 "const_int_operand")
26384 (match_operand 1 "const_int_operand")]
26385 UNSPECV_PATCHABLE_AREA)]
26386 ""
26387 {
26388 ix86_output_patchable_area (INTVAL (operands[0]),
26389 INTVAL (operands[1]) != 0);
26390 return "";
26391 }
26392 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26393 (set_attr "length_immediate" "0")
26394 (set_attr "modrm" "0")])
26395
26396 (define_insn "hreset"
26397 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26398 UNSPECV_HRESET)]
26399 "TARGET_HRESET"
26400 "hreset\t{$0|0}"
26401 [(set_attr "type" "other")
26402 (set_attr "length" "4")])
26403
26404 ;; Spaceship optimization
26405 (define_expand "spaceship<mode>3"
26406 [(match_operand:SI 0 "register_operand")
26407 (match_operand:MODEF 1 "cmp_fp_expander_operand")
26408 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26409 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26410 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26411 {
26412 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26413 DONE;
26414 })
26415
26416 (define_expand "spaceshipxf3"
26417 [(match_operand:SI 0 "register_operand")
26418 (match_operand:XF 1 "nonmemory_operand")
26419 (match_operand:XF 2 "nonmemory_operand")]
26420 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26421 {
26422 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26423 DONE;
26424 })
26425
26426 ;; Defined because the generic expand_builtin_issignaling for XFmode
26427 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26428 ;; signaling.
26429 (define_expand "issignalingxf2"
26430 [(match_operand:SI 0 "register_operand")
26431 (match_operand:XF 1 "general_operand")]
26432 ""
26433 {
26434 rtx temp = operands[1];
26435 if (!MEM_P (temp))
26436 {
26437 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26438 emit_move_insn (mem, temp);
26439 temp = mem;
26440 }
26441 rtx ex = adjust_address (temp, HImode, 8);
26442 rtx hi = adjust_address (temp, SImode, 4);
26443 rtx lo = adjust_address (temp, SImode, 0);
26444 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26445 rtx mask = GEN_INT (0x7fff);
26446 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26447 /* Expand to:
26448 ((ex & mask) && (int) hi >= 0)
26449 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
26450 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26451 lo = expand_binop (SImode, ior_optab, lo, nlo,
26452 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26453 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26454 temp = expand_binop (SImode, xor_optab, hi, bit,
26455 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26456 temp = expand_binop (SImode, ior_optab, temp, lo,
26457 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26458 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
26459 SImode, 1, 1);
26460 ex = expand_binop (HImode, and_optab, ex, mask,
26461 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26462 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
26463 ex, const0_rtx, SImode, 1, 1);
26464 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
26465 ex, mask, HImode, 1, 1);
26466 temp = expand_binop (SImode, and_optab, temp, ex,
26467 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26468 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
26469 hi, const0_rtx, SImode, 0, 1);
26470 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
26471 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26472 temp = expand_binop (SImode, ior_optab, temp, temp2,
26473 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26474 emit_move_insn (operands[0], temp);
26475 DONE;
26476 })
26477
26478 (include "mmx.md")
26479 (include "sse.md")
26480 (include "sync.md")