]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
x86: improve fast bfloat->float conversion
[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 "*add<mode>_1"
6298 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6299 (plus:SWI48
6300 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6301 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6302 (clobber (reg:CC FLAGS_REG))]
6303 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6304 {
6305 switch (get_attr_type (insn))
6306 {
6307 case TYPE_LEA:
6308 return "#";
6309
6310 case TYPE_INCDEC:
6311 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6312 if (operands[2] == const1_rtx)
6313 return "inc{<imodesuffix>}\t%0";
6314 else
6315 {
6316 gcc_assert (operands[2] == constm1_rtx);
6317 return "dec{<imodesuffix>}\t%0";
6318 }
6319
6320 default:
6321 /* For most processors, ADD is faster than LEA. This alternative
6322 was added to use ADD as much as possible. */
6323 if (which_alternative == 2)
6324 std::swap (operands[1], operands[2]);
6325
6326 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6327 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6328 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6329
6330 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6331 }
6332 }
6333 [(set (attr "type")
6334 (cond [(eq_attr "alternative" "3")
6335 (const_string "lea")
6336 (match_operand:SWI48 2 "incdec_operand")
6337 (const_string "incdec")
6338 ]
6339 (const_string "alu")))
6340 (set (attr "length_immediate")
6341 (if_then_else
6342 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6343 (const_string "1")
6344 (const_string "*")))
6345 (set_attr "mode" "<MODE>")])
6346
6347 ;; It may seem that nonimmediate operand is proper one for operand 1.
6348 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6349 ;; we take care in ix86_binary_operator_ok to not allow two memory
6350 ;; operands so proper swapping will be done in reload. This allow
6351 ;; patterns constructed from addsi_1 to match.
6352
6353 (define_insn "addsi_1_zext"
6354 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6355 (zero_extend:DI
6356 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6357 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6358 (clobber (reg:CC FLAGS_REG))]
6359 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6360 {
6361 switch (get_attr_type (insn))
6362 {
6363 case TYPE_LEA:
6364 return "#";
6365
6366 case TYPE_INCDEC:
6367 if (operands[2] == const1_rtx)
6368 return "inc{l}\t%k0";
6369 else
6370 {
6371 gcc_assert (operands[2] == constm1_rtx);
6372 return "dec{l}\t%k0";
6373 }
6374
6375 default:
6376 /* For most processors, ADD is faster than LEA. This alternative
6377 was added to use ADD as much as possible. */
6378 if (which_alternative == 1)
6379 std::swap (operands[1], operands[2]);
6380
6381 if (x86_maybe_negate_const_int (&operands[2], SImode))
6382 return "sub{l}\t{%2, %k0|%k0, %2}";
6383
6384 return "add{l}\t{%2, %k0|%k0, %2}";
6385 }
6386 }
6387 [(set (attr "type")
6388 (cond [(eq_attr "alternative" "2")
6389 (const_string "lea")
6390 (match_operand:SI 2 "incdec_operand")
6391 (const_string "incdec")
6392 ]
6393 (const_string "alu")))
6394 (set (attr "length_immediate")
6395 (if_then_else
6396 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6397 (const_string "1")
6398 (const_string "*")))
6399 (set_attr "mode" "SI")])
6400
6401 (define_insn "*addhi_1"
6402 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6403 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6404 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6405 (clobber (reg:CC FLAGS_REG))]
6406 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6407 {
6408 switch (get_attr_type (insn))
6409 {
6410 case TYPE_LEA:
6411 return "#";
6412
6413 case TYPE_INCDEC:
6414 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6415 if (operands[2] == const1_rtx)
6416 return "inc{w}\t%0";
6417 else
6418 {
6419 gcc_assert (operands[2] == constm1_rtx);
6420 return "dec{w}\t%0";
6421 }
6422
6423 default:
6424 /* For most processors, ADD is faster than LEA. This alternative
6425 was added to use ADD as much as possible. */
6426 if (which_alternative == 2)
6427 std::swap (operands[1], operands[2]);
6428
6429 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6430 if (x86_maybe_negate_const_int (&operands[2], HImode))
6431 return "sub{w}\t{%2, %0|%0, %2}";
6432
6433 return "add{w}\t{%2, %0|%0, %2}";
6434 }
6435 }
6436 [(set (attr "type")
6437 (cond [(eq_attr "alternative" "3")
6438 (const_string "lea")
6439 (match_operand:HI 2 "incdec_operand")
6440 (const_string "incdec")
6441 ]
6442 (const_string "alu")))
6443 (set (attr "length_immediate")
6444 (if_then_else
6445 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6446 (const_string "1")
6447 (const_string "*")))
6448 (set_attr "mode" "HI,HI,HI,SI")])
6449
6450 (define_insn "*addqi_1"
6451 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6452 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6453 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6454 (clobber (reg:CC FLAGS_REG))]
6455 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6456 {
6457 bool widen = (get_attr_mode (insn) != MODE_QI);
6458
6459 switch (get_attr_type (insn))
6460 {
6461 case TYPE_LEA:
6462 return "#";
6463
6464 case TYPE_INCDEC:
6465 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6466 if (operands[2] == const1_rtx)
6467 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6468 else
6469 {
6470 gcc_assert (operands[2] == constm1_rtx);
6471 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6472 }
6473
6474 default:
6475 /* For most processors, ADD is faster than LEA. These alternatives
6476 were added to use ADD as much as possible. */
6477 if (which_alternative == 2 || which_alternative == 4)
6478 std::swap (operands[1], operands[2]);
6479
6480 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6481 if (x86_maybe_negate_const_int (&operands[2], QImode))
6482 {
6483 if (widen)
6484 return "sub{l}\t{%2, %k0|%k0, %2}";
6485 else
6486 return "sub{b}\t{%2, %0|%0, %2}";
6487 }
6488 if (widen)
6489 return "add{l}\t{%k2, %k0|%k0, %k2}";
6490 else
6491 return "add{b}\t{%2, %0|%0, %2}";
6492 }
6493 }
6494 [(set (attr "type")
6495 (cond [(eq_attr "alternative" "5")
6496 (const_string "lea")
6497 (match_operand:QI 2 "incdec_operand")
6498 (const_string "incdec")
6499 ]
6500 (const_string "alu")))
6501 (set (attr "length_immediate")
6502 (if_then_else
6503 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6504 (const_string "1")
6505 (const_string "*")))
6506 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6507 ;; Potential partial reg stall on alternatives 3 and 4.
6508 (set (attr "preferred_for_speed")
6509 (cond [(eq_attr "alternative" "3,4")
6510 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6511 (symbol_ref "true")))])
6512
6513 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6514 (define_insn_and_split "*add<mode>_1_slp"
6515 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6516 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6517 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6518 (clobber (reg:CC FLAGS_REG))]
6519 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6520 {
6521 if (which_alternative)
6522 return "#";
6523
6524 switch (get_attr_type (insn))
6525 {
6526 case TYPE_INCDEC:
6527 if (operands[2] == const1_rtx)
6528 return "inc{<imodesuffix>}\t%0";
6529 else
6530 {
6531 gcc_assert (operands[2] == constm1_rtx);
6532 return "dec{<imodesuffix>}\t%0";
6533 }
6534
6535 default:
6536 if (x86_maybe_negate_const_int (&operands[2], QImode))
6537 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6538
6539 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6540 }
6541 }
6542 "&& reload_completed"
6543 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6544 (parallel
6545 [(set (strict_low_part (match_dup 0))
6546 (plus:SWI12 (match_dup 0) (match_dup 2)))
6547 (clobber (reg:CC FLAGS_REG))])]
6548 ""
6549 [(set (attr "type")
6550 (if_then_else (match_operand:QI 2 "incdec_operand")
6551 (const_string "incdec")
6552 (const_string "alu")))
6553 (set_attr "mode" "<MODE>")])
6554
6555 ;; Split non destructive adds if we cannot use lea.
6556 (define_split
6557 [(set (match_operand:SWI48 0 "register_operand")
6558 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6559 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6560 (clobber (reg:CC FLAGS_REG))]
6561 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6562 [(set (match_dup 0) (match_dup 1))
6563 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6564 (clobber (reg:CC FLAGS_REG))])])
6565
6566 ;; Split non destructive adds if we cannot use lea.
6567 (define_split
6568 [(set (match_operand:DI 0 "register_operand")
6569 (zero_extend:DI
6570 (plus:SI (match_operand:SI 1 "register_operand")
6571 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6572 (clobber (reg:CC FLAGS_REG))]
6573 "TARGET_64BIT
6574 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6575 [(set (match_dup 3) (match_dup 1))
6576 (parallel [(set (match_dup 0)
6577 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6578 (clobber (reg:CC FLAGS_REG))])]
6579 "operands[3] = gen_lowpart (SImode, operands[0]);")
6580
6581 ;; Convert add to the lea pattern to avoid flags dependency.
6582 (define_split
6583 [(set (match_operand:SWI 0 "register_operand")
6584 (plus:SWI (match_operand:SWI 1 "register_operand")
6585 (match_operand:SWI 2 "<nonmemory_operand>")))
6586 (clobber (reg:CC FLAGS_REG))]
6587 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6588 [(set (match_dup 0)
6589 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6590 {
6591 if (<MODE>mode != <LEAMODE>mode)
6592 {
6593 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6594 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6595 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6596 }
6597 })
6598
6599 ;; Convert add to the lea pattern to avoid flags dependency.
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 && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6607 [(set (match_dup 0)
6608 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6609
6610 (define_insn "*add<mode>_2"
6611 [(set (reg FLAGS_REG)
6612 (compare
6613 (plus:SWI
6614 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6615 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6616 (const_int 0)))
6617 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6618 (plus:SWI (match_dup 1) (match_dup 2)))]
6619 "ix86_match_ccmode (insn, CCGOCmode)
6620 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6621 {
6622 switch (get_attr_type (insn))
6623 {
6624 case TYPE_INCDEC:
6625 if (operands[2] == const1_rtx)
6626 return "inc{<imodesuffix>}\t%0";
6627 else
6628 {
6629 gcc_assert (operands[2] == constm1_rtx);
6630 return "dec{<imodesuffix>}\t%0";
6631 }
6632
6633 default:
6634 if (which_alternative == 2)
6635 std::swap (operands[1], operands[2]);
6636
6637 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6638 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6639 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6640
6641 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6642 }
6643 }
6644 [(set (attr "type")
6645 (if_then_else (match_operand:SWI 2 "incdec_operand")
6646 (const_string "incdec")
6647 (const_string "alu")))
6648 (set (attr "length_immediate")
6649 (if_then_else
6650 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6651 (const_string "1")
6652 (const_string "*")))
6653 (set_attr "mode" "<MODE>")])
6654
6655 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6656 (define_insn "*addsi_2_zext"
6657 [(set (reg FLAGS_REG)
6658 (compare
6659 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6660 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6661 (const_int 0)))
6662 (set (match_operand:DI 0 "register_operand" "=r,r")
6663 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6664 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6666 {
6667 switch (get_attr_type (insn))
6668 {
6669 case TYPE_INCDEC:
6670 if (operands[2] == const1_rtx)
6671 return "inc{l}\t%k0";
6672 else
6673 {
6674 gcc_assert (operands[2] == constm1_rtx);
6675 return "dec{l}\t%k0";
6676 }
6677
6678 default:
6679 if (which_alternative == 1)
6680 std::swap (operands[1], operands[2]);
6681
6682 if (x86_maybe_negate_const_int (&operands[2], SImode))
6683 return "sub{l}\t{%2, %k0|%k0, %2}";
6684
6685 return "add{l}\t{%2, %k0|%k0, %2}";
6686 }
6687 }
6688 [(set (attr "type")
6689 (if_then_else (match_operand:SI 2 "incdec_operand")
6690 (const_string "incdec")
6691 (const_string "alu")))
6692 (set (attr "length_immediate")
6693 (if_then_else
6694 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6695 (const_string "1")
6696 (const_string "*")))
6697 (set_attr "mode" "SI")])
6698
6699 (define_insn "*add<mode>_3"
6700 [(set (reg FLAGS_REG)
6701 (compare
6702 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6703 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6704 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6705 "ix86_match_ccmode (insn, CCZmode)
6706 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6707 {
6708 switch (get_attr_type (insn))
6709 {
6710 case TYPE_INCDEC:
6711 if (operands[2] == const1_rtx)
6712 return "inc{<imodesuffix>}\t%0";
6713 else
6714 {
6715 gcc_assert (operands[2] == constm1_rtx);
6716 return "dec{<imodesuffix>}\t%0";
6717 }
6718
6719 default:
6720 if (which_alternative == 1)
6721 std::swap (operands[1], operands[2]);
6722
6723 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6724 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6725 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6726
6727 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6728 }
6729 }
6730 [(set (attr "type")
6731 (if_then_else (match_operand:SWI 2 "incdec_operand")
6732 (const_string "incdec")
6733 (const_string "alu")))
6734 (set (attr "length_immediate")
6735 (if_then_else
6736 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6737 (const_string "1")
6738 (const_string "*")))
6739 (set_attr "mode" "<MODE>")])
6740
6741 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6742 (define_insn "*addsi_3_zext"
6743 [(set (reg FLAGS_REG)
6744 (compare
6745 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6746 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6747 (set (match_operand:DI 0 "register_operand" "=r,r")
6748 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6749 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6750 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6751 {
6752 switch (get_attr_type (insn))
6753 {
6754 case TYPE_INCDEC:
6755 if (operands[2] == const1_rtx)
6756 return "inc{l}\t%k0";
6757 else
6758 {
6759 gcc_assert (operands[2] == constm1_rtx);
6760 return "dec{l}\t%k0";
6761 }
6762
6763 default:
6764 if (which_alternative == 1)
6765 std::swap (operands[1], operands[2]);
6766
6767 if (x86_maybe_negate_const_int (&operands[2], SImode))
6768 return "sub{l}\t{%2, %k0|%k0, %2}";
6769
6770 return "add{l}\t{%2, %k0|%k0, %2}";
6771 }
6772 }
6773 [(set (attr "type")
6774 (if_then_else (match_operand:SI 2 "incdec_operand")
6775 (const_string "incdec")
6776 (const_string "alu")))
6777 (set (attr "length_immediate")
6778 (if_then_else
6779 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6780 (const_string "1")
6781 (const_string "*")))
6782 (set_attr "mode" "SI")])
6783
6784 ; For comparisons against 1, -1 and 128, we may generate better code
6785 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6786 ; is matched then. We can't accept general immediate, because for
6787 ; case of overflows, the result is messed up.
6788 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6789 ; only for comparisons not depending on it.
6790
6791 (define_insn "*adddi_4"
6792 [(set (reg FLAGS_REG)
6793 (compare
6794 (match_operand:DI 1 "nonimmediate_operand" "0")
6795 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6796 (clobber (match_scratch:DI 0 "=r"))]
6797 "TARGET_64BIT
6798 && ix86_match_ccmode (insn, CCGCmode)"
6799 {
6800 switch (get_attr_type (insn))
6801 {
6802 case TYPE_INCDEC:
6803 if (operands[2] == constm1_rtx)
6804 return "inc{q}\t%0";
6805 else
6806 {
6807 gcc_assert (operands[2] == const1_rtx);
6808 return "dec{q}\t%0";
6809 }
6810
6811 default:
6812 if (x86_maybe_negate_const_int (&operands[2], DImode))
6813 return "add{q}\t{%2, %0|%0, %2}";
6814
6815 return "sub{q}\t{%2, %0|%0, %2}";
6816 }
6817 }
6818 [(set (attr "type")
6819 (if_then_else (match_operand:DI 2 "incdec_operand")
6820 (const_string "incdec")
6821 (const_string "alu")))
6822 (set (attr "length_immediate")
6823 (if_then_else
6824 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6825 (const_string "1")
6826 (const_string "*")))
6827 (set_attr "mode" "DI")])
6828
6829 ; For comparisons against 1, -1 and 128, we may generate better code
6830 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6831 ; is matched then. We can't accept general immediate, because for
6832 ; case of overflows, the result is messed up.
6833 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6834 ; only for comparisons not depending on it.
6835
6836 (define_insn "*add<mode>_4"
6837 [(set (reg FLAGS_REG)
6838 (compare
6839 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6840 (match_operand:SWI124 2 "const_int_operand")))
6841 (clobber (match_scratch:SWI124 0 "=<r>"))]
6842 "ix86_match_ccmode (insn, CCGCmode)"
6843 {
6844 switch (get_attr_type (insn))
6845 {
6846 case TYPE_INCDEC:
6847 if (operands[2] == constm1_rtx)
6848 return "inc{<imodesuffix>}\t%0";
6849 else
6850 {
6851 gcc_assert (operands[2] == const1_rtx);
6852 return "dec{<imodesuffix>}\t%0";
6853 }
6854
6855 default:
6856 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6857 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6858
6859 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6860 }
6861 }
6862 [(set (attr "type")
6863 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6864 (const_string "incdec")
6865 (const_string "alu")))
6866 (set (attr "length_immediate")
6867 (if_then_else
6868 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6869 (const_string "1")
6870 (const_string "*")))
6871 (set_attr "mode" "<MODE>")])
6872
6873 (define_insn "*add<mode>_5"
6874 [(set (reg FLAGS_REG)
6875 (compare
6876 (plus:SWI
6877 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6878 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6879 (const_int 0)))
6880 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6881 "ix86_match_ccmode (insn, CCGOCmode)
6882 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6883 {
6884 switch (get_attr_type (insn))
6885 {
6886 case TYPE_INCDEC:
6887 if (operands[2] == const1_rtx)
6888 return "inc{<imodesuffix>}\t%0";
6889 else
6890 {
6891 gcc_assert (operands[2] == constm1_rtx);
6892 return "dec{<imodesuffix>}\t%0";
6893 }
6894
6895 default:
6896 if (which_alternative == 1)
6897 std::swap (operands[1], operands[2]);
6898
6899 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6900 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6901 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6902
6903 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6904 }
6905 }
6906 [(set (attr "type")
6907 (if_then_else (match_operand:SWI 2 "incdec_operand")
6908 (const_string "incdec")
6909 (const_string "alu")))
6910 (set (attr "length_immediate")
6911 (if_then_else
6912 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6913 (const_string "1")
6914 (const_string "*")))
6915 (set_attr "mode" "<MODE>")])
6916
6917 (define_insn "*addqi_ext<mode>_0"
6918 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
6919 (plus:QI
6920 (subreg:QI
6921 (match_operator:SWI248 3 "extract_operator"
6922 [(match_operand 2 "int248_register_operand" "Q,Q")
6923 (const_int 8)
6924 (const_int 8)]) 0)
6925 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
6926 (clobber (reg:CC FLAGS_REG))]
6927 ""
6928 "add{b}\t{%h2, %0|%0, %h2}"
6929 [(set_attr "isa" "*,nox64")
6930 (set_attr "type" "alu")
6931 (set_attr "mode" "QI")])
6932
6933 (define_expand "addqi_ext_1"
6934 [(parallel
6935 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
6936 (const_int 8)
6937 (const_int 8))
6938 (subreg:HI
6939 (plus:QI
6940 (subreg:QI
6941 (zero_extract:HI (match_operand:HI 1 "register_operand")
6942 (const_int 8)
6943 (const_int 8)) 0)
6944 (match_operand:QI 2 "const_int_operand")) 0))
6945 (clobber (reg:CC FLAGS_REG))])])
6946
6947 (define_insn "*addqi_ext<mode>_1"
6948 [(set (zero_extract:SWI248
6949 (match_operand 0 "int248_register_operand" "+Q,Q")
6950 (const_int 8)
6951 (const_int 8))
6952 (subreg:SWI248
6953 (plus:QI
6954 (subreg:QI
6955 (match_operator:SWI248 3 "extract_operator"
6956 [(match_operand 1 "int248_register_operand" "0,0")
6957 (const_int 8)
6958 (const_int 8)]) 0)
6959 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
6960 (clobber (reg:CC FLAGS_REG))]
6961 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6962 rtx_equal_p (operands[0], operands[1])"
6963 {
6964 switch (get_attr_type (insn))
6965 {
6966 case TYPE_INCDEC:
6967 if (operands[2] == const1_rtx)
6968 return "inc{b}\t%h0";
6969 else
6970 {
6971 gcc_assert (operands[2] == constm1_rtx);
6972 return "dec{b}\t%h0";
6973 }
6974
6975 default:
6976 return "add{b}\t{%2, %h0|%h0, %2}";
6977 }
6978 }
6979 [(set_attr "isa" "*,nox64")
6980 (set (attr "type")
6981 (if_then_else (match_operand:QI 2 "incdec_operand")
6982 (const_string "incdec")
6983 (const_string "alu")))
6984 (set_attr "mode" "QI")])
6985
6986 (define_insn "*addqi_ext<mode>_2"
6987 [(set (zero_extract:SWI248
6988 (match_operand 0 "int248_register_operand" "+Q")
6989 (const_int 8)
6990 (const_int 8))
6991 (subreg:SWI248
6992 (plus:QI
6993 (subreg:QI
6994 (match_operator:SWI248 3 "extract_operator"
6995 [(match_operand 1 "int248_register_operand" "%0")
6996 (const_int 8)
6997 (const_int 8)]) 0)
6998 (subreg:QI
6999 (match_operator:SWI248 4 "extract_operator"
7000 [(match_operand 2 "int248_register_operand" "Q")
7001 (const_int 8)
7002 (const_int 8)]) 0)) 0))
7003 (clobber (reg:CC FLAGS_REG))]
7004 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7005 rtx_equal_p (operands[0], operands[1])
7006 || rtx_equal_p (operands[0], operands[2])"
7007 "add{b}\t{%h2, %h0|%h0, %h2}"
7008 [(set_attr "type" "alu")
7009 (set_attr "mode" "QI")])
7010
7011 ;; Like DWI, but use POImode instead of OImode.
7012 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
7013
7014 ;; Add with jump on overflow.
7015 (define_expand "addv<mode>4"
7016 [(parallel [(set (reg:CCO FLAGS_REG)
7017 (eq:CCO
7018 (plus:<DPWI>
7019 (sign_extend:<DPWI>
7020 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7021 (match_dup 4))
7022 (sign_extend:<DPWI>
7023 (plus:SWIDWI (match_dup 1)
7024 (match_operand:SWIDWI 2
7025 "<general_hilo_operand>")))))
7026 (set (match_operand:SWIDWI 0 "register_operand")
7027 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7028 (set (pc) (if_then_else
7029 (eq (reg:CCO FLAGS_REG) (const_int 0))
7030 (label_ref (match_operand 3))
7031 (pc)))]
7032 ""
7033 {
7034 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
7035 if (CONST_SCALAR_INT_P (operands[2]))
7036 operands[4] = operands[2];
7037 else
7038 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7039 })
7040
7041 (define_insn "*addv<mode>4"
7042 [(set (reg:CCO FLAGS_REG)
7043 (eq:CCO (plus:<DWI>
7044 (sign_extend:<DWI>
7045 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7046 (sign_extend:<DWI>
7047 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7048 (sign_extend:<DWI>
7049 (plus:SWI (match_dup 1) (match_dup 2)))))
7050 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7051 (plus:SWI (match_dup 1) (match_dup 2)))]
7052 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7053 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7054 [(set_attr "type" "alu")
7055 (set_attr "mode" "<MODE>")])
7056
7057 (define_insn "addv<mode>4_1"
7058 [(set (reg:CCO FLAGS_REG)
7059 (eq:CCO (plus:<DWI>
7060 (sign_extend:<DWI>
7061 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7062 (match_operand:<DWI> 3 "const_int_operand"))
7063 (sign_extend:<DWI>
7064 (plus:SWI
7065 (match_dup 1)
7066 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7067 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7068 (plus:SWI (match_dup 1) (match_dup 2)))]
7069 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7070 && CONST_INT_P (operands[2])
7071 && INTVAL (operands[2]) == INTVAL (operands[3])"
7072 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7073 [(set_attr "type" "alu")
7074 (set_attr "mode" "<MODE>")
7075 (set (attr "length_immediate")
7076 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7077 (const_string "1")
7078 (match_test "<MODE_SIZE> == 8")
7079 (const_string "4")]
7080 (const_string "<MODE_SIZE>")))])
7081
7082 ;; Quad word integer modes as mode attribute.
7083 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7084
7085 (define_insn_and_split "*addv<dwi>4_doubleword"
7086 [(set (reg:CCO FLAGS_REG)
7087 (eq:CCO
7088 (plus:<QPWI>
7089 (sign_extend:<QPWI>
7090 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7091 (sign_extend:<QPWI>
7092 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7093 (sign_extend:<QPWI>
7094 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7095 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7096 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7097 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7098 "#"
7099 "&& reload_completed"
7100 [(parallel [(set (reg:CCC FLAGS_REG)
7101 (compare:CCC
7102 (plus:DWIH (match_dup 1) (match_dup 2))
7103 (match_dup 1)))
7104 (set (match_dup 0)
7105 (plus:DWIH (match_dup 1) (match_dup 2)))])
7106 (parallel [(set (reg:CCO FLAGS_REG)
7107 (eq:CCO
7108 (plus:<DWI>
7109 (plus:<DWI>
7110 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7111 (sign_extend:<DWI> (match_dup 4)))
7112 (sign_extend:<DWI> (match_dup 5)))
7113 (sign_extend:<DWI>
7114 (plus:DWIH
7115 (plus:DWIH
7116 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7117 (match_dup 4))
7118 (match_dup 5)))))
7119 (set (match_dup 3)
7120 (plus:DWIH
7121 (plus:DWIH
7122 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7123 (match_dup 4))
7124 (match_dup 5)))])]
7125 {
7126 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7127 })
7128
7129 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7130 [(set (reg:CCO FLAGS_REG)
7131 (eq:CCO
7132 (plus:<QPWI>
7133 (sign_extend:<QPWI>
7134 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7135 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7136 (sign_extend:<QPWI>
7137 (plus:<DWI>
7138 (match_dup 1)
7139 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7140 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7141 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7142 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7143 && CONST_SCALAR_INT_P (operands[2])
7144 && rtx_equal_p (operands[2], operands[3])"
7145 "#"
7146 "&& reload_completed"
7147 [(parallel [(set (reg:CCC FLAGS_REG)
7148 (compare:CCC
7149 (plus:DWIH (match_dup 1) (match_dup 2))
7150 (match_dup 1)))
7151 (set (match_dup 0)
7152 (plus:DWIH (match_dup 1) (match_dup 2)))])
7153 (parallel [(set (reg:CCO FLAGS_REG)
7154 (eq:CCO
7155 (plus:<DWI>
7156 (plus:<DWI>
7157 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7158 (sign_extend:<DWI> (match_dup 4)))
7159 (match_dup 5))
7160 (sign_extend:<DWI>
7161 (plus:DWIH
7162 (plus:DWIH
7163 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7164 (match_dup 4))
7165 (match_dup 5)))))
7166 (set (match_dup 3)
7167 (plus:DWIH
7168 (plus:DWIH
7169 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7170 (match_dup 4))
7171 (match_dup 5)))])]
7172 {
7173 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7174 if (operands[2] == const0_rtx)
7175 {
7176 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7177 operands[5]));
7178 DONE;
7179 }
7180 })
7181
7182 (define_insn "*addv<mode>4_overflow_1"
7183 [(set (reg:CCO FLAGS_REG)
7184 (eq:CCO
7185 (plus:<DWI>
7186 (plus:<DWI>
7187 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7188 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7189 (sign_extend:<DWI>
7190 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7191 (sign_extend:<DWI>
7192 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7193 (sign_extend:<DWI>
7194 (plus:SWI
7195 (plus:SWI
7196 (match_operator:SWI 5 "ix86_carry_flag_operator"
7197 [(match_dup 3) (const_int 0)])
7198 (match_dup 1))
7199 (match_dup 2)))))
7200 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7201 (plus:SWI
7202 (plus:SWI
7203 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7204 (match_dup 1))
7205 (match_dup 2)))]
7206 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7207 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7208 [(set_attr "type" "alu")
7209 (set_attr "mode" "<MODE>")])
7210
7211 (define_insn "*addv<mode>4_overflow_2"
7212 [(set (reg:CCO FLAGS_REG)
7213 (eq:CCO
7214 (plus:<DWI>
7215 (plus:<DWI>
7216 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7217 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7218 (sign_extend:<DWI>
7219 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7220 (match_operand:<DWI> 6 "const_int_operand" "n"))
7221 (sign_extend:<DWI>
7222 (plus:SWI
7223 (plus:SWI
7224 (match_operator:SWI 5 "ix86_carry_flag_operator"
7225 [(match_dup 3) (const_int 0)])
7226 (match_dup 1))
7227 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7228 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7229 (plus:SWI
7230 (plus:SWI
7231 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7232 (match_dup 1))
7233 (match_dup 2)))]
7234 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7235 && CONST_INT_P (operands[2])
7236 && INTVAL (operands[2]) == INTVAL (operands[6])"
7237 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7238 [(set_attr "type" "alu")
7239 (set_attr "mode" "<MODE>")
7240 (set (attr "length_immediate")
7241 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7242 (const_string "1")
7243 (const_string "4")))])
7244
7245 (define_expand "uaddv<mode>4"
7246 [(parallel [(set (reg:CCC FLAGS_REG)
7247 (compare:CCC
7248 (plus:SWIDWI
7249 (match_operand:SWIDWI 1 "nonimmediate_operand")
7250 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7251 (match_dup 1)))
7252 (set (match_operand:SWIDWI 0 "register_operand")
7253 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7254 (set (pc) (if_then_else
7255 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7256 (label_ref (match_operand 3))
7257 (pc)))]
7258 ""
7259 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7260
7261 ;; The lea patterns for modes less than 32 bits need to be matched by
7262 ;; several insns converted to real lea by splitters.
7263
7264 (define_insn_and_split "*lea<mode>_general_1"
7265 [(set (match_operand:SWI12 0 "register_operand" "=r")
7266 (plus:SWI12
7267 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7268 (match_operand:SWI12 2 "register_operand" "r"))
7269 (match_operand:SWI12 3 "immediate_operand" "i")))]
7270 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7271 "#"
7272 "&& reload_completed"
7273 [(set (match_dup 0)
7274 (plus:SI
7275 (plus:SI (match_dup 1) (match_dup 2))
7276 (match_dup 3)))]
7277 {
7278 operands[0] = gen_lowpart (SImode, operands[0]);
7279 operands[1] = gen_lowpart (SImode, operands[1]);
7280 operands[2] = gen_lowpart (SImode, operands[2]);
7281 operands[3] = gen_lowpart (SImode, operands[3]);
7282 }
7283 [(set_attr "type" "lea")
7284 (set_attr "mode" "SI")])
7285
7286 (define_insn_and_split "*lea<mode>_general_2"
7287 [(set (match_operand:SWI12 0 "register_operand" "=r")
7288 (plus:SWI12
7289 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7290 (match_operand 2 "const248_operand" "n"))
7291 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7292 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7293 "#"
7294 "&& reload_completed"
7295 [(set (match_dup 0)
7296 (plus:SI
7297 (mult:SI (match_dup 1) (match_dup 2))
7298 (match_dup 3)))]
7299 {
7300 operands[0] = gen_lowpart (SImode, operands[0]);
7301 operands[1] = gen_lowpart (SImode, operands[1]);
7302 operands[3] = gen_lowpart (SImode, operands[3]);
7303 }
7304 [(set_attr "type" "lea")
7305 (set_attr "mode" "SI")])
7306
7307 (define_insn_and_split "*lea<mode>_general_2b"
7308 [(set (match_operand:SWI12 0 "register_operand" "=r")
7309 (plus:SWI12
7310 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7311 (match_operand 2 "const123_operand" "n"))
7312 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7313 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7314 "#"
7315 "&& reload_completed"
7316 [(set (match_dup 0)
7317 (plus:SI
7318 (ashift:SI (match_dup 1) (match_dup 2))
7319 (match_dup 3)))]
7320 {
7321 operands[0] = gen_lowpart (SImode, operands[0]);
7322 operands[1] = gen_lowpart (SImode, operands[1]);
7323 operands[3] = gen_lowpart (SImode, operands[3]);
7324 }
7325 [(set_attr "type" "lea")
7326 (set_attr "mode" "SI")])
7327
7328 (define_insn_and_split "*lea<mode>_general_3"
7329 [(set (match_operand:SWI12 0 "register_operand" "=r")
7330 (plus:SWI12
7331 (plus:SWI12
7332 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7333 (match_operand 2 "const248_operand" "n"))
7334 (match_operand:SWI12 3 "register_operand" "r"))
7335 (match_operand:SWI12 4 "immediate_operand" "i")))]
7336 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7337 "#"
7338 "&& reload_completed"
7339 [(set (match_dup 0)
7340 (plus:SI
7341 (plus:SI
7342 (mult:SI (match_dup 1) (match_dup 2))
7343 (match_dup 3))
7344 (match_dup 4)))]
7345 {
7346 operands[0] = gen_lowpart (SImode, operands[0]);
7347 operands[1] = gen_lowpart (SImode, operands[1]);
7348 operands[3] = gen_lowpart (SImode, operands[3]);
7349 operands[4] = gen_lowpart (SImode, operands[4]);
7350 }
7351 [(set_attr "type" "lea")
7352 (set_attr "mode" "SI")])
7353
7354 (define_insn_and_split "*lea<mode>_general_3b"
7355 [(set (match_operand:SWI12 0 "register_operand" "=r")
7356 (plus:SWI12
7357 (plus:SWI12
7358 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7359 (match_operand 2 "const123_operand" "n"))
7360 (match_operand:SWI12 3 "register_operand" "r"))
7361 (match_operand:SWI12 4 "immediate_operand" "i")))]
7362 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7363 "#"
7364 "&& reload_completed"
7365 [(set (match_dup 0)
7366 (plus:SI
7367 (plus:SI
7368 (ashift:SI (match_dup 1) (match_dup 2))
7369 (match_dup 3))
7370 (match_dup 4)))]
7371 {
7372 operands[0] = gen_lowpart (SImode, operands[0]);
7373 operands[1] = gen_lowpart (SImode, operands[1]);
7374 operands[3] = gen_lowpart (SImode, operands[3]);
7375 operands[4] = gen_lowpart (SImode, operands[4]);
7376 }
7377 [(set_attr "type" "lea")
7378 (set_attr "mode" "SI")])
7379
7380 (define_insn_and_split "*lea<mode>_general_4"
7381 [(set (match_operand:SWI12 0 "register_operand" "=r")
7382 (any_or:SWI12
7383 (ashift:SWI12
7384 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7385 (match_operand 2 "const_0_to_3_operand"))
7386 (match_operand 3 "const_int_operand")))]
7387 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7388 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7389 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7390 "#"
7391 "&& reload_completed"
7392 [(set (match_dup 0)
7393 (plus:SI
7394 (mult:SI (match_dup 1) (match_dup 2))
7395 (match_dup 3)))]
7396 {
7397 operands[0] = gen_lowpart (SImode, operands[0]);
7398 operands[1] = gen_lowpart (SImode, operands[1]);
7399 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7400 }
7401 [(set_attr "type" "lea")
7402 (set_attr "mode" "SI")])
7403
7404 (define_insn_and_split "*lea<mode>_general_4"
7405 [(set (match_operand:SWI48 0 "register_operand" "=r")
7406 (any_or:SWI48
7407 (ashift:SWI48
7408 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7409 (match_operand 2 "const_0_to_3_operand"))
7410 (match_operand 3 "const_int_operand")))]
7411 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7412 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7413 "#"
7414 "&& reload_completed"
7415 [(set (match_dup 0)
7416 (plus:SWI48
7417 (mult:SWI48 (match_dup 1) (match_dup 2))
7418 (match_dup 3)))]
7419 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7420 [(set_attr "type" "lea")
7421 (set_attr "mode" "<MODE>")])
7422 \f
7423 ;; Subtract instructions
7424
7425 (define_expand "sub<mode>3"
7426 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7427 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7428 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7429 ""
7430 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7431
7432 (define_insn_and_split "*sub<dwi>3_doubleword"
7433 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7434 (minus:<DWI>
7435 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7436 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7437 (clobber (reg:CC FLAGS_REG))]
7438 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7439 "#"
7440 "&& reload_completed"
7441 [(parallel [(set (reg:CC FLAGS_REG)
7442 (compare:CC (match_dup 1) (match_dup 2)))
7443 (set (match_dup 0)
7444 (minus:DWIH (match_dup 1) (match_dup 2)))])
7445 (parallel [(set (match_dup 3)
7446 (minus:DWIH
7447 (minus:DWIH
7448 (match_dup 4)
7449 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7450 (match_dup 5)))
7451 (clobber (reg:CC FLAGS_REG))])]
7452 {
7453 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7454 if (operands[2] == const0_rtx)
7455 {
7456 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7457 DONE;
7458 }
7459 })
7460
7461 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7462 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7463 (minus:<DWI>
7464 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7465 (zero_extend:<DWI>
7466 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7467 (clobber (reg:CC FLAGS_REG))]
7468 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7469 "#"
7470 "&& reload_completed"
7471 [(parallel [(set (reg:CC FLAGS_REG)
7472 (compare:CC (match_dup 1) (match_dup 2)))
7473 (set (match_dup 0)
7474 (minus:DWIH (match_dup 1) (match_dup 2)))])
7475 (parallel [(set (match_dup 3)
7476 (minus:DWIH
7477 (minus:DWIH
7478 (match_dup 4)
7479 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7480 (const_int 0)))
7481 (clobber (reg:CC FLAGS_REG))])]
7482 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7483
7484 (define_insn "*sub<mode>_1"
7485 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7486 (minus:SWI
7487 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7488 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7489 (clobber (reg:CC FLAGS_REG))]
7490 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7491 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7492 [(set_attr "type" "alu")
7493 (set_attr "mode" "<MODE>")])
7494
7495 (define_insn "*subsi_1_zext"
7496 [(set (match_operand:DI 0 "register_operand" "=r")
7497 (zero_extend:DI
7498 (minus:SI (match_operand:SI 1 "register_operand" "0")
7499 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7500 (clobber (reg:CC FLAGS_REG))]
7501 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7502 "sub{l}\t{%2, %k0|%k0, %2}"
7503 [(set_attr "type" "alu")
7504 (set_attr "mode" "SI")])
7505
7506 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7507 (define_insn_and_split "*sub<mode>_1_slp"
7508 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7509 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7510 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7511 (clobber (reg:CC FLAGS_REG))]
7512 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7513 "@
7514 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7515 #"
7516 "&& reload_completed"
7517 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7518 (parallel
7519 [(set (strict_low_part (match_dup 0))
7520 (minus:SWI12 (match_dup 0) (match_dup 2)))
7521 (clobber (reg:CC FLAGS_REG))])]
7522 ""
7523 [(set_attr "type" "alu")
7524 (set_attr "mode" "<MODE>")])
7525
7526 (define_insn "*sub<mode>_2"
7527 [(set (reg FLAGS_REG)
7528 (compare
7529 (minus:SWI
7530 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7531 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7532 (const_int 0)))
7533 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7534 (minus:SWI (match_dup 1) (match_dup 2)))]
7535 "ix86_match_ccmode (insn, CCGOCmode)
7536 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7537 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7538 [(set_attr "type" "alu")
7539 (set_attr "mode" "<MODE>")])
7540
7541 (define_insn "*subsi_2_zext"
7542 [(set (reg FLAGS_REG)
7543 (compare
7544 (minus:SI (match_operand:SI 1 "register_operand" "0")
7545 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7546 (const_int 0)))
7547 (set (match_operand:DI 0 "register_operand" "=r")
7548 (zero_extend:DI
7549 (minus:SI (match_dup 1)
7550 (match_dup 2))))]
7551 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7552 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7553 "sub{l}\t{%2, %k0|%k0, %2}"
7554 [(set_attr "type" "alu")
7555 (set_attr "mode" "SI")])
7556
7557 (define_insn "*subqi_ext<mode>_0"
7558 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
7559 (minus:QI
7560 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")
7561 (subreg:QI
7562 (match_operator:SWI248 3 "extract_operator"
7563 [(match_operand 2 "int248_register_operand" "Q,Q")
7564 (const_int 8)
7565 (const_int 8)]) 0)))
7566 (clobber (reg:CC FLAGS_REG))]
7567 ""
7568 "sub{b}\t{%h2, %0|%0, %h2}"
7569 [(set_attr "isa" "*,nox64")
7570 (set_attr "type" "alu")
7571 (set_attr "mode" "QI")])
7572
7573 (define_insn "*subqi_ext<mode>_2"
7574 [(set (zero_extract:SWI248
7575 (match_operand 0 "int248_register_operand" "+Q")
7576 (const_int 8)
7577 (const_int 8))
7578 (subreg:SWI248
7579 (minus:QI
7580 (subreg:QI
7581 (match_operator:SWI248 3 "extract_operator"
7582 [(match_operand 1 "int248_register_operand" "0")
7583 (const_int 8)
7584 (const_int 8)]) 0)
7585 (subreg:QI
7586 (match_operator:SWI248 4 "extract_operator"
7587 [(match_operand 2 "int248_register_operand" "Q")
7588 (const_int 8)
7589 (const_int 8)]) 0)) 0))
7590 (clobber (reg:CC FLAGS_REG))]
7591 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7592 rtx_equal_p (operands[0], operands[1])"
7593 "sub{b}\t{%h2, %h0|%h0, %h2}"
7594 [(set_attr "type" "alu")
7595 (set_attr "mode" "QI")])
7596
7597 ;; Subtract with jump on overflow.
7598 (define_expand "subv<mode>4"
7599 [(parallel [(set (reg:CCO FLAGS_REG)
7600 (eq:CCO
7601 (minus:<DPWI>
7602 (sign_extend:<DPWI>
7603 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7604 (match_dup 4))
7605 (sign_extend:<DPWI>
7606 (minus:SWIDWI (match_dup 1)
7607 (match_operand:SWIDWI 2
7608 "<general_hilo_operand>")))))
7609 (set (match_operand:SWIDWI 0 "register_operand")
7610 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7611 (set (pc) (if_then_else
7612 (eq (reg:CCO FLAGS_REG) (const_int 0))
7613 (label_ref (match_operand 3))
7614 (pc)))]
7615 ""
7616 {
7617 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7618 if (CONST_SCALAR_INT_P (operands[2]))
7619 operands[4] = operands[2];
7620 else
7621 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7622 })
7623
7624 (define_insn "*subv<mode>4"
7625 [(set (reg:CCO FLAGS_REG)
7626 (eq:CCO (minus:<DWI>
7627 (sign_extend:<DWI>
7628 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7629 (sign_extend:<DWI>
7630 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7631 (sign_extend:<DWI>
7632 (minus:SWI (match_dup 1) (match_dup 2)))))
7633 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7634 (minus:SWI (match_dup 1) (match_dup 2)))]
7635 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7636 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7637 [(set_attr "type" "alu")
7638 (set_attr "mode" "<MODE>")])
7639
7640 (define_insn "subv<mode>4_1"
7641 [(set (reg:CCO FLAGS_REG)
7642 (eq:CCO (minus:<DWI>
7643 (sign_extend:<DWI>
7644 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7645 (match_operand:<DWI> 3 "const_int_operand"))
7646 (sign_extend:<DWI>
7647 (minus:SWI
7648 (match_dup 1)
7649 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7650 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7651 (minus:SWI (match_dup 1) (match_dup 2)))]
7652 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7653 && CONST_INT_P (operands[2])
7654 && INTVAL (operands[2]) == INTVAL (operands[3])"
7655 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7656 [(set_attr "type" "alu")
7657 (set_attr "mode" "<MODE>")
7658 (set (attr "length_immediate")
7659 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7660 (const_string "1")
7661 (match_test "<MODE_SIZE> == 8")
7662 (const_string "4")]
7663 (const_string "<MODE_SIZE>")))])
7664
7665 (define_insn_and_split "*subv<dwi>4_doubleword"
7666 [(set (reg:CCO FLAGS_REG)
7667 (eq:CCO
7668 (minus:<QPWI>
7669 (sign_extend:<QPWI>
7670 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7671 (sign_extend:<QPWI>
7672 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7673 (sign_extend:<QPWI>
7674 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7675 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7676 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7677 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7678 "#"
7679 "&& reload_completed"
7680 [(parallel [(set (reg:CC FLAGS_REG)
7681 (compare:CC (match_dup 1) (match_dup 2)))
7682 (set (match_dup 0)
7683 (minus:DWIH (match_dup 1) (match_dup 2)))])
7684 (parallel [(set (reg:CCO FLAGS_REG)
7685 (eq:CCO
7686 (minus:<DWI>
7687 (minus:<DWI>
7688 (sign_extend:<DWI> (match_dup 4))
7689 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7690 (sign_extend:<DWI> (match_dup 5)))
7691 (sign_extend:<DWI>
7692 (minus:DWIH
7693 (minus:DWIH
7694 (match_dup 4)
7695 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7696 (match_dup 5)))))
7697 (set (match_dup 3)
7698 (minus:DWIH
7699 (minus:DWIH
7700 (match_dup 4)
7701 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7702 (match_dup 5)))])]
7703 {
7704 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7705 })
7706
7707 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7708 [(set (reg:CCO FLAGS_REG)
7709 (eq:CCO
7710 (minus:<QPWI>
7711 (sign_extend:<QPWI>
7712 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7713 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7714 (sign_extend:<QPWI>
7715 (minus:<DWI>
7716 (match_dup 1)
7717 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7718 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7719 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7720 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7721 && CONST_SCALAR_INT_P (operands[2])
7722 && rtx_equal_p (operands[2], operands[3])"
7723 "#"
7724 "&& reload_completed"
7725 [(parallel [(set (reg:CC FLAGS_REG)
7726 (compare:CC (match_dup 1) (match_dup 2)))
7727 (set (match_dup 0)
7728 (minus:DWIH (match_dup 1) (match_dup 2)))])
7729 (parallel [(set (reg:CCO FLAGS_REG)
7730 (eq:CCO
7731 (minus:<DWI>
7732 (minus:<DWI>
7733 (sign_extend:<DWI> (match_dup 4))
7734 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7735 (match_dup 5))
7736 (sign_extend:<DWI>
7737 (minus:DWIH
7738 (minus:DWIH
7739 (match_dup 4)
7740 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7741 (match_dup 5)))))
7742 (set (match_dup 3)
7743 (minus:DWIH
7744 (minus:DWIH
7745 (match_dup 4)
7746 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7747 (match_dup 5)))])]
7748 {
7749 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7750 if (operands[2] == const0_rtx)
7751 {
7752 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7753 operands[5]));
7754 DONE;
7755 }
7756 })
7757
7758 (define_insn "*subv<mode>4_overflow_1"
7759 [(set (reg:CCO FLAGS_REG)
7760 (eq:CCO
7761 (minus:<DWI>
7762 (minus:<DWI>
7763 (sign_extend:<DWI>
7764 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7765 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7766 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7767 (sign_extend:<DWI>
7768 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7769 (sign_extend:<DWI>
7770 (minus:SWI
7771 (minus:SWI
7772 (match_dup 1)
7773 (match_operator:SWI 5 "ix86_carry_flag_operator"
7774 [(match_dup 3) (const_int 0)]))
7775 (match_dup 2)))))
7776 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7777 (minus:SWI
7778 (minus:SWI
7779 (match_dup 1)
7780 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7781 (match_dup 2)))]
7782 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7783 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7784 [(set_attr "type" "alu")
7785 (set_attr "mode" "<MODE>")])
7786
7787 (define_insn "*subv<mode>4_overflow_2"
7788 [(set (reg:CCO FLAGS_REG)
7789 (eq:CCO
7790 (minus:<DWI>
7791 (minus:<DWI>
7792 (sign_extend:<DWI>
7793 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7794 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7795 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7796 (match_operand:<DWI> 6 "const_int_operand" "n"))
7797 (sign_extend:<DWI>
7798 (minus:SWI
7799 (minus:SWI
7800 (match_dup 1)
7801 (match_operator:SWI 5 "ix86_carry_flag_operator"
7802 [(match_dup 3) (const_int 0)]))
7803 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7804 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7805 (minus:SWI
7806 (minus:SWI
7807 (match_dup 1)
7808 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7809 (match_dup 2)))]
7810 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7811 && CONST_INT_P (operands[2])
7812 && INTVAL (operands[2]) == INTVAL (operands[6])"
7813 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7814 [(set_attr "type" "alu")
7815 (set_attr "mode" "<MODE>")
7816 (set (attr "length_immediate")
7817 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7818 (const_string "1")
7819 (const_string "4")))])
7820
7821 (define_expand "usubv<mode>4"
7822 [(parallel [(set (reg:CC FLAGS_REG)
7823 (compare:CC
7824 (match_operand:SWI 1 "nonimmediate_operand")
7825 (match_operand:SWI 2 "<general_operand>")))
7826 (set (match_operand:SWI 0 "register_operand")
7827 (minus:SWI (match_dup 1) (match_dup 2)))])
7828 (set (pc) (if_then_else
7829 (ltu (reg:CC FLAGS_REG) (const_int 0))
7830 (label_ref (match_operand 3))
7831 (pc)))]
7832 ""
7833 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
7834
7835 (define_insn "*sub<mode>_3"
7836 [(set (reg FLAGS_REG)
7837 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7838 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7839 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7840 (minus:SWI (match_dup 1) (match_dup 2)))]
7841 "ix86_match_ccmode (insn, CCmode)
7842 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7843 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7844 [(set_attr "type" "alu")
7845 (set_attr "mode" "<MODE>")])
7846
7847 (define_peephole2
7848 [(parallel
7849 [(set (reg:CC FLAGS_REG)
7850 (compare:CC (match_operand:SWI 0 "general_reg_operand")
7851 (match_operand:SWI 1 "general_gr_operand")))
7852 (set (match_dup 0)
7853 (minus:SWI (match_dup 0) (match_dup 1)))])]
7854 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
7855 [(set (reg:CC FLAGS_REG)
7856 (compare:CC (match_dup 0) (match_dup 1)))])
7857
7858 (define_peephole2
7859 [(set (match_operand:SWI 0 "general_reg_operand")
7860 (match_operand:SWI 1 "memory_operand"))
7861 (parallel [(set (reg:CC FLAGS_REG)
7862 (compare:CC (match_dup 0)
7863 (match_operand:SWI 2 "memory_operand")))
7864 (set (match_dup 0)
7865 (minus:SWI (match_dup 0) (match_dup 2)))])
7866 (set (match_dup 1) (match_dup 0))]
7867 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7868 && peep2_reg_dead_p (3, operands[0])
7869 && !reg_overlap_mentioned_p (operands[0], operands[1])
7870 && !reg_overlap_mentioned_p (operands[0], operands[2])"
7871 [(set (match_dup 0) (match_dup 2))
7872 (parallel [(set (reg:CC FLAGS_REG)
7873 (compare:CC (match_dup 1) (match_dup 0)))
7874 (set (match_dup 1)
7875 (minus:SWI (match_dup 1) (match_dup 0)))])])
7876
7877 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
7878 ;; subl $1, %eax; jnc .Lxx;
7879 (define_peephole2
7880 [(parallel
7881 [(set (match_operand:SWI 0 "general_reg_operand")
7882 (plus:SWI (match_dup 0) (const_int -1)))
7883 (clobber (reg FLAGS_REG))])
7884 (set (reg:CCZ FLAGS_REG)
7885 (compare:CCZ (match_dup 0) (const_int -1)))
7886 (set (pc)
7887 (if_then_else (match_operator 1 "bt_comparison_operator"
7888 [(reg:CCZ FLAGS_REG) (const_int 0)])
7889 (match_operand 2)
7890 (pc)))]
7891 "peep2_regno_dead_p (3, FLAGS_REG)"
7892 [(parallel
7893 [(set (reg:CC FLAGS_REG)
7894 (compare:CC (match_dup 0) (const_int 1)))
7895 (set (match_dup 0)
7896 (minus:SWI (match_dup 0) (const_int 1)))])
7897 (set (pc)
7898 (if_then_else (match_dup 3)
7899 (match_dup 2)
7900 (pc)))]
7901 {
7902 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
7903 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7904 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7905 })
7906
7907 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
7908 (define_insn_and_split "*dec_cmov<mode>"
7909 [(set (match_operand:SWI248 0 "register_operand" "=r")
7910 (if_then_else:SWI248
7911 (match_operator 1 "bt_comparison_operator"
7912 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
7913 (plus:SWI248 (match_dup 2) (const_int -1))
7914 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
7915 (clobber (reg:CC FLAGS_REG))]
7916 "TARGET_CMOVE"
7917 "#"
7918 "&& reload_completed"
7919 [(parallel [(set (reg:CC FLAGS_REG)
7920 (compare:CC (match_dup 2) (const_int 1)))
7921 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
7922 (set (match_dup 0)
7923 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
7924 {
7925 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
7926 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7927 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7928 })
7929
7930 (define_insn "*subsi_3_zext"
7931 [(set (reg FLAGS_REG)
7932 (compare (match_operand:SI 1 "register_operand" "0")
7933 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
7934 (set (match_operand:DI 0 "register_operand" "=r")
7935 (zero_extend:DI
7936 (minus:SI (match_dup 1)
7937 (match_dup 2))))]
7938 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7939 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7940 "sub{l}\t{%2, %1|%1, %2}"
7941 [(set_attr "type" "alu")
7942 (set_attr "mode" "SI")])
7943 \f
7944 ;; Add with carry and subtract with borrow
7945
7946 (define_insn "@add<mode>3_carry"
7947 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7948 (plus:SWI
7949 (plus:SWI
7950 (match_operator:SWI 4 "ix86_carry_flag_operator"
7951 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7952 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7953 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7954 (clobber (reg:CC FLAGS_REG))]
7955 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7956 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7957 [(set_attr "type" "alu")
7958 (set_attr "use_carry" "1")
7959 (set_attr "pent_pair" "pu")
7960 (set_attr "mode" "<MODE>")])
7961
7962 (define_peephole2
7963 [(set (match_operand:SWI 0 "general_reg_operand")
7964 (match_operand:SWI 1 "memory_operand"))
7965 (parallel [(set (match_dup 0)
7966 (plus:SWI
7967 (plus:SWI
7968 (match_operator:SWI 4 "ix86_carry_flag_operator"
7969 [(match_operand 3 "flags_reg_operand")
7970 (const_int 0)])
7971 (match_dup 0))
7972 (match_operand:SWI 2 "memory_operand")))
7973 (clobber (reg:CC FLAGS_REG))])
7974 (set (match_dup 1) (match_dup 0))]
7975 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7976 && peep2_reg_dead_p (3, operands[0])
7977 && !reg_overlap_mentioned_p (operands[0], operands[1])
7978 && !reg_overlap_mentioned_p (operands[0], operands[2])"
7979 [(set (match_dup 0) (match_dup 2))
7980 (parallel [(set (match_dup 1)
7981 (plus:SWI (plus:SWI (match_op_dup 4
7982 [(match_dup 3) (const_int 0)])
7983 (match_dup 1))
7984 (match_dup 0)))
7985 (clobber (reg:CC FLAGS_REG))])])
7986
7987 (define_peephole2
7988 [(set (match_operand:SWI 0 "general_reg_operand")
7989 (match_operand:SWI 1 "memory_operand"))
7990 (parallel [(set (match_dup 0)
7991 (plus:SWI
7992 (plus:SWI
7993 (match_operator:SWI 4 "ix86_carry_flag_operator"
7994 [(match_operand 3 "flags_reg_operand")
7995 (const_int 0)])
7996 (match_dup 0))
7997 (match_operand:SWI 2 "memory_operand")))
7998 (clobber (reg:CC FLAGS_REG))])
7999 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8000 (set (match_dup 1) (match_dup 5))]
8001 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8002 && peep2_reg_dead_p (3, operands[0])
8003 && peep2_reg_dead_p (4, operands[5])
8004 && !reg_overlap_mentioned_p (operands[0], operands[1])
8005 && !reg_overlap_mentioned_p (operands[0], operands[2])
8006 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8007 [(set (match_dup 0) (match_dup 2))
8008 (parallel [(set (match_dup 1)
8009 (plus:SWI (plus:SWI (match_op_dup 4
8010 [(match_dup 3) (const_int 0)])
8011 (match_dup 1))
8012 (match_dup 0)))
8013 (clobber (reg:CC FLAGS_REG))])])
8014
8015 (define_insn "*add<mode>3_carry_0"
8016 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8017 (plus:SWI
8018 (match_operator:SWI 2 "ix86_carry_flag_operator"
8019 [(reg FLAGS_REG) (const_int 0)])
8020 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8021 (clobber (reg:CC FLAGS_REG))]
8022 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8023 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
8024 [(set_attr "type" "alu")
8025 (set_attr "use_carry" "1")
8026 (set_attr "pent_pair" "pu")
8027 (set_attr "mode" "<MODE>")])
8028
8029 (define_insn "*add<mode>3_carry_0r"
8030 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8031 (plus:SWI
8032 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8033 [(reg FLAGS_REG) (const_int 0)])
8034 (match_operand:SWI 1 "nonimmediate_operand" "0")))
8035 (clobber (reg:CC FLAGS_REG))]
8036 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8037 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
8038 [(set_attr "type" "alu")
8039 (set_attr "use_carry" "1")
8040 (set_attr "pent_pair" "pu")
8041 (set_attr "mode" "<MODE>")])
8042
8043 (define_insn "*addsi3_carry_zext"
8044 [(set (match_operand:DI 0 "register_operand" "=r")
8045 (zero_extend:DI
8046 (plus:SI
8047 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
8048 [(reg FLAGS_REG) (const_int 0)])
8049 (match_operand:SI 1 "register_operand" "%0"))
8050 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8051 (clobber (reg:CC FLAGS_REG))]
8052 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8053 "adc{l}\t{%2, %k0|%k0, %2}"
8054 [(set_attr "type" "alu")
8055 (set_attr "use_carry" "1")
8056 (set_attr "pent_pair" "pu")
8057 (set_attr "mode" "SI")])
8058
8059 (define_insn "*addsi3_carry_zext_0"
8060 [(set (match_operand:DI 0 "register_operand" "=r")
8061 (zero_extend:DI
8062 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
8063 [(reg FLAGS_REG) (const_int 0)])
8064 (match_operand:SI 1 "register_operand" "0"))))
8065 (clobber (reg:CC FLAGS_REG))]
8066 "TARGET_64BIT"
8067 "adc{l}\t{$0, %k0|%k0, 0}"
8068 [(set_attr "type" "alu")
8069 (set_attr "use_carry" "1")
8070 (set_attr "pent_pair" "pu")
8071 (set_attr "mode" "SI")])
8072
8073 (define_insn "*addsi3_carry_zext_0r"
8074 [(set (match_operand:DI 0 "register_operand" "=r")
8075 (zero_extend:DI
8076 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8077 [(reg FLAGS_REG) (const_int 0)])
8078 (match_operand:SI 1 "register_operand" "0"))))
8079 (clobber (reg:CC FLAGS_REG))]
8080 "TARGET_64BIT"
8081 "sbb{l}\t{$-1, %k0|%k0, -1}"
8082 [(set_attr "type" "alu")
8083 (set_attr "use_carry" "1")
8084 (set_attr "pent_pair" "pu")
8085 (set_attr "mode" "SI")])
8086
8087 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8088
8089 (define_insn "addcarry<mode>"
8090 [(set (reg:CCC FLAGS_REG)
8091 (compare:CCC
8092 (zero_extend:<DWI>
8093 (plus:SWI48
8094 (plus:SWI48
8095 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8096 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8097 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8098 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8099 (plus:<DWI>
8100 (zero_extend:<DWI> (match_dup 2))
8101 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8102 [(match_dup 3) (const_int 0)]))))
8103 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8104 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8105 [(match_dup 3) (const_int 0)])
8106 (match_dup 1))
8107 (match_dup 2)))]
8108 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8109 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8110 [(set_attr "type" "alu")
8111 (set_attr "use_carry" "1")
8112 (set_attr "pent_pair" "pu")
8113 (set_attr "mode" "<MODE>")])
8114
8115 (define_peephole2
8116 [(parallel [(set (reg:CCC FLAGS_REG)
8117 (compare:CCC
8118 (zero_extend:<DWI>
8119 (plus:SWI48
8120 (plus:SWI48
8121 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8122 [(match_operand 2 "flags_reg_operand")
8123 (const_int 0)])
8124 (match_operand:SWI48 0 "general_reg_operand"))
8125 (match_operand:SWI48 1 "memory_operand")))
8126 (plus:<DWI>
8127 (zero_extend:<DWI> (match_dup 1))
8128 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8129 [(match_dup 2) (const_int 0)]))))
8130 (set (match_dup 0)
8131 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8132 [(match_dup 2) (const_int 0)])
8133 (match_dup 0))
8134 (match_dup 1)))])
8135 (set (match_dup 1) (match_dup 0))]
8136 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8137 && peep2_reg_dead_p (2, operands[0])
8138 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8139 [(parallel [(set (reg:CCC FLAGS_REG)
8140 (compare:CCC
8141 (zero_extend:<DWI>
8142 (plus:SWI48
8143 (plus:SWI48
8144 (match_op_dup 4
8145 [(match_dup 2) (const_int 0)])
8146 (match_dup 1))
8147 (match_dup 0)))
8148 (plus:<DWI>
8149 (zero_extend:<DWI> (match_dup 0))
8150 (match_op_dup 3
8151 [(match_dup 2) (const_int 0)]))))
8152 (set (match_dup 1)
8153 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8154 [(match_dup 2) (const_int 0)])
8155 (match_dup 1))
8156 (match_dup 0)))])])
8157
8158 (define_peephole2
8159 [(set (match_operand:SWI48 0 "general_reg_operand")
8160 (match_operand:SWI48 1 "memory_operand"))
8161 (parallel [(set (reg:CCC FLAGS_REG)
8162 (compare:CCC
8163 (zero_extend:<DWI>
8164 (plus:SWI48
8165 (plus:SWI48
8166 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8167 [(match_operand 3 "flags_reg_operand")
8168 (const_int 0)])
8169 (match_dup 0))
8170 (match_operand:SWI48 2 "memory_operand")))
8171 (plus:<DWI>
8172 (zero_extend:<DWI> (match_dup 2))
8173 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8174 [(match_dup 3) (const_int 0)]))))
8175 (set (match_dup 0)
8176 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8177 [(match_dup 3) (const_int 0)])
8178 (match_dup 0))
8179 (match_dup 2)))])
8180 (set (match_dup 1) (match_dup 0))]
8181 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8182 && peep2_reg_dead_p (3, operands[0])
8183 && !reg_overlap_mentioned_p (operands[0], operands[1])
8184 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8185 [(set (match_dup 0) (match_dup 2))
8186 (parallel [(set (reg:CCC FLAGS_REG)
8187 (compare:CCC
8188 (zero_extend:<DWI>
8189 (plus:SWI48
8190 (plus:SWI48
8191 (match_op_dup 5
8192 [(match_dup 3) (const_int 0)])
8193 (match_dup 1))
8194 (match_dup 0)))
8195 (plus:<DWI>
8196 (zero_extend:<DWI> (match_dup 0))
8197 (match_op_dup 4
8198 [(match_dup 3) (const_int 0)]))))
8199 (set (match_dup 1)
8200 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8201 [(match_dup 3) (const_int 0)])
8202 (match_dup 1))
8203 (match_dup 0)))])])
8204
8205 (define_peephole2
8206 [(parallel [(set (reg:CCC FLAGS_REG)
8207 (compare:CCC
8208 (zero_extend:<DWI>
8209 (plus:SWI48
8210 (plus:SWI48
8211 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8212 [(match_operand 2 "flags_reg_operand")
8213 (const_int 0)])
8214 (match_operand:SWI48 0 "general_reg_operand"))
8215 (match_operand:SWI48 1 "memory_operand")))
8216 (plus:<DWI>
8217 (zero_extend:<DWI> (match_dup 1))
8218 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8219 [(match_dup 2) (const_int 0)]))))
8220 (set (match_dup 0)
8221 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8222 [(match_dup 2) (const_int 0)])
8223 (match_dup 0))
8224 (match_dup 1)))])
8225 (set (match_operand:QI 5 "general_reg_operand")
8226 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8227 (set (match_operand:SWI48 6 "general_reg_operand")
8228 (zero_extend:SWI48 (match_dup 5)))
8229 (set (match_dup 1) (match_dup 0))]
8230 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8231 && peep2_reg_dead_p (4, operands[0])
8232 && !reg_overlap_mentioned_p (operands[0], operands[1])
8233 && !reg_overlap_mentioned_p (operands[0], operands[5])
8234 && !reg_overlap_mentioned_p (operands[5], operands[1])
8235 && !reg_overlap_mentioned_p (operands[0], operands[6])
8236 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8237 [(parallel [(set (reg:CCC FLAGS_REG)
8238 (compare:CCC
8239 (zero_extend:<DWI>
8240 (plus:SWI48
8241 (plus:SWI48
8242 (match_op_dup 4
8243 [(match_dup 2) (const_int 0)])
8244 (match_dup 1))
8245 (match_dup 0)))
8246 (plus:<DWI>
8247 (zero_extend:<DWI> (match_dup 0))
8248 (match_op_dup 3
8249 [(match_dup 2) (const_int 0)]))))
8250 (set (match_dup 1)
8251 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8252 [(match_dup 2) (const_int 0)])
8253 (match_dup 1))
8254 (match_dup 0)))])
8255 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8256 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8257
8258 (define_expand "addcarry<mode>_0"
8259 [(parallel
8260 [(set (reg:CCC FLAGS_REG)
8261 (compare:CCC
8262 (plus:SWI48
8263 (match_operand:SWI48 1 "nonimmediate_operand")
8264 (match_operand:SWI48 2 "x86_64_general_operand"))
8265 (match_dup 1)))
8266 (set (match_operand:SWI48 0 "nonimmediate_operand")
8267 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8268 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8269
8270 (define_insn "*addcarry<mode>_1"
8271 [(set (reg:CCC FLAGS_REG)
8272 (compare:CCC
8273 (zero_extend:<DWI>
8274 (plus:SWI48
8275 (plus:SWI48
8276 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8277 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8278 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8279 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8280 (plus:<DWI>
8281 (match_operand:<DWI> 6 "const_scalar_int_operand")
8282 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8283 [(match_dup 3) (const_int 0)]))))
8284 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8285 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8286 [(match_dup 3) (const_int 0)])
8287 (match_dup 1))
8288 (match_dup 2)))]
8289 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8290 && CONST_INT_P (operands[2])
8291 /* Check that operands[6] is operands[2] zero extended from
8292 <MODE>mode to <DWI>mode. */
8293 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8294 ? (CONST_INT_P (operands[6])
8295 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8296 & GET_MODE_MASK (<MODE>mode)))
8297 : (CONST_WIDE_INT_P (operands[6])
8298 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8299 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8300 == UINTVAL (operands[2]))
8301 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8302 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8303 [(set_attr "type" "alu")
8304 (set_attr "use_carry" "1")
8305 (set_attr "pent_pair" "pu")
8306 (set_attr "mode" "<MODE>")
8307 (set (attr "length_immediate")
8308 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8309 (const_string "1")
8310 (const_string "4")))])
8311
8312 (define_insn "@sub<mode>3_carry"
8313 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8314 (minus:SWI
8315 (minus:SWI
8316 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8317 (match_operator:SWI 4 "ix86_carry_flag_operator"
8318 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8319 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8320 (clobber (reg:CC FLAGS_REG))]
8321 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8322 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8323 [(set_attr "type" "alu")
8324 (set_attr "use_carry" "1")
8325 (set_attr "pent_pair" "pu")
8326 (set_attr "mode" "<MODE>")])
8327
8328 (define_peephole2
8329 [(set (match_operand:SWI 0 "general_reg_operand")
8330 (match_operand:SWI 1 "memory_operand"))
8331 (parallel [(set (match_dup 0)
8332 (minus:SWI
8333 (minus:SWI
8334 (match_dup 0)
8335 (match_operator:SWI 4 "ix86_carry_flag_operator"
8336 [(match_operand 3 "flags_reg_operand")
8337 (const_int 0)]))
8338 (match_operand:SWI 2 "memory_operand")))
8339 (clobber (reg:CC FLAGS_REG))])
8340 (set (match_dup 1) (match_dup 0))]
8341 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8342 && peep2_reg_dead_p (3, operands[0])
8343 && !reg_overlap_mentioned_p (operands[0], operands[1])
8344 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8345 [(set (match_dup 0) (match_dup 2))
8346 (parallel [(set (match_dup 1)
8347 (minus:SWI (minus:SWI (match_dup 1)
8348 (match_op_dup 4
8349 [(match_dup 3) (const_int 0)]))
8350 (match_dup 0)))
8351 (clobber (reg:CC FLAGS_REG))])])
8352
8353 (define_peephole2
8354 [(set (match_operand:SWI 0 "general_reg_operand")
8355 (match_operand:SWI 1 "memory_operand"))
8356 (parallel [(set (match_dup 0)
8357 (minus:SWI
8358 (minus:SWI
8359 (match_dup 0)
8360 (match_operator:SWI 4 "ix86_carry_flag_operator"
8361 [(match_operand 3 "flags_reg_operand")
8362 (const_int 0)]))
8363 (match_operand:SWI 2 "memory_operand")))
8364 (clobber (reg:CC FLAGS_REG))])
8365 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8366 (set (match_dup 1) (match_dup 5))]
8367 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8368 && peep2_reg_dead_p (3, operands[0])
8369 && peep2_reg_dead_p (4, operands[5])
8370 && !reg_overlap_mentioned_p (operands[0], operands[1])
8371 && !reg_overlap_mentioned_p (operands[0], operands[2])
8372 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8373 [(set (match_dup 0) (match_dup 2))
8374 (parallel [(set (match_dup 1)
8375 (minus:SWI (minus:SWI (match_dup 1)
8376 (match_op_dup 4
8377 [(match_dup 3) (const_int 0)]))
8378 (match_dup 0)))
8379 (clobber (reg:CC FLAGS_REG))])])
8380
8381 (define_insn "*sub<mode>3_carry_0"
8382 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8383 (minus:SWI
8384 (match_operand:SWI 1 "nonimmediate_operand" "0")
8385 (match_operator:SWI 2 "ix86_carry_flag_operator"
8386 [(reg FLAGS_REG) (const_int 0)])))
8387 (clobber (reg:CC FLAGS_REG))]
8388 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8389 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8390 [(set_attr "type" "alu")
8391 (set_attr "use_carry" "1")
8392 (set_attr "pent_pair" "pu")
8393 (set_attr "mode" "<MODE>")])
8394
8395 (define_insn "*sub<mode>3_carry_0r"
8396 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8397 (minus:SWI
8398 (match_operand:SWI 1 "nonimmediate_operand" "0")
8399 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8400 [(reg FLAGS_REG) (const_int 0)])))
8401 (clobber (reg:CC FLAGS_REG))]
8402 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8403 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8404 [(set_attr "type" "alu")
8405 (set_attr "use_carry" "1")
8406 (set_attr "pent_pair" "pu")
8407 (set_attr "mode" "<MODE>")])
8408
8409 (define_insn "*subsi3_carry_zext"
8410 [(set (match_operand:DI 0 "register_operand" "=r")
8411 (zero_extend:DI
8412 (minus:SI
8413 (minus:SI
8414 (match_operand:SI 1 "register_operand" "0")
8415 (match_operator:SI 3 "ix86_carry_flag_operator"
8416 [(reg FLAGS_REG) (const_int 0)]))
8417 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8418 (clobber (reg:CC FLAGS_REG))]
8419 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8420 "sbb{l}\t{%2, %k0|%k0, %2}"
8421 [(set_attr "type" "alu")
8422 (set_attr "use_carry" "1")
8423 (set_attr "pent_pair" "pu")
8424 (set_attr "mode" "SI")])
8425
8426 (define_insn "*subsi3_carry_zext_0"
8427 [(set (match_operand:DI 0 "register_operand" "=r")
8428 (zero_extend:DI
8429 (minus:SI
8430 (match_operand:SI 1 "register_operand" "0")
8431 (match_operator:SI 2 "ix86_carry_flag_operator"
8432 [(reg FLAGS_REG) (const_int 0)]))))
8433 (clobber (reg:CC FLAGS_REG))]
8434 "TARGET_64BIT"
8435 "sbb{l}\t{$0, %k0|%k0, 0}"
8436 [(set_attr "type" "alu")
8437 (set_attr "use_carry" "1")
8438 (set_attr "pent_pair" "pu")
8439 (set_attr "mode" "SI")])
8440
8441 (define_insn "*subsi3_carry_zext_0r"
8442 [(set (match_operand:DI 0 "register_operand" "=r")
8443 (zero_extend:DI
8444 (minus:SI
8445 (match_operand:SI 1 "register_operand" "0")
8446 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8447 [(reg FLAGS_REG) (const_int 0)]))))
8448 (clobber (reg:CC FLAGS_REG))]
8449 "TARGET_64BIT"
8450 "adc{l}\t{$-1, %k0|%k0, -1}"
8451 [(set_attr "type" "alu")
8452 (set_attr "use_carry" "1")
8453 (set_attr "pent_pair" "pu")
8454 (set_attr "mode" "SI")])
8455
8456 (define_insn "@sub<mode>3_carry_ccc"
8457 [(set (reg:CCC FLAGS_REG)
8458 (compare:CCC
8459 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8460 (plus:<DWI>
8461 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8462 (zero_extend:<DWI>
8463 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8464 (clobber (match_scratch:DWIH 0 "=r"))]
8465 ""
8466 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8467 [(set_attr "type" "alu")
8468 (set_attr "mode" "<MODE>")])
8469
8470 (define_insn "*sub<mode>3_carry_ccc_1"
8471 [(set (reg:CCC FLAGS_REG)
8472 (compare:CCC
8473 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8474 (plus:<DWI>
8475 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8476 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8477 (clobber (match_scratch:DWIH 0 "=r"))]
8478 ""
8479 {
8480 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8481 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8482 }
8483 [(set_attr "type" "alu")
8484 (set_attr "mode" "<MODE>")])
8485
8486 ;; The sign flag is set from the
8487 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8488 ;; result, the overflow flag likewise, but the overflow flag is also
8489 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8490 (define_insn "@sub<mode>3_carry_ccgz"
8491 [(set (reg:CCGZ FLAGS_REG)
8492 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8493 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8494 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8495 UNSPEC_SBB))
8496 (clobber (match_scratch:DWIH 0 "=r"))]
8497 ""
8498 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8499 [(set_attr "type" "alu")
8500 (set_attr "mode" "<MODE>")])
8501
8502 (define_insn "subborrow<mode>"
8503 [(set (reg:CCC FLAGS_REG)
8504 (compare:CCC
8505 (zero_extend:<DWI>
8506 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8507 (plus:<DWI>
8508 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8509 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8510 (zero_extend:<DWI>
8511 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8512 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8513 (minus:SWI48 (minus:SWI48
8514 (match_dup 1)
8515 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8516 [(match_dup 3) (const_int 0)]))
8517 (match_dup 2)))]
8518 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8519 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8520 [(set_attr "type" "alu")
8521 (set_attr "use_carry" "1")
8522 (set_attr "pent_pair" "pu")
8523 (set_attr "mode" "<MODE>")])
8524
8525 (define_peephole2
8526 [(set (match_operand:SWI48 0 "general_reg_operand")
8527 (match_operand:SWI48 1 "memory_operand"))
8528 (parallel [(set (reg:CCC FLAGS_REG)
8529 (compare:CCC
8530 (zero_extend:<DWI> (match_dup 0))
8531 (plus:<DWI>
8532 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8533 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8534 (zero_extend:<DWI>
8535 (match_operand:SWI48 2 "memory_operand")))))
8536 (set (match_dup 0)
8537 (minus:SWI48
8538 (minus:SWI48
8539 (match_dup 0)
8540 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8541 [(match_dup 3) (const_int 0)]))
8542 (match_dup 2)))])
8543 (set (match_dup 1) (match_dup 0))]
8544 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8545 && peep2_reg_dead_p (3, operands[0])
8546 && !reg_overlap_mentioned_p (operands[0], operands[1])
8547 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8548 [(set (match_dup 0) (match_dup 2))
8549 (parallel [(set (reg:CCC FLAGS_REG)
8550 (compare:CCC
8551 (zero_extend:<DWI> (match_dup 1))
8552 (plus:<DWI> (match_op_dup 4
8553 [(match_dup 3) (const_int 0)])
8554 (zero_extend:<DWI> (match_dup 0)))))
8555 (set (match_dup 1)
8556 (minus:SWI48 (minus:SWI48 (match_dup 1)
8557 (match_op_dup 5
8558 [(match_dup 3) (const_int 0)]))
8559 (match_dup 0)))])])
8560
8561 (define_peephole2
8562 [(set (match_operand:SWI48 6 "general_reg_operand")
8563 (match_operand:SWI48 7 "memory_operand"))
8564 (set (match_operand:SWI48 8 "general_reg_operand")
8565 (match_operand:SWI48 9 "memory_operand"))
8566 (parallel [(set (reg:CCC FLAGS_REG)
8567 (compare:CCC
8568 (zero_extend:<DWI>
8569 (match_operand:SWI48 0 "general_reg_operand"))
8570 (plus:<DWI>
8571 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8572 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8573 (zero_extend:<DWI>
8574 (match_operand:SWI48 2 "general_reg_operand")))))
8575 (set (match_dup 0)
8576 (minus:SWI48
8577 (minus:SWI48
8578 (match_dup 0)
8579 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8580 [(match_dup 3) (const_int 0)]))
8581 (match_dup 2)))])
8582 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8583 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8584 && peep2_reg_dead_p (4, operands[0])
8585 && peep2_reg_dead_p (3, operands[2])
8586 && !reg_overlap_mentioned_p (operands[0], operands[1])
8587 && !reg_overlap_mentioned_p (operands[2], operands[1])
8588 && !reg_overlap_mentioned_p (operands[6], operands[9])
8589 && (rtx_equal_p (operands[6], operands[0])
8590 ? (rtx_equal_p (operands[7], operands[1])
8591 && rtx_equal_p (operands[8], operands[2]))
8592 : (rtx_equal_p (operands[8], operands[0])
8593 && rtx_equal_p (operands[9], operands[1])
8594 && rtx_equal_p (operands[6], operands[2])))"
8595 [(set (match_dup 0) (match_dup 9))
8596 (parallel [(set (reg:CCC FLAGS_REG)
8597 (compare:CCC
8598 (zero_extend:<DWI> (match_dup 1))
8599 (plus:<DWI> (match_op_dup 4
8600 [(match_dup 3) (const_int 0)])
8601 (zero_extend:<DWI> (match_dup 0)))))
8602 (set (match_dup 1)
8603 (minus:SWI48 (minus:SWI48 (match_dup 1)
8604 (match_op_dup 5
8605 [(match_dup 3) (const_int 0)]))
8606 (match_dup 0)))])]
8607 {
8608 if (!rtx_equal_p (operands[6], operands[0]))
8609 operands[9] = operands[7];
8610 })
8611
8612 (define_peephole2
8613 [(set (match_operand:SWI48 6 "general_reg_operand")
8614 (match_operand:SWI48 7 "memory_operand"))
8615 (set (match_operand:SWI48 8 "general_reg_operand")
8616 (match_operand:SWI48 9 "memory_operand"))
8617 (parallel [(set (reg:CCC FLAGS_REG)
8618 (compare:CCC
8619 (zero_extend:<DWI>
8620 (match_operand:SWI48 0 "general_reg_operand"))
8621 (plus:<DWI>
8622 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8623 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8624 (zero_extend:<DWI>
8625 (match_operand:SWI48 2 "general_reg_operand")))))
8626 (set (match_dup 0)
8627 (minus:SWI48
8628 (minus:SWI48
8629 (match_dup 0)
8630 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8631 [(match_dup 3) (const_int 0)]))
8632 (match_dup 2)))])
8633 (set (match_operand:QI 10 "general_reg_operand")
8634 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8635 (set (match_operand:SWI48 11 "general_reg_operand")
8636 (zero_extend:SWI48 (match_dup 10)))
8637 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8638 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8639 && peep2_reg_dead_p (6, operands[0])
8640 && peep2_reg_dead_p (3, operands[2])
8641 && !reg_overlap_mentioned_p (operands[0], operands[1])
8642 && !reg_overlap_mentioned_p (operands[2], operands[1])
8643 && !reg_overlap_mentioned_p (operands[6], operands[9])
8644 && !reg_overlap_mentioned_p (operands[0], operands[10])
8645 && !reg_overlap_mentioned_p (operands[10], operands[1])
8646 && !reg_overlap_mentioned_p (operands[0], operands[11])
8647 && !reg_overlap_mentioned_p (operands[11], operands[1])
8648 && (rtx_equal_p (operands[6], operands[0])
8649 ? (rtx_equal_p (operands[7], operands[1])
8650 && rtx_equal_p (operands[8], operands[2]))
8651 : (rtx_equal_p (operands[8], operands[0])
8652 && rtx_equal_p (operands[9], operands[1])
8653 && rtx_equal_p (operands[6], operands[2])))"
8654 [(set (match_dup 0) (match_dup 9))
8655 (parallel [(set (reg:CCC FLAGS_REG)
8656 (compare:CCC
8657 (zero_extend:<DWI> (match_dup 1))
8658 (plus:<DWI> (match_op_dup 4
8659 [(match_dup 3) (const_int 0)])
8660 (zero_extend:<DWI> (match_dup 0)))))
8661 (set (match_dup 1)
8662 (minus:SWI48 (minus:SWI48 (match_dup 1)
8663 (match_op_dup 5
8664 [(match_dup 3) (const_int 0)]))
8665 (match_dup 0)))])
8666 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8667 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8668 {
8669 if (!rtx_equal_p (operands[6], operands[0]))
8670 operands[9] = operands[7];
8671 })
8672
8673 (define_expand "subborrow<mode>_0"
8674 [(parallel
8675 [(set (reg:CC FLAGS_REG)
8676 (compare:CC
8677 (match_operand:SWI48 1 "nonimmediate_operand")
8678 (match_operand:SWI48 2 "<general_operand>")))
8679 (set (match_operand:SWI48 0 "register_operand")
8680 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8681 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8682
8683 (define_expand "uaddc<mode>5"
8684 [(match_operand:SWI48 0 "register_operand")
8685 (match_operand:SWI48 1 "register_operand")
8686 (match_operand:SWI48 2 "register_operand")
8687 (match_operand:SWI48 3 "register_operand")
8688 (match_operand:SWI48 4 "nonmemory_operand")]
8689 ""
8690 {
8691 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8692 if (operands[4] == const0_rtx)
8693 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8694 else
8695 {
8696 ix86_expand_carry (operands[4]);
8697 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8698 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8699 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8700 cf, pat, pat2));
8701 }
8702 rtx cc = gen_reg_rtx (QImode);
8703 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8704 emit_insn (gen_rtx_SET (cc, pat));
8705 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8706 DONE;
8707 })
8708
8709 (define_expand "usubc<mode>5"
8710 [(match_operand:SWI48 0 "register_operand")
8711 (match_operand:SWI48 1 "register_operand")
8712 (match_operand:SWI48 2 "register_operand")
8713 (match_operand:SWI48 3 "register_operand")
8714 (match_operand:SWI48 4 "nonmemory_operand")]
8715 ""
8716 {
8717 rtx cf, pat, pat2;
8718 if (operands[4] == const0_rtx)
8719 {
8720 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8721 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8722 operands[3]));
8723 }
8724 else
8725 {
8726 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8727 ix86_expand_carry (operands[4]);
8728 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8729 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8730 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8731 cf, pat, pat2));
8732 }
8733 rtx cc = gen_reg_rtx (QImode);
8734 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8735 emit_insn (gen_rtx_SET (cc, pat));
8736 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8737 DONE;
8738 })
8739
8740 (define_mode_iterator CC_CCC [CC CCC])
8741
8742 ;; Pre-reload splitter to optimize
8743 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8744 ;; operand and no intervening flags modifications into nothing.
8745 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8746 [(set (reg:CCC FLAGS_REG)
8747 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8748 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8749 "ix86_pre_reload_split ()"
8750 "#"
8751 "&& 1"
8752 [(const_int 0)]
8753 "emit_note (NOTE_INSN_DELETED); DONE;")
8754
8755 ;; Set the carry flag from the carry flag.
8756 (define_insn_and_split "*setccc"
8757 [(set (reg:CCC FLAGS_REG)
8758 (reg:CCC FLAGS_REG))]
8759 "ix86_pre_reload_split ()"
8760 "#"
8761 "&& 1"
8762 [(const_int 0)]
8763 "emit_note (NOTE_INSN_DELETED); DONE;")
8764
8765 ;; Set the carry flag from the carry flag.
8766 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8767 [(set (reg:CCC FLAGS_REG)
8768 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8769 "ix86_pre_reload_split ()"
8770 "#"
8771 "&& 1"
8772 [(const_int 0)]
8773 "emit_note (NOTE_INSN_DELETED); DONE;")
8774
8775 ;; Set the carry flag from the carry flag.
8776 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8777 [(set (reg:CCC FLAGS_REG)
8778 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8779 (const_int 0)] UNSPEC_CC_NE))]
8780 "ix86_pre_reload_split ()"
8781 "#"
8782 "&& 1"
8783 [(const_int 0)]
8784 "emit_note (NOTE_INSN_DELETED); DONE;")
8785 \f
8786 ;; Overflow setting add instructions
8787
8788 (define_expand "addqi3_cconly_overflow"
8789 [(parallel
8790 [(set (reg:CCC FLAGS_REG)
8791 (compare:CCC
8792 (plus:QI
8793 (match_operand:QI 0 "nonimmediate_operand")
8794 (match_operand:QI 1 "general_operand"))
8795 (match_dup 0)))
8796 (clobber (scratch:QI))])]
8797 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8798
8799 (define_insn "*add<mode>3_cconly_overflow_1"
8800 [(set (reg:CCC FLAGS_REG)
8801 (compare:CCC
8802 (plus:SWI
8803 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8804 (match_operand:SWI 2 "<general_operand>" "<g>"))
8805 (match_dup 1)))
8806 (clobber (match_scratch:SWI 0 "=<r>"))]
8807 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8808 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8809 [(set_attr "type" "alu")
8810 (set_attr "mode" "<MODE>")])
8811
8812 (define_insn "*add<mode>3_cc_overflow_1"
8813 [(set (reg:CCC FLAGS_REG)
8814 (compare:CCC
8815 (plus:SWI
8816 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8817 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8818 (match_dup 1)))
8819 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8820 (plus:SWI (match_dup 1) (match_dup 2)))]
8821 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8822 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8823 [(set_attr "type" "alu")
8824 (set_attr "mode" "<MODE>")])
8825
8826 (define_peephole2
8827 [(parallel [(set (reg:CCC FLAGS_REG)
8828 (compare:CCC
8829 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
8830 (match_operand:SWI 1 "memory_operand"))
8831 (match_dup 0)))
8832 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
8833 (set (match_dup 1) (match_dup 0))]
8834 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8835 && peep2_reg_dead_p (2, operands[0])
8836 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8837 [(parallel [(set (reg:CCC FLAGS_REG)
8838 (compare:CCC
8839 (plus:SWI (match_dup 1) (match_dup 0))
8840 (match_dup 1)))
8841 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8842
8843 (define_peephole2
8844 [(set (match_operand:SWI 0 "general_reg_operand")
8845 (match_operand:SWI 1 "memory_operand"))
8846 (parallel [(set (reg:CCC FLAGS_REG)
8847 (compare:CCC
8848 (plus:SWI (match_dup 0)
8849 (match_operand:SWI 2 "memory_operand"))
8850 (match_dup 0)))
8851 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
8852 (set (match_dup 1) (match_dup 0))]
8853 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8854 && peep2_reg_dead_p (3, operands[0])
8855 && !reg_overlap_mentioned_p (operands[0], operands[1])
8856 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8857 [(set (match_dup 0) (match_dup 2))
8858 (parallel [(set (reg:CCC FLAGS_REG)
8859 (compare:CCC
8860 (plus:SWI (match_dup 1) (match_dup 0))
8861 (match_dup 1)))
8862 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8863
8864 (define_insn "*addsi3_zext_cc_overflow_1"
8865 [(set (reg:CCC FLAGS_REG)
8866 (compare:CCC
8867 (plus:SI
8868 (match_operand:SI 1 "nonimmediate_operand" "%0")
8869 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8870 (match_dup 1)))
8871 (set (match_operand:DI 0 "register_operand" "=r")
8872 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8873 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8874 "add{l}\t{%2, %k0|%k0, %2}"
8875 [(set_attr "type" "alu")
8876 (set_attr "mode" "SI")])
8877
8878 (define_insn "*add<mode>3_cconly_overflow_2"
8879 [(set (reg:CCC FLAGS_REG)
8880 (compare:CCC
8881 (plus:SWI
8882 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8883 (match_operand:SWI 2 "<general_operand>" "<g>"))
8884 (match_dup 2)))
8885 (clobber (match_scratch:SWI 0 "=<r>"))]
8886 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8887 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8888 [(set_attr "type" "alu")
8889 (set_attr "mode" "<MODE>")])
8890
8891 (define_insn "*add<mode>3_cc_overflow_2"
8892 [(set (reg:CCC FLAGS_REG)
8893 (compare:CCC
8894 (plus:SWI
8895 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8896 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8897 (match_dup 2)))
8898 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8899 (plus:SWI (match_dup 1) (match_dup 2)))]
8900 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8901 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8902 [(set_attr "type" "alu")
8903 (set_attr "mode" "<MODE>")])
8904
8905 (define_insn "*addsi3_zext_cc_overflow_2"
8906 [(set (reg:CCC FLAGS_REG)
8907 (compare:CCC
8908 (plus:SI
8909 (match_operand:SI 1 "nonimmediate_operand" "%0")
8910 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8911 (match_dup 2)))
8912 (set (match_operand:DI 0 "register_operand" "=r")
8913 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8914 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8915 "add{l}\t{%2, %k0|%k0, %2}"
8916 [(set_attr "type" "alu")
8917 (set_attr "mode" "SI")])
8918
8919 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
8920 [(set (reg:CCC FLAGS_REG)
8921 (compare:CCC
8922 (plus:<DWI>
8923 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
8924 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
8925 (match_dup 1)))
8926 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
8927 (plus:<DWI> (match_dup 1) (match_dup 2)))]
8928 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
8929 "#"
8930 "&& reload_completed"
8931 [(parallel [(set (reg:CCC FLAGS_REG)
8932 (compare:CCC
8933 (plus:DWIH (match_dup 1) (match_dup 2))
8934 (match_dup 1)))
8935 (set (match_dup 0)
8936 (plus:DWIH (match_dup 1) (match_dup 2)))])
8937 (parallel [(set (reg:CCC FLAGS_REG)
8938 (compare:CCC
8939 (zero_extend:<DWI>
8940 (plus:DWIH
8941 (plus:DWIH
8942 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8943 (match_dup 4))
8944 (match_dup 5)))
8945 (plus:<DWI>
8946 (match_dup 6)
8947 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
8948 (set (match_dup 3)
8949 (plus:DWIH
8950 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8951 (match_dup 4))
8952 (match_dup 5)))])]
8953 {
8954 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8955 if (operands[2] == const0_rtx)
8956 {
8957 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
8958 DONE;
8959 }
8960 if (CONST_INT_P (operands[5]))
8961 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
8962 operands[5], <MODE>mode);
8963 else
8964 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
8965 })
8966
8967 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
8968 ;; test, where the latter is preferrable if we have some carry consuming
8969 ;; instruction.
8970 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
8971 ;; + (1 - CF).
8972 (define_insn_and_split "*add<mode>3_eq"
8973 [(set (match_operand:SWI 0 "nonimmediate_operand")
8974 (plus:SWI
8975 (plus:SWI
8976 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
8977 (match_operand:SWI 1 "nonimmediate_operand"))
8978 (match_operand:SWI 2 "<general_operand>")))
8979 (clobber (reg:CC FLAGS_REG))]
8980 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8981 && ix86_pre_reload_split ()"
8982 "#"
8983 "&& 1"
8984 [(set (reg:CC FLAGS_REG)
8985 (compare:CC (match_dup 3) (const_int 1)))
8986 (parallel [(set (match_dup 0)
8987 (plus:SWI
8988 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
8989 (match_dup 1))
8990 (match_dup 2)))
8991 (clobber (reg:CC FLAGS_REG))])])
8992
8993 (define_insn_and_split "*add<mode>3_ne"
8994 [(set (match_operand:SWI 0 "nonimmediate_operand")
8995 (plus:SWI
8996 (plus:SWI
8997 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
8998 (match_operand:SWI 1 "nonimmediate_operand"))
8999 (match_operand:SWI 2 "<immediate_operand>")))
9000 (clobber (reg:CC FLAGS_REG))]
9001 "CONST_INT_P (operands[2])
9002 && (<MODE>mode != DImode
9003 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9004 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
9005 && ix86_pre_reload_split ()"
9006 "#"
9007 "&& 1"
9008 [(set (reg:CC FLAGS_REG)
9009 (compare:CC (match_dup 3) (const_int 1)))
9010 (parallel [(set (match_dup 0)
9011 (minus:SWI
9012 (minus:SWI (match_dup 1)
9013 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9014 (match_dup 2)))
9015 (clobber (reg:CC FLAGS_REG))])]
9016 {
9017 operands[2] = gen_int_mode (~INTVAL (operands[2]),
9018 <MODE>mode == DImode ? SImode : <MODE>mode);
9019 })
9020
9021 (define_insn_and_split "*add<mode>3_eq_0"
9022 [(set (match_operand:SWI 0 "nonimmediate_operand")
9023 (plus:SWI
9024 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9025 (match_operand:SWI 1 "<general_operand>")))
9026 (clobber (reg:CC FLAGS_REG))]
9027 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9028 && ix86_pre_reload_split ()"
9029 "#"
9030 "&& 1"
9031 [(set (reg:CC FLAGS_REG)
9032 (compare:CC (match_dup 2) (const_int 1)))
9033 (parallel [(set (match_dup 0)
9034 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9035 (match_dup 1)))
9036 (clobber (reg:CC FLAGS_REG))])]
9037 {
9038 if (!nonimmediate_operand (operands[1], <MODE>mode))
9039 operands[1] = force_reg (<MODE>mode, operands[1]);
9040 })
9041
9042 (define_insn_and_split "*add<mode>3_ne_0"
9043 [(set (match_operand:SWI 0 "nonimmediate_operand")
9044 (plus:SWI
9045 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
9046 (match_operand:SWI 1 "<general_operand>")))
9047 (clobber (reg:CC FLAGS_REG))]
9048 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
9049 && ix86_pre_reload_split ()"
9050 "#"
9051 "&& 1"
9052 [(set (reg:CC FLAGS_REG)
9053 (compare:CC (match_dup 2) (const_int 1)))
9054 (parallel [(set (match_dup 0)
9055 (minus:SWI (minus:SWI
9056 (match_dup 1)
9057 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9058 (const_int -1)))
9059 (clobber (reg:CC FLAGS_REG))])]
9060 {
9061 if (!nonimmediate_operand (operands[1], <MODE>mode))
9062 operands[1] = force_reg (<MODE>mode, operands[1]);
9063 })
9064
9065 (define_insn_and_split "*sub<mode>3_eq"
9066 [(set (match_operand:SWI 0 "nonimmediate_operand")
9067 (minus:SWI
9068 (minus:SWI
9069 (match_operand:SWI 1 "nonimmediate_operand")
9070 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9071 (const_int 0)))
9072 (match_operand:SWI 2 "<general_operand>")))
9073 (clobber (reg:CC FLAGS_REG))]
9074 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9075 && ix86_pre_reload_split ()"
9076 "#"
9077 "&& 1"
9078 [(set (reg:CC FLAGS_REG)
9079 (compare:CC (match_dup 3) (const_int 1)))
9080 (parallel [(set (match_dup 0)
9081 (minus:SWI
9082 (minus:SWI (match_dup 1)
9083 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9084 (match_dup 2)))
9085 (clobber (reg:CC FLAGS_REG))])])
9086
9087 (define_insn_and_split "*sub<mode>3_ne"
9088 [(set (match_operand:SWI 0 "nonimmediate_operand")
9089 (plus:SWI
9090 (minus:SWI
9091 (match_operand:SWI 1 "nonimmediate_operand")
9092 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9093 (const_int 0)))
9094 (match_operand:SWI 2 "<immediate_operand>")))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "CONST_INT_P (operands[2])
9097 && (<MODE>mode != DImode
9098 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9099 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9100 && ix86_pre_reload_split ()"
9101 "#"
9102 "&& 1"
9103 [(set (reg:CC FLAGS_REG)
9104 (compare:CC (match_dup 3) (const_int 1)))
9105 (parallel [(set (match_dup 0)
9106 (plus:SWI
9107 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9108 (match_dup 1))
9109 (match_dup 2)))
9110 (clobber (reg:CC FLAGS_REG))])]
9111 {
9112 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9113 <MODE>mode == DImode ? SImode : <MODE>mode);
9114 })
9115
9116 (define_insn_and_split "*sub<mode>3_eq_1"
9117 [(set (match_operand:SWI 0 "nonimmediate_operand")
9118 (plus:SWI
9119 (minus:SWI
9120 (match_operand:SWI 1 "nonimmediate_operand")
9121 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9122 (const_int 0)))
9123 (match_operand:SWI 2 "<immediate_operand>")))
9124 (clobber (reg:CC FLAGS_REG))]
9125 "CONST_INT_P (operands[2])
9126 && (<MODE>mode != DImode
9127 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9128 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9129 && ix86_pre_reload_split ()"
9130 "#"
9131 "&& 1"
9132 [(set (reg:CC FLAGS_REG)
9133 (compare:CC (match_dup 3) (const_int 1)))
9134 (parallel [(set (match_dup 0)
9135 (minus:SWI
9136 (minus:SWI (match_dup 1)
9137 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9138 (match_dup 2)))
9139 (clobber (reg:CC FLAGS_REG))])]
9140 {
9141 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9142 <MODE>mode == DImode ? SImode : <MODE>mode);
9143 })
9144
9145 (define_insn_and_split "*sub<mode>3_eq_0"
9146 [(set (match_operand:SWI 0 "nonimmediate_operand")
9147 (minus:SWI
9148 (match_operand:SWI 1 "<general_operand>")
9149 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9150 (clobber (reg:CC FLAGS_REG))]
9151 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9152 && ix86_pre_reload_split ()"
9153 "#"
9154 "&& 1"
9155 [(set (reg:CC FLAGS_REG)
9156 (compare:CC (match_dup 2) (const_int 1)))
9157 (parallel [(set (match_dup 0)
9158 (minus:SWI (match_dup 1)
9159 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9160 (clobber (reg:CC FLAGS_REG))])]
9161 {
9162 if (!nonimmediate_operand (operands[1], <MODE>mode))
9163 operands[1] = force_reg (<MODE>mode, operands[1]);
9164 })
9165
9166 (define_insn_and_split "*sub<mode>3_ne_0"
9167 [(set (match_operand:SWI 0 "nonimmediate_operand")
9168 (minus:SWI
9169 (match_operand:SWI 1 "<general_operand>")
9170 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9171 (clobber (reg:CC FLAGS_REG))]
9172 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9173 && ix86_pre_reload_split ()"
9174 "#"
9175 "&& 1"
9176 [(set (reg:CC FLAGS_REG)
9177 (compare:CC (match_dup 2) (const_int 1)))
9178 (parallel [(set (match_dup 0)
9179 (plus:SWI (plus:SWI
9180 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9181 (match_dup 1))
9182 (const_int -1)))
9183 (clobber (reg:CC FLAGS_REG))])]
9184 {
9185 if (!nonimmediate_operand (operands[1], <MODE>mode))
9186 operands[1] = force_reg (<MODE>mode, operands[1]);
9187 })
9188
9189 ;; The patterns that match these are at the end of this file.
9190
9191 (define_expand "<insn>xf3"
9192 [(set (match_operand:XF 0 "register_operand")
9193 (plusminus:XF
9194 (match_operand:XF 1 "register_operand")
9195 (match_operand:XF 2 "register_operand")))]
9196 "TARGET_80387")
9197
9198 (define_expand "<insn>hf3"
9199 [(set (match_operand:HF 0 "register_operand")
9200 (plusminus:HF
9201 (match_operand:HF 1 "register_operand")
9202 (match_operand:HF 2 "nonimmediate_operand")))]
9203 "TARGET_AVX512FP16")
9204
9205 (define_expand "<insn><mode>3"
9206 [(set (match_operand:MODEF 0 "register_operand")
9207 (plusminus:MODEF
9208 (match_operand:MODEF 1 "register_operand")
9209 (match_operand:MODEF 2 "nonimmediate_operand")))]
9210 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9211 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9212 \f
9213 ;; Multiply instructions
9214
9215 (define_expand "mul<mode>3"
9216 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9217 (mult:SWIM248
9218 (match_operand:SWIM248 1 "register_operand")
9219 (match_operand:SWIM248 2 "<general_operand>")))
9220 (clobber (reg:CC FLAGS_REG))])])
9221
9222 (define_expand "mulqi3"
9223 [(parallel [(set (match_operand:QI 0 "register_operand")
9224 (mult:QI
9225 (match_operand:QI 1 "register_operand")
9226 (match_operand:QI 2 "nonimmediate_operand")))
9227 (clobber (reg:CC FLAGS_REG))])]
9228 "TARGET_QIMODE_MATH")
9229
9230 ;; On AMDFAM10
9231 ;; IMUL reg32/64, reg32/64, imm8 Direct
9232 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9233 ;; IMUL reg32/64, reg32/64, imm32 Direct
9234 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9235 ;; IMUL reg32/64, reg32/64 Direct
9236 ;; IMUL reg32/64, mem32/64 Direct
9237 ;;
9238 ;; On BDVER1, all above IMULs use DirectPath
9239 ;;
9240 ;; On AMDFAM10
9241 ;; IMUL reg16, reg16, imm8 VectorPath
9242 ;; IMUL reg16, mem16, imm8 VectorPath
9243 ;; IMUL reg16, reg16, imm16 VectorPath
9244 ;; IMUL reg16, mem16, imm16 VectorPath
9245 ;; IMUL reg16, reg16 Direct
9246 ;; IMUL reg16, mem16 Direct
9247 ;;
9248 ;; On BDVER1, all HI MULs use DoublePath
9249
9250 (define_insn "*mul<mode>3_1"
9251 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9252 (mult:SWIM248
9253 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9254 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9255 (clobber (reg:CC FLAGS_REG))]
9256 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9257 "@
9258 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9259 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9260 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9261 [(set_attr "type" "imul")
9262 (set_attr "prefix_0f" "0,0,1")
9263 (set (attr "athlon_decode")
9264 (cond [(eq_attr "cpu" "athlon")
9265 (const_string "vector")
9266 (eq_attr "alternative" "1")
9267 (const_string "vector")
9268 (and (eq_attr "alternative" "2")
9269 (ior (match_test "<MODE>mode == HImode")
9270 (match_operand 1 "memory_operand")))
9271 (const_string "vector")]
9272 (const_string "direct")))
9273 (set (attr "amdfam10_decode")
9274 (cond [(and (eq_attr "alternative" "0,1")
9275 (ior (match_test "<MODE>mode == HImode")
9276 (match_operand 1 "memory_operand")))
9277 (const_string "vector")]
9278 (const_string "direct")))
9279 (set (attr "bdver1_decode")
9280 (if_then_else
9281 (match_test "<MODE>mode == HImode")
9282 (const_string "double")
9283 (const_string "direct")))
9284 (set_attr "mode" "<MODE>")])
9285
9286 (define_insn "*mulsi3_1_zext"
9287 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9288 (zero_extend:DI
9289 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9290 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9291 (clobber (reg:CC FLAGS_REG))]
9292 "TARGET_64BIT
9293 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9294 "@
9295 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9296 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9297 imul{l}\t{%2, %k0|%k0, %2}"
9298 [(set_attr "type" "imul")
9299 (set_attr "prefix_0f" "0,0,1")
9300 (set (attr "athlon_decode")
9301 (cond [(eq_attr "cpu" "athlon")
9302 (const_string "vector")
9303 (eq_attr "alternative" "1")
9304 (const_string "vector")
9305 (and (eq_attr "alternative" "2")
9306 (match_operand 1 "memory_operand"))
9307 (const_string "vector")]
9308 (const_string "direct")))
9309 (set (attr "amdfam10_decode")
9310 (cond [(and (eq_attr "alternative" "0,1")
9311 (match_operand 1 "memory_operand"))
9312 (const_string "vector")]
9313 (const_string "direct")))
9314 (set_attr "bdver1_decode" "direct")
9315 (set_attr "mode" "SI")])
9316
9317 ;;On AMDFAM10 and BDVER1
9318 ;; MUL reg8 Direct
9319 ;; MUL mem8 Direct
9320
9321 (define_insn "*mulqi3_1"
9322 [(set (match_operand:QI 0 "register_operand" "=a")
9323 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9324 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9325 (clobber (reg:CC FLAGS_REG))]
9326 "TARGET_QIMODE_MATH
9327 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9328 "mul{b}\t%2"
9329 [(set_attr "type" "imul")
9330 (set_attr "length_immediate" "0")
9331 (set (attr "athlon_decode")
9332 (if_then_else (eq_attr "cpu" "athlon")
9333 (const_string "vector")
9334 (const_string "direct")))
9335 (set_attr "amdfam10_decode" "direct")
9336 (set_attr "bdver1_decode" "direct")
9337 (set_attr "mode" "QI")])
9338
9339 ;; Multiply with jump on overflow.
9340 (define_expand "mulv<mode>4"
9341 [(parallel [(set (reg:CCO FLAGS_REG)
9342 (eq:CCO (mult:<DWI>
9343 (sign_extend:<DWI>
9344 (match_operand:SWI248 1 "register_operand"))
9345 (match_dup 4))
9346 (sign_extend:<DWI>
9347 (mult:SWI248 (match_dup 1)
9348 (match_operand:SWI248 2
9349 "<general_operand>")))))
9350 (set (match_operand:SWI248 0 "register_operand")
9351 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9352 (set (pc) (if_then_else
9353 (eq (reg:CCO FLAGS_REG) (const_int 0))
9354 (label_ref (match_operand 3))
9355 (pc)))]
9356 ""
9357 {
9358 if (CONST_INT_P (operands[2]))
9359 operands[4] = operands[2];
9360 else
9361 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9362 })
9363
9364 (define_insn "*mulv<mode>4"
9365 [(set (reg:CCO FLAGS_REG)
9366 (eq:CCO (mult:<DWI>
9367 (sign_extend:<DWI>
9368 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9369 (sign_extend:<DWI>
9370 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9371 (sign_extend:<DWI>
9372 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9373 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9374 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9375 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9376 "@
9377 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9378 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9379 [(set_attr "type" "imul")
9380 (set_attr "prefix_0f" "0,1")
9381 (set (attr "athlon_decode")
9382 (cond [(eq_attr "cpu" "athlon")
9383 (const_string "vector")
9384 (eq_attr "alternative" "0")
9385 (const_string "vector")
9386 (and (eq_attr "alternative" "1")
9387 (match_operand 1 "memory_operand"))
9388 (const_string "vector")]
9389 (const_string "direct")))
9390 (set (attr "amdfam10_decode")
9391 (cond [(and (eq_attr "alternative" "1")
9392 (match_operand 1 "memory_operand"))
9393 (const_string "vector")]
9394 (const_string "direct")))
9395 (set_attr "bdver1_decode" "direct")
9396 (set_attr "mode" "<MODE>")])
9397
9398 (define_insn "*mulvhi4"
9399 [(set (reg:CCO FLAGS_REG)
9400 (eq:CCO (mult:SI
9401 (sign_extend:SI
9402 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9403 (sign_extend:SI
9404 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9405 (sign_extend:SI
9406 (mult:HI (match_dup 1) (match_dup 2)))))
9407 (set (match_operand:HI 0 "register_operand" "=r")
9408 (mult:HI (match_dup 1) (match_dup 2)))]
9409 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9410 "imul{w}\t{%2, %0|%0, %2}"
9411 [(set_attr "type" "imul")
9412 (set_attr "prefix_0f" "1")
9413 (set_attr "athlon_decode" "vector")
9414 (set_attr "amdfam10_decode" "direct")
9415 (set_attr "bdver1_decode" "double")
9416 (set_attr "mode" "HI")])
9417
9418 (define_insn "*mulv<mode>4_1"
9419 [(set (reg:CCO FLAGS_REG)
9420 (eq:CCO (mult:<DWI>
9421 (sign_extend:<DWI>
9422 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9423 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9424 (sign_extend:<DWI>
9425 (mult:SWI248 (match_dup 1)
9426 (match_operand:SWI248 2
9427 "<immediate_operand>" "K,<i>")))))
9428 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9429 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9430 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9431 && CONST_INT_P (operands[2])
9432 && INTVAL (operands[2]) == INTVAL (operands[3])"
9433 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9434 [(set_attr "type" "imul")
9435 (set (attr "prefix_0f")
9436 (if_then_else
9437 (match_test "<MODE>mode == HImode")
9438 (const_string "0")
9439 (const_string "*")))
9440 (set (attr "athlon_decode")
9441 (cond [(eq_attr "cpu" "athlon")
9442 (const_string "vector")
9443 (eq_attr "alternative" "1")
9444 (const_string "vector")]
9445 (const_string "direct")))
9446 (set (attr "amdfam10_decode")
9447 (cond [(ior (match_test "<MODE>mode == HImode")
9448 (match_operand 1 "memory_operand"))
9449 (const_string "vector")]
9450 (const_string "direct")))
9451 (set (attr "bdver1_decode")
9452 (if_then_else
9453 (match_test "<MODE>mode == HImode")
9454 (const_string "double")
9455 (const_string "direct")))
9456 (set_attr "mode" "<MODE>")
9457 (set (attr "length_immediate")
9458 (cond [(eq_attr "alternative" "0")
9459 (const_string "1")
9460 (match_test "<MODE_SIZE> == 8")
9461 (const_string "4")]
9462 (const_string "<MODE_SIZE>")))])
9463
9464 (define_expand "umulv<mode>4"
9465 [(parallel [(set (reg:CCO FLAGS_REG)
9466 (eq:CCO (mult:<DWI>
9467 (zero_extend:<DWI>
9468 (match_operand:SWI248 1
9469 "nonimmediate_operand"))
9470 (zero_extend:<DWI>
9471 (match_operand:SWI248 2
9472 "nonimmediate_operand")))
9473 (zero_extend:<DWI>
9474 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9475 (set (match_operand:SWI248 0 "register_operand")
9476 (mult:SWI248 (match_dup 1) (match_dup 2)))
9477 (clobber (scratch:SWI248))])
9478 (set (pc) (if_then_else
9479 (eq (reg:CCO FLAGS_REG) (const_int 0))
9480 (label_ref (match_operand 3))
9481 (pc)))]
9482 ""
9483 {
9484 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9485 operands[1] = force_reg (<MODE>mode, operands[1]);
9486 })
9487
9488 (define_insn "*umulv<mode>4"
9489 [(set (reg:CCO FLAGS_REG)
9490 (eq:CCO (mult:<DWI>
9491 (zero_extend:<DWI>
9492 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9493 (zero_extend:<DWI>
9494 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9495 (zero_extend:<DWI>
9496 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9497 (set (match_operand:SWI248 0 "register_operand" "=a")
9498 (mult:SWI248 (match_dup 1) (match_dup 2)))
9499 (clobber (match_scratch:SWI248 3 "=d"))]
9500 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9501 "mul{<imodesuffix>}\t%2"
9502 [(set_attr "type" "imul")
9503 (set_attr "length_immediate" "0")
9504 (set (attr "athlon_decode")
9505 (if_then_else (eq_attr "cpu" "athlon")
9506 (const_string "vector")
9507 (const_string "double")))
9508 (set_attr "amdfam10_decode" "double")
9509 (set_attr "bdver1_decode" "direct")
9510 (set_attr "mode" "<MODE>")])
9511
9512 (define_expand "<u>mulvqi4"
9513 [(parallel [(set (reg:CCO FLAGS_REG)
9514 (eq:CCO (mult:HI
9515 (any_extend:HI
9516 (match_operand:QI 1 "nonimmediate_operand"))
9517 (any_extend:HI
9518 (match_operand:QI 2 "nonimmediate_operand")))
9519 (any_extend:HI
9520 (mult:QI (match_dup 1) (match_dup 2)))))
9521 (set (match_operand:QI 0 "register_operand")
9522 (mult:QI (match_dup 1) (match_dup 2)))])
9523 (set (pc) (if_then_else
9524 (eq (reg:CCO FLAGS_REG) (const_int 0))
9525 (label_ref (match_operand 3))
9526 (pc)))]
9527 "TARGET_QIMODE_MATH"
9528 {
9529 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9530 operands[1] = force_reg (QImode, operands[1]);
9531 })
9532
9533 (define_insn "*<u>mulvqi4"
9534 [(set (reg:CCO FLAGS_REG)
9535 (eq:CCO (mult:HI
9536 (any_extend:HI
9537 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9538 (any_extend:HI
9539 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9540 (any_extend:HI
9541 (mult:QI (match_dup 1) (match_dup 2)))))
9542 (set (match_operand:QI 0 "register_operand" "=a")
9543 (mult:QI (match_dup 1) (match_dup 2)))]
9544 "TARGET_QIMODE_MATH
9545 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9546 "<sgnprefix>mul{b}\t%2"
9547 [(set_attr "type" "imul")
9548 (set_attr "length_immediate" "0")
9549 (set (attr "athlon_decode")
9550 (if_then_else (eq_attr "cpu" "athlon")
9551 (const_string "vector")
9552 (const_string "direct")))
9553 (set_attr "amdfam10_decode" "direct")
9554 (set_attr "bdver1_decode" "direct")
9555 (set_attr "mode" "QI")])
9556
9557 (define_expand "<u>mul<mode><dwi>3"
9558 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9559 (mult:<DWI>
9560 (any_extend:<DWI>
9561 (match_operand:DWIH 1 "nonimmediate_operand"))
9562 (any_extend:<DWI>
9563 (match_operand:DWIH 2 "register_operand"))))
9564 (clobber (reg:CC FLAGS_REG))])])
9565
9566 (define_expand "<u>mulqihi3"
9567 [(parallel [(set (match_operand:HI 0 "register_operand")
9568 (mult:HI
9569 (any_extend:HI
9570 (match_operand:QI 1 "nonimmediate_operand"))
9571 (any_extend:HI
9572 (match_operand:QI 2 "register_operand"))))
9573 (clobber (reg:CC FLAGS_REG))])]
9574 "TARGET_QIMODE_MATH")
9575
9576 (define_insn "*bmi2_umul<mode><dwi>3_1"
9577 [(set (match_operand:DWIH 0 "register_operand" "=r")
9578 (mult:DWIH
9579 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
9580 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9581 (set (match_operand:DWIH 1 "register_operand" "=r")
9582 (truncate:DWIH
9583 (lshiftrt:<DWI>
9584 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9585 (zero_extend:<DWI> (match_dup 3)))
9586 (match_operand:QI 4 "const_int_operand"))))]
9587 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
9588 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
9589 "mulx\t{%3, %0, %1|%1, %0, %3}"
9590 [(set_attr "type" "imulx")
9591 (set_attr "prefix" "vex")
9592 (set_attr "mode" "<MODE>")])
9593
9594 (define_insn "*umul<mode><dwi>3_1"
9595 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9596 (mult:<DWI>
9597 (zero_extend:<DWI>
9598 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
9599 (zero_extend:<DWI>
9600 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9601 (clobber (reg:CC FLAGS_REG))]
9602 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9603 "@
9604 #
9605 mul{<imodesuffix>}\t%2"
9606 [(set_attr "isa" "bmi2,*")
9607 (set_attr "type" "imulx,imul")
9608 (set_attr "length_immediate" "*,0")
9609 (set (attr "athlon_decode")
9610 (cond [(eq_attr "alternative" "1")
9611 (if_then_else (eq_attr "cpu" "athlon")
9612 (const_string "vector")
9613 (const_string "double"))]
9614 (const_string "*")))
9615 (set_attr "amdfam10_decode" "*,double")
9616 (set_attr "bdver1_decode" "*,direct")
9617 (set_attr "prefix" "vex,orig")
9618 (set_attr "mode" "<MODE>")])
9619
9620 ;; Convert mul to the mulx pattern to avoid flags dependency.
9621 (define_split
9622 [(set (match_operand:<DWI> 0 "register_operand")
9623 (mult:<DWI>
9624 (zero_extend:<DWI>
9625 (match_operand:DWIH 1 "register_operand"))
9626 (zero_extend:<DWI>
9627 (match_operand:DWIH 2 "nonimmediate_operand"))))
9628 (clobber (reg:CC FLAGS_REG))]
9629 "TARGET_BMI2 && reload_completed
9630 && REGNO (operands[1]) == DX_REG"
9631 [(parallel [(set (match_dup 3)
9632 (mult:DWIH (match_dup 1) (match_dup 2)))
9633 (set (match_dup 4)
9634 (truncate:DWIH
9635 (lshiftrt:<DWI>
9636 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
9637 (zero_extend:<DWI> (match_dup 2)))
9638 (match_dup 5))))])]
9639 {
9640 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9641
9642 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9643 })
9644
9645 (define_insn "*mul<mode><dwi>3_1"
9646 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9647 (mult:<DWI>
9648 (sign_extend:<DWI>
9649 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
9650 (sign_extend:<DWI>
9651 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9652 (clobber (reg:CC FLAGS_REG))]
9653 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9654 "imul{<imodesuffix>}\t%2"
9655 [(set_attr "type" "imul")
9656 (set_attr "length_immediate" "0")
9657 (set (attr "athlon_decode")
9658 (if_then_else (eq_attr "cpu" "athlon")
9659 (const_string "vector")
9660 (const_string "double")))
9661 (set_attr "amdfam10_decode" "double")
9662 (set_attr "bdver1_decode" "direct")
9663 (set_attr "mode" "<MODE>")])
9664
9665 (define_insn "*<u>mulqihi3_1"
9666 [(set (match_operand:HI 0 "register_operand" "=a")
9667 (mult:HI
9668 (any_extend:HI
9669 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9670 (any_extend:HI
9671 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9672 (clobber (reg:CC FLAGS_REG))]
9673 "TARGET_QIMODE_MATH
9674 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9675 "<sgnprefix>mul{b}\t%2"
9676 [(set_attr "type" "imul")
9677 (set_attr "length_immediate" "0")
9678 (set (attr "athlon_decode")
9679 (if_then_else (eq_attr "cpu" "athlon")
9680 (const_string "vector")
9681 (const_string "direct")))
9682 (set_attr "amdfam10_decode" "direct")
9683 (set_attr "bdver1_decode" "direct")
9684 (set_attr "mode" "QI")])
9685
9686 ;; Highpart multiplication patterns
9687 (define_insn "<s>mul<mode>3_highpart"
9688 [(set (match_operand:DWIH 0 "register_operand" "=d")
9689 (any_mul_highpart:DWIH
9690 (match_operand:DWIH 1 "register_operand" "%a")
9691 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9692 (clobber (match_scratch:DWIH 3 "=1"))
9693 (clobber (reg:CC FLAGS_REG))]
9694 ""
9695 "<sgnprefix>mul{<imodesuffix>}\t%2"
9696 [(set_attr "type" "imul")
9697 (set_attr "length_immediate" "0")
9698 (set (attr "athlon_decode")
9699 (if_then_else (eq_attr "cpu" "athlon")
9700 (const_string "vector")
9701 (const_string "double")))
9702 (set_attr "amdfam10_decode" "double")
9703 (set_attr "bdver1_decode" "direct")
9704 (set_attr "mode" "<MODE>")])
9705
9706 (define_insn "*<s>mulsi3_highpart_zext"
9707 [(set (match_operand:DI 0 "register_operand" "=d")
9708 (zero_extend:DI
9709 (any_mul_highpart:SI
9710 (match_operand:SI 1 "register_operand" "%a")
9711 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9712 (clobber (match_scratch:SI 3 "=1"))
9713 (clobber (reg:CC FLAGS_REG))]
9714 "TARGET_64BIT"
9715 "<sgnprefix>mul{l}\t%2"
9716 [(set_attr "type" "imul")
9717 (set_attr "length_immediate" "0")
9718 (set (attr "athlon_decode")
9719 (if_then_else (eq_attr "cpu" "athlon")
9720 (const_string "vector")
9721 (const_string "double")))
9722 (set_attr "amdfam10_decode" "double")
9723 (set_attr "bdver1_decode" "direct")
9724 (set_attr "mode" "SI")])
9725
9726 (define_insn "*<s>muldi3_highpart_1"
9727 [(set (match_operand:DI 0 "register_operand" "=d")
9728 (truncate:DI
9729 (lshiftrt:TI
9730 (mult:TI
9731 (any_extend:TI
9732 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9733 (any_extend:TI
9734 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9735 (const_int 64))))
9736 (clobber (match_scratch:DI 3 "=1"))
9737 (clobber (reg:CC FLAGS_REG))]
9738 "TARGET_64BIT
9739 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9740 "<sgnprefix>mul{q}\t%2"
9741 [(set_attr "type" "imul")
9742 (set_attr "length_immediate" "0")
9743 (set (attr "athlon_decode")
9744 (if_then_else (eq_attr "cpu" "athlon")
9745 (const_string "vector")
9746 (const_string "double")))
9747 (set_attr "amdfam10_decode" "double")
9748 (set_attr "bdver1_decode" "direct")
9749 (set_attr "mode" "DI")])
9750
9751 (define_insn "*<s>mulsi3_highpart_zext"
9752 [(set (match_operand:DI 0 "register_operand" "=d")
9753 (zero_extend:DI (truncate:SI
9754 (lshiftrt:DI
9755 (mult:DI (any_extend:DI
9756 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9757 (any_extend:DI
9758 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9759 (const_int 32)))))
9760 (clobber (match_scratch:SI 3 "=1"))
9761 (clobber (reg:CC FLAGS_REG))]
9762 "TARGET_64BIT
9763 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9764 "<sgnprefix>mul{l}\t%2"
9765 [(set_attr "type" "imul")
9766 (set_attr "length_immediate" "0")
9767 (set (attr "athlon_decode")
9768 (if_then_else (eq_attr "cpu" "athlon")
9769 (const_string "vector")
9770 (const_string "double")))
9771 (set_attr "amdfam10_decode" "double")
9772 (set_attr "bdver1_decode" "direct")
9773 (set_attr "mode" "SI")])
9774
9775 (define_insn "*<s>mulsi3_highpart_1"
9776 [(set (match_operand:SI 0 "register_operand" "=d")
9777 (truncate:SI
9778 (lshiftrt:DI
9779 (mult:DI
9780 (any_extend:DI
9781 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9782 (any_extend:DI
9783 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9784 (const_int 32))))
9785 (clobber (match_scratch:SI 3 "=1"))
9786 (clobber (reg:CC FLAGS_REG))]
9787 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9788 "<sgnprefix>mul{l}\t%2"
9789 [(set_attr "type" "imul")
9790 (set_attr "length_immediate" "0")
9791 (set (attr "athlon_decode")
9792 (if_then_else (eq_attr "cpu" "athlon")
9793 (const_string "vector")
9794 (const_string "double")))
9795 (set_attr "amdfam10_decode" "double")
9796 (set_attr "bdver1_decode" "direct")
9797 (set_attr "mode" "SI")])
9798
9799 ;; Highpart multiplication peephole2s to tweak register allocation.
9800 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
9801 (define_peephole2
9802 [(set (match_operand:SWI48 0 "general_reg_operand")
9803 (match_operand:SWI48 1 "immediate_operand"))
9804 (set (match_operand:SWI48 2 "general_reg_operand")
9805 (match_operand:SWI48 3 "general_reg_operand"))
9806 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
9807 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
9808 (clobber (match_dup 2))
9809 (clobber (reg:CC FLAGS_REG))])]
9810 "REGNO (operands[3]) != AX_REG
9811 && REGNO (operands[0]) != REGNO (operands[2])
9812 && REGNO (operands[0]) != REGNO (operands[3])
9813 && (REGNO (operands[0]) == REGNO (operands[4])
9814 || peep2_reg_dead_p (3, operands[0]))"
9815 [(set (match_dup 2) (match_dup 1))
9816 (parallel [(set (match_dup 4)
9817 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
9818 (clobber (match_dup 2))
9819 (clobber (reg:CC FLAGS_REG))])])
9820
9821 (define_peephole2
9822 [(set (match_operand:SI 0 "general_reg_operand")
9823 (match_operand:SI 1 "immediate_operand"))
9824 (set (match_operand:SI 2 "general_reg_operand")
9825 (match_operand:SI 3 "general_reg_operand"))
9826 (parallel [(set (match_operand:DI 4 "general_reg_operand")
9827 (zero_extend:DI
9828 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
9829 (clobber (match_dup 2))
9830 (clobber (reg:CC FLAGS_REG))])]
9831 "TARGET_64BIT
9832 && REGNO (operands[3]) != AX_REG
9833 && REGNO (operands[0]) != REGNO (operands[2])
9834 && REGNO (operands[2]) != REGNO (operands[3])
9835 && REGNO (operands[0]) != REGNO (operands[3])
9836 && (REGNO (operands[0]) == REGNO (operands[4])
9837 || peep2_reg_dead_p (3, operands[0]))"
9838 [(set (match_dup 2) (match_dup 1))
9839 (parallel [(set (match_dup 4)
9840 (zero_extend:DI
9841 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
9842 (clobber (match_dup 2))
9843 (clobber (reg:CC FLAGS_REG))])])
9844
9845 ;; The patterns that match these are at the end of this file.
9846
9847 (define_expand "mulxf3"
9848 [(set (match_operand:XF 0 "register_operand")
9849 (mult:XF (match_operand:XF 1 "register_operand")
9850 (match_operand:XF 2 "register_operand")))]
9851 "TARGET_80387")
9852
9853 (define_expand "mulhf3"
9854 [(set (match_operand:HF 0 "register_operand")
9855 (mult:HF (match_operand:HF 1 "register_operand")
9856 (match_operand:HF 2 "nonimmediate_operand")))]
9857 "TARGET_AVX512FP16")
9858
9859 (define_expand "mul<mode>3"
9860 [(set (match_operand:MODEF 0 "register_operand")
9861 (mult:MODEF (match_operand:MODEF 1 "register_operand")
9862 (match_operand:MODEF 2 "nonimmediate_operand")))]
9863 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9864 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9865 \f
9866 ;; Divide instructions
9867
9868 ;; The patterns that match these are at the end of this file.
9869
9870 (define_expand "divxf3"
9871 [(set (match_operand:XF 0 "register_operand")
9872 (div:XF (match_operand:XF 1 "register_operand")
9873 (match_operand:XF 2 "register_operand")))]
9874 "TARGET_80387")
9875
9876 /* There is no more precision loss than Newton-Rhapson approximation
9877 when using HFmode rcp/rsqrt, so do the transformation directly under
9878 TARGET_RECIP_DIV and fast-math. */
9879 (define_expand "divhf3"
9880 [(set (match_operand:HF 0 "register_operand")
9881 (div:HF (match_operand:HF 1 "register_operand")
9882 (match_operand:HF 2 "nonimmediate_operand")))]
9883 "TARGET_AVX512FP16"
9884 {
9885 if (TARGET_RECIP_DIV
9886 && optimize_insn_for_speed_p ()
9887 && flag_finite_math_only && !flag_trapping_math
9888 && flag_unsafe_math_optimizations)
9889 {
9890 rtx op = gen_reg_rtx (HFmode);
9891 operands[2] = force_reg (HFmode, operands[2]);
9892 emit_insn (gen_rcphf2 (op, operands[2]));
9893 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
9894 DONE;
9895 }
9896 })
9897
9898 (define_expand "div<mode>3"
9899 [(set (match_operand:MODEF 0 "register_operand")
9900 (div:MODEF (match_operand:MODEF 1 "register_operand")
9901 (match_operand:MODEF 2 "nonimmediate_operand")))]
9902 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9903 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9904 {
9905 if (<MODE>mode == SFmode
9906 && TARGET_SSE && TARGET_SSE_MATH
9907 && TARGET_RECIP_DIV
9908 && optimize_insn_for_speed_p ()
9909 && flag_finite_math_only && !flag_trapping_math
9910 && flag_unsafe_math_optimizations)
9911 {
9912 ix86_emit_swdivsf (operands[0], operands[1],
9913 operands[2], SFmode);
9914 DONE;
9915 }
9916 })
9917 \f
9918 ;; Divmod instructions.
9919
9920 (define_code_iterator any_div [div udiv])
9921 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
9922
9923 (define_expand "<u>divmod<mode>4"
9924 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9925 (any_div:SWIM248
9926 (match_operand:SWIM248 1 "register_operand")
9927 (match_operand:SWIM248 2 "nonimmediate_operand")))
9928 (set (match_operand:SWIM248 3 "register_operand")
9929 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
9930 (clobber (reg:CC FLAGS_REG))])])
9931
9932 ;; Split with 8bit unsigned divide:
9933 ;; if (dividend an divisor are in [0-255])
9934 ;; use 8bit unsigned integer divide
9935 ;; else
9936 ;; use original integer divide
9937 (define_split
9938 [(set (match_operand:SWI48 0 "register_operand")
9939 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
9940 (match_operand:SWI48 3 "nonimmediate_operand")))
9941 (set (match_operand:SWI48 1 "register_operand")
9942 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
9943 (clobber (reg:CC FLAGS_REG))]
9944 "TARGET_USE_8BIT_IDIV
9945 && TARGET_QIMODE_MATH
9946 && can_create_pseudo_p ()
9947 && !optimize_insn_for_size_p ()"
9948 [(const_int 0)]
9949 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
9950
9951 (define_split
9952 [(set (match_operand:DI 0 "register_operand")
9953 (zero_extend:DI
9954 (any_div:SI (match_operand:SI 2 "register_operand")
9955 (match_operand:SI 3 "nonimmediate_operand"))))
9956 (set (match_operand:SI 1 "register_operand")
9957 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
9958 (clobber (reg:CC FLAGS_REG))]
9959 "TARGET_64BIT
9960 && TARGET_USE_8BIT_IDIV
9961 && TARGET_QIMODE_MATH
9962 && can_create_pseudo_p ()
9963 && !optimize_insn_for_size_p ()"
9964 [(const_int 0)]
9965 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
9966
9967 (define_split
9968 [(set (match_operand:DI 1 "register_operand")
9969 (zero_extend:DI
9970 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
9971 (match_operand:SI 3 "nonimmediate_operand"))))
9972 (set (match_operand:SI 0 "register_operand")
9973 (any_div:SI (match_dup 2) (match_dup 3)))
9974 (clobber (reg:CC FLAGS_REG))]
9975 "TARGET_64BIT
9976 && TARGET_USE_8BIT_IDIV
9977 && TARGET_QIMODE_MATH
9978 && can_create_pseudo_p ()
9979 && !optimize_insn_for_size_p ()"
9980 [(const_int 0)]
9981 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
9982
9983 (define_insn_and_split "divmod<mode>4_1"
9984 [(set (match_operand:SWI48 0 "register_operand" "=a")
9985 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
9986 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
9987 (set (match_operand:SWI48 1 "register_operand" "=&d")
9988 (mod:SWI48 (match_dup 2) (match_dup 3)))
9989 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
9990 (clobber (reg:CC FLAGS_REG))]
9991 ""
9992 "#"
9993 "reload_completed"
9994 [(parallel [(set (match_dup 1)
9995 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
9996 (clobber (reg:CC FLAGS_REG))])
9997 (parallel [(set (match_dup 0)
9998 (div:SWI48 (match_dup 2) (match_dup 3)))
9999 (set (match_dup 1)
10000 (mod:SWI48 (match_dup 2) (match_dup 3)))
10001 (use (match_dup 1))
10002 (clobber (reg:CC FLAGS_REG))])]
10003 {
10004 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10005
10006 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10007 operands[4] = operands[2];
10008 else
10009 {
10010 /* Avoid use of cltd in favor of a mov+shift. */
10011 emit_move_insn (operands[1], operands[2]);
10012 operands[4] = operands[1];
10013 }
10014 }
10015 [(set_attr "type" "multi")
10016 (set_attr "mode" "<MODE>")])
10017
10018 (define_insn_and_split "udivmod<mode>4_1"
10019 [(set (match_operand:SWI48 0 "register_operand" "=a")
10020 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10021 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
10022 (set (match_operand:SWI48 1 "register_operand" "=&d")
10023 (umod:SWI48 (match_dup 2) (match_dup 3)))
10024 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10025 (clobber (reg:CC FLAGS_REG))]
10026 ""
10027 "#"
10028 "reload_completed"
10029 [(set (match_dup 1) (const_int 0))
10030 (parallel [(set (match_dup 0)
10031 (udiv:SWI48 (match_dup 2) (match_dup 3)))
10032 (set (match_dup 1)
10033 (umod:SWI48 (match_dup 2) (match_dup 3)))
10034 (use (match_dup 1))
10035 (clobber (reg:CC FLAGS_REG))])]
10036 ""
10037 [(set_attr "type" "multi")
10038 (set_attr "mode" "<MODE>")])
10039
10040 (define_insn_and_split "divmodsi4_zext_1"
10041 [(set (match_operand:DI 0 "register_operand" "=a")
10042 (zero_extend:DI
10043 (div:SI (match_operand:SI 2 "register_operand" "0")
10044 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10045 (set (match_operand:SI 1 "register_operand" "=&d")
10046 (mod:SI (match_dup 2) (match_dup 3)))
10047 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10048 (clobber (reg:CC FLAGS_REG))]
10049 "TARGET_64BIT"
10050 "#"
10051 "&& reload_completed"
10052 [(parallel [(set (match_dup 1)
10053 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10054 (clobber (reg:CC FLAGS_REG))])
10055 (parallel [(set (match_dup 0)
10056 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10057 (set (match_dup 1)
10058 (mod:SI (match_dup 2) (match_dup 3)))
10059 (use (match_dup 1))
10060 (clobber (reg:CC FLAGS_REG))])]
10061 {
10062 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10063
10064 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10065 operands[4] = operands[2];
10066 else
10067 {
10068 /* Avoid use of cltd in favor of a mov+shift. */
10069 emit_move_insn (operands[1], operands[2]);
10070 operands[4] = operands[1];
10071 }
10072 }
10073 [(set_attr "type" "multi")
10074 (set_attr "mode" "SI")])
10075
10076 (define_insn_and_split "udivmodsi4_zext_1"
10077 [(set (match_operand:DI 0 "register_operand" "=a")
10078 (zero_extend:DI
10079 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10080 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10081 (set (match_operand:SI 1 "register_operand" "=&d")
10082 (umod:SI (match_dup 2) (match_dup 3)))
10083 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10084 (clobber (reg:CC FLAGS_REG))]
10085 "TARGET_64BIT"
10086 "#"
10087 "&& reload_completed"
10088 [(set (match_dup 1) (const_int 0))
10089 (parallel [(set (match_dup 0)
10090 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10091 (set (match_dup 1)
10092 (umod:SI (match_dup 2) (match_dup 3)))
10093 (use (match_dup 1))
10094 (clobber (reg:CC FLAGS_REG))])]
10095 ""
10096 [(set_attr "type" "multi")
10097 (set_attr "mode" "SI")])
10098
10099 (define_insn_and_split "divmodsi4_zext_2"
10100 [(set (match_operand:DI 1 "register_operand" "=&d")
10101 (zero_extend:DI
10102 (mod:SI (match_operand:SI 2 "register_operand" "0")
10103 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10104 (set (match_operand:SI 0 "register_operand" "=a")
10105 (div:SI (match_dup 2) (match_dup 3)))
10106 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10107 (clobber (reg:CC FLAGS_REG))]
10108 "TARGET_64BIT"
10109 "#"
10110 "&& reload_completed"
10111 [(parallel [(set (match_dup 6)
10112 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10113 (clobber (reg:CC FLAGS_REG))])
10114 (parallel [(set (match_dup 1)
10115 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10116 (set (match_dup 0)
10117 (div:SI (match_dup 2) (match_dup 3)))
10118 (use (match_dup 6))
10119 (clobber (reg:CC FLAGS_REG))])]
10120 {
10121 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10122 operands[6] = gen_lowpart (SImode, operands[1]);
10123
10124 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10125 operands[4] = operands[2];
10126 else
10127 {
10128 /* Avoid use of cltd in favor of a mov+shift. */
10129 emit_move_insn (operands[6], operands[2]);
10130 operands[4] = operands[6];
10131 }
10132 }
10133 [(set_attr "type" "multi")
10134 (set_attr "mode" "SI")])
10135
10136 (define_insn_and_split "udivmodsi4_zext_2"
10137 [(set (match_operand:DI 1 "register_operand" "=&d")
10138 (zero_extend:DI
10139 (umod:SI (match_operand:SI 2 "register_operand" "0")
10140 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10141 (set (match_operand:SI 0 "register_operand" "=a")
10142 (udiv:SI (match_dup 2) (match_dup 3)))
10143 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10144 (clobber (reg:CC FLAGS_REG))]
10145 "TARGET_64BIT"
10146 "#"
10147 "&& reload_completed"
10148 [(set (match_dup 4) (const_int 0))
10149 (parallel [(set (match_dup 1)
10150 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10151 (set (match_dup 0)
10152 (udiv:SI (match_dup 2) (match_dup 3)))
10153 (use (match_dup 4))
10154 (clobber (reg:CC FLAGS_REG))])]
10155 "operands[4] = gen_lowpart (SImode, operands[1]);"
10156 [(set_attr "type" "multi")
10157 (set_attr "mode" "SI")])
10158
10159 (define_insn_and_split "*divmod<mode>4"
10160 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10161 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10162 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10163 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10164 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10165 (clobber (reg:CC FLAGS_REG))]
10166 ""
10167 "#"
10168 "reload_completed"
10169 [(parallel [(set (match_dup 1)
10170 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10171 (clobber (reg:CC FLAGS_REG))])
10172 (parallel [(set (match_dup 0)
10173 (div:SWIM248 (match_dup 2) (match_dup 3)))
10174 (set (match_dup 1)
10175 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10176 (use (match_dup 1))
10177 (clobber (reg:CC FLAGS_REG))])]
10178 {
10179 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10180
10181 if (<MODE>mode != HImode
10182 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10183 operands[4] = operands[2];
10184 else
10185 {
10186 /* Avoid use of cltd in favor of a mov+shift. */
10187 emit_move_insn (operands[1], operands[2]);
10188 operands[4] = operands[1];
10189 }
10190 }
10191 [(set_attr "type" "multi")
10192 (set_attr "mode" "<MODE>")])
10193
10194 (define_insn_and_split "*udivmod<mode>4"
10195 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10196 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10197 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10198 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10199 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10200 (clobber (reg:CC FLAGS_REG))]
10201 ""
10202 "#"
10203 "reload_completed"
10204 [(set (match_dup 1) (const_int 0))
10205 (parallel [(set (match_dup 0)
10206 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10207 (set (match_dup 1)
10208 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10209 (use (match_dup 1))
10210 (clobber (reg:CC FLAGS_REG))])]
10211 ""
10212 [(set_attr "type" "multi")
10213 (set_attr "mode" "<MODE>")])
10214
10215 ;; Optimize division or modulo by constant power of 2, if the constant
10216 ;; materializes only after expansion.
10217 (define_insn_and_split "*udivmod<mode>4_pow2"
10218 [(set (match_operand:SWI48 0 "register_operand" "=r")
10219 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10220 (match_operand:SWI48 3 "const_int_operand")))
10221 (set (match_operand:SWI48 1 "register_operand" "=r")
10222 (umod:SWI48 (match_dup 2) (match_dup 3)))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10225 "#"
10226 "&& reload_completed"
10227 [(set (match_dup 1) (match_dup 2))
10228 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10229 (clobber (reg:CC FLAGS_REG))])
10230 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10231 (clobber (reg:CC FLAGS_REG))])]
10232 {
10233 int v = exact_log2 (UINTVAL (operands[3]));
10234 operands[4] = GEN_INT (v);
10235 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10236 }
10237 [(set_attr "type" "multi")
10238 (set_attr "mode" "<MODE>")])
10239
10240 (define_insn_and_split "*divmodsi4_zext_1"
10241 [(set (match_operand:DI 0 "register_operand" "=a")
10242 (zero_extend:DI
10243 (div:SI (match_operand:SI 2 "register_operand" "0")
10244 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10245 (set (match_operand:SI 1 "register_operand" "=&d")
10246 (mod:SI (match_dup 2) (match_dup 3)))
10247 (clobber (reg:CC FLAGS_REG))]
10248 "TARGET_64BIT"
10249 "#"
10250 "&& reload_completed"
10251 [(parallel [(set (match_dup 1)
10252 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10253 (clobber (reg:CC FLAGS_REG))])
10254 (parallel [(set (match_dup 0)
10255 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10256 (set (match_dup 1)
10257 (mod:SI (match_dup 2) (match_dup 3)))
10258 (use (match_dup 1))
10259 (clobber (reg:CC FLAGS_REG))])]
10260 {
10261 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10262
10263 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10264 operands[4] = operands[2];
10265 else
10266 {
10267 /* Avoid use of cltd in favor of a mov+shift. */
10268 emit_move_insn (operands[1], operands[2]);
10269 operands[4] = operands[1];
10270 }
10271 }
10272 [(set_attr "type" "multi")
10273 (set_attr "mode" "SI")])
10274
10275 (define_insn_and_split "*udivmodsi4_zext_1"
10276 [(set (match_operand:DI 0 "register_operand" "=a")
10277 (zero_extend:DI
10278 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10279 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10280 (set (match_operand:SI 1 "register_operand" "=&d")
10281 (umod:SI (match_dup 2) (match_dup 3)))
10282 (clobber (reg:CC FLAGS_REG))]
10283 "TARGET_64BIT"
10284 "#"
10285 "&& reload_completed"
10286 [(set (match_dup 1) (const_int 0))
10287 (parallel [(set (match_dup 0)
10288 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10289 (set (match_dup 1)
10290 (umod:SI (match_dup 2) (match_dup 3)))
10291 (use (match_dup 1))
10292 (clobber (reg:CC FLAGS_REG))])]
10293 ""
10294 [(set_attr "type" "multi")
10295 (set_attr "mode" "SI")])
10296
10297 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10298 [(set (match_operand:DI 0 "register_operand" "=r")
10299 (zero_extend:DI
10300 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10301 (match_operand:SI 3 "const_int_operand"))))
10302 (set (match_operand:SI 1 "register_operand" "=r")
10303 (umod:SI (match_dup 2) (match_dup 3)))
10304 (clobber (reg:CC FLAGS_REG))]
10305 "TARGET_64BIT
10306 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10307 "#"
10308 "&& reload_completed"
10309 [(set (match_dup 1) (match_dup 2))
10310 (parallel [(set (match_dup 0)
10311 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10312 (clobber (reg:CC FLAGS_REG))])
10313 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10314 (clobber (reg:CC FLAGS_REG))])]
10315 {
10316 int v = exact_log2 (UINTVAL (operands[3]));
10317 operands[4] = GEN_INT (v);
10318 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10319 }
10320 [(set_attr "type" "multi")
10321 (set_attr "mode" "SI")])
10322
10323 (define_insn_and_split "*divmodsi4_zext_2"
10324 [(set (match_operand:DI 1 "register_operand" "=&d")
10325 (zero_extend:DI
10326 (mod:SI (match_operand:SI 2 "register_operand" "0")
10327 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10328 (set (match_operand:SI 0 "register_operand" "=a")
10329 (div:SI (match_dup 2) (match_dup 3)))
10330 (clobber (reg:CC FLAGS_REG))]
10331 "TARGET_64BIT"
10332 "#"
10333 "&& reload_completed"
10334 [(parallel [(set (match_dup 6)
10335 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10336 (clobber (reg:CC FLAGS_REG))])
10337 (parallel [(set (match_dup 1)
10338 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10339 (set (match_dup 0)
10340 (div:SI (match_dup 2) (match_dup 3)))
10341 (use (match_dup 6))
10342 (clobber (reg:CC FLAGS_REG))])]
10343 {
10344 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10345 operands[6] = gen_lowpart (SImode, operands[1]);
10346
10347 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10348 operands[4] = operands[2];
10349 else
10350 {
10351 /* Avoid use of cltd in favor of a mov+shift. */
10352 emit_move_insn (operands[6], operands[2]);
10353 operands[4] = operands[6];
10354 }
10355 }
10356 [(set_attr "type" "multi")
10357 (set_attr "mode" "SI")])
10358
10359 (define_insn_and_split "*udivmodsi4_zext_2"
10360 [(set (match_operand:DI 1 "register_operand" "=&d")
10361 (zero_extend:DI
10362 (umod:SI (match_operand:SI 2 "register_operand" "0")
10363 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10364 (set (match_operand:SI 0 "register_operand" "=a")
10365 (udiv:SI (match_dup 2) (match_dup 3)))
10366 (clobber (reg:CC FLAGS_REG))]
10367 "TARGET_64BIT"
10368 "#"
10369 "&& reload_completed"
10370 [(set (match_dup 4) (const_int 0))
10371 (parallel [(set (match_dup 1)
10372 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10373 (set (match_dup 0)
10374 (udiv:SI (match_dup 2) (match_dup 3)))
10375 (use (match_dup 4))
10376 (clobber (reg:CC FLAGS_REG))])]
10377 "operands[4] = gen_lowpart (SImode, operands[1]);"
10378 [(set_attr "type" "multi")
10379 (set_attr "mode" "SI")])
10380
10381 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10382 [(set (match_operand:DI 1 "register_operand" "=r")
10383 (zero_extend:DI
10384 (umod:SI (match_operand:SI 2 "register_operand" "0")
10385 (match_operand:SI 3 "const_int_operand"))))
10386 (set (match_operand:SI 0 "register_operand" "=r")
10387 (udiv:SI (match_dup 2) (match_dup 3)))
10388 (clobber (reg:CC FLAGS_REG))]
10389 "TARGET_64BIT
10390 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10391 "#"
10392 "&& reload_completed"
10393 [(set (match_dup 1) (match_dup 2))
10394 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10395 (clobber (reg:CC FLAGS_REG))])
10396 (parallel [(set (match_dup 1)
10397 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10398 (clobber (reg:CC FLAGS_REG))])]
10399 {
10400 int v = exact_log2 (UINTVAL (operands[3]));
10401 operands[4] = GEN_INT (v);
10402 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10403 }
10404 [(set_attr "type" "multi")
10405 (set_attr "mode" "SI")])
10406
10407 (define_insn "*<u>divmod<mode>4_noext"
10408 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10409 (any_div:SWIM248
10410 (match_operand:SWIM248 2 "register_operand" "0")
10411 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10412 (set (match_operand:SWIM248 1 "register_operand" "=d")
10413 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10414 (use (match_operand:SWIM248 4 "register_operand" "1"))
10415 (clobber (reg:CC FLAGS_REG))]
10416 ""
10417 "<sgnprefix>div{<imodesuffix>}\t%3"
10418 [(set_attr "type" "idiv")
10419 (set_attr "mode" "<MODE>")])
10420
10421 (define_insn "*<u>divmodsi4_noext_zext_1"
10422 [(set (match_operand:DI 0 "register_operand" "=a")
10423 (zero_extend:DI
10424 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10425 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10426 (set (match_operand:SI 1 "register_operand" "=d")
10427 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10428 (use (match_operand:SI 4 "register_operand" "1"))
10429 (clobber (reg:CC FLAGS_REG))]
10430 "TARGET_64BIT"
10431 "<sgnprefix>div{l}\t%3"
10432 [(set_attr "type" "idiv")
10433 (set_attr "mode" "SI")])
10434
10435 (define_insn "*<u>divmodsi4_noext_zext_2"
10436 [(set (match_operand:DI 1 "register_operand" "=d")
10437 (zero_extend:DI
10438 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10439 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10440 (set (match_operand:SI 0 "register_operand" "=a")
10441 (any_div:SI (match_dup 2) (match_dup 3)))
10442 (use (match_operand:SI 4 "register_operand" "1"))
10443 (clobber (reg:CC FLAGS_REG))]
10444 "TARGET_64BIT"
10445 "<sgnprefix>div{l}\t%3"
10446 [(set_attr "type" "idiv")
10447 (set_attr "mode" "SI")])
10448
10449 ;; Avoid sign-extension (using cdq) for constant numerators.
10450 (define_insn_and_split "*divmodsi4_const"
10451 [(set (match_operand:SI 0 "register_operand" "=&a")
10452 (div:SI (match_operand:SI 2 "const_int_operand")
10453 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10454 (set (match_operand:SI 1 "register_operand" "=&d")
10455 (mod:SI (match_dup 2) (match_dup 3)))
10456 (clobber (reg:CC FLAGS_REG))]
10457 "!optimize_function_for_size_p (cfun)"
10458 "#"
10459 "&& reload_completed"
10460 [(set (match_dup 0) (match_dup 2))
10461 (set (match_dup 1) (match_dup 4))
10462 (parallel [(set (match_dup 0)
10463 (div:SI (match_dup 0) (match_dup 3)))
10464 (set (match_dup 1)
10465 (mod:SI (match_dup 0) (match_dup 3)))
10466 (use (match_dup 1))
10467 (clobber (reg:CC FLAGS_REG))])]
10468 {
10469 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10470 }
10471 [(set_attr "type" "multi")
10472 (set_attr "mode" "SI")])
10473
10474 (define_expand "divmodqi4"
10475 [(parallel [(set (match_operand:QI 0 "register_operand")
10476 (div:QI
10477 (match_operand:QI 1 "register_operand")
10478 (match_operand:QI 2 "nonimmediate_operand")))
10479 (set (match_operand:QI 3 "register_operand")
10480 (mod:QI (match_dup 1) (match_dup 2)))
10481 (clobber (reg:CC FLAGS_REG))])]
10482 "TARGET_QIMODE_MATH"
10483 {
10484 rtx div, mod;
10485 rtx tmp0, tmp1;
10486
10487 tmp0 = gen_reg_rtx (HImode);
10488 tmp1 = gen_reg_rtx (HImode);
10489
10490 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10491 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10492 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10493
10494 /* Extract remainder from AH. */
10495 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10496 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10497 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10498
10499 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10500 set_unique_reg_note (insn, REG_EQUAL, mod);
10501
10502 /* Extract quotient from AL. */
10503 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10504
10505 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10506 set_unique_reg_note (insn, REG_EQUAL, div);
10507
10508 DONE;
10509 })
10510
10511 (define_expand "udivmodqi4"
10512 [(parallel [(set (match_operand:QI 0 "register_operand")
10513 (udiv:QI
10514 (match_operand:QI 1 "register_operand")
10515 (match_operand:QI 2 "nonimmediate_operand")))
10516 (set (match_operand:QI 3 "register_operand")
10517 (umod:QI (match_dup 1) (match_dup 2)))
10518 (clobber (reg:CC FLAGS_REG))])]
10519 "TARGET_QIMODE_MATH"
10520 {
10521 rtx div, mod;
10522 rtx tmp0, tmp1;
10523
10524 tmp0 = gen_reg_rtx (HImode);
10525 tmp1 = gen_reg_rtx (HImode);
10526
10527 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10528 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10529 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10530
10531 /* Extract remainder from AH. */
10532 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10533 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10534 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10535
10536 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10537 set_unique_reg_note (insn, REG_EQUAL, mod);
10538
10539 /* Extract quotient from AL. */
10540 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10541
10542 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10543 set_unique_reg_note (insn, REG_EQUAL, div);
10544
10545 DONE;
10546 })
10547
10548 ;; Divide AX by r/m8, with result stored in
10549 ;; AL <- Quotient
10550 ;; AH <- Remainder
10551 ;; Change div/mod to HImode and extend the second argument to HImode
10552 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10553 ;; combine may fail.
10554 (define_insn "<u>divmodhiqi3"
10555 [(set (match_operand:HI 0 "register_operand" "=a")
10556 (ior:HI
10557 (ashift:HI
10558 (zero_extend:HI
10559 (truncate:QI
10560 (mod:HI (match_operand:HI 1 "register_operand" "0")
10561 (any_extend:HI
10562 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10563 (const_int 8))
10564 (zero_extend:HI
10565 (truncate:QI
10566 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10567 (clobber (reg:CC FLAGS_REG))]
10568 "TARGET_QIMODE_MATH"
10569 "<sgnprefix>div{b}\t%2"
10570 [(set_attr "type" "idiv")
10571 (set_attr "mode" "QI")])
10572
10573 ;; We cannot use div/idiv for double division, because it causes
10574 ;; "division by zero" on the overflow and that's not what we expect
10575 ;; from truncate. Because true (non truncating) double division is
10576 ;; never generated, we can't create this insn anyway.
10577 ;
10578 ;(define_insn ""
10579 ; [(set (match_operand:SI 0 "register_operand" "=a")
10580 ; (truncate:SI
10581 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10582 ; (zero_extend:DI
10583 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10584 ; (set (match_operand:SI 3 "register_operand" "=d")
10585 ; (truncate:SI
10586 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10587 ; (clobber (reg:CC FLAGS_REG))]
10588 ; ""
10589 ; "div{l}\t{%2, %0|%0, %2}"
10590 ; [(set_attr "type" "idiv")])
10591 \f
10592 ;;- Logical AND instructions
10593
10594 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10595 ;; Note that this excludes ah.
10596
10597 (define_expand "@test<mode>_ccno_1"
10598 [(set (reg:CCNO FLAGS_REG)
10599 (compare:CCNO
10600 (and:SWI48
10601 (match_operand:SWI48 0 "nonimmediate_operand")
10602 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10603 (const_int 0)))])
10604
10605 (define_expand "testqi_ccz_1"
10606 [(set (reg:CCZ FLAGS_REG)
10607 (compare:CCZ
10608 (and:QI
10609 (match_operand:QI 0 "nonimmediate_operand")
10610 (match_operand:QI 1 "nonmemory_operand"))
10611 (const_int 0)))])
10612
10613 (define_insn "*testdi_1"
10614 [(set (reg FLAGS_REG)
10615 (compare
10616 (and:DI
10617 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10618 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10619 (const_int 0)))]
10620 "TARGET_64BIT
10621 && ix86_match_ccmode
10622 (insn,
10623 /* If we are going to emit testl instead of testq, and the operands[1]
10624 constant might have the SImode sign bit set, make sure the sign
10625 flag isn't tested, because the instruction will set the sign flag
10626 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10627 conservatively assume it might have bit 31 set. */
10628 (satisfies_constraint_Z (operands[1])
10629 && (!CONST_INT_P (operands[1])
10630 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10631 ? CCZmode : CCNOmode)"
10632 "@
10633 test{l}\t{%k1, %k0|%k0, %k1}
10634 test{q}\t{%1, %0|%0, %1}"
10635 [(set_attr "type" "test")
10636 (set_attr "mode" "SI,DI")])
10637
10638 (define_insn "*testqi_1_maybe_si"
10639 [(set (reg FLAGS_REG)
10640 (compare
10641 (and:QI
10642 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10643 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10644 (const_int 0)))]
10645 "ix86_match_ccmode (insn,
10646 CONST_INT_P (operands[1])
10647 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10648 {
10649 if (get_attr_mode (insn) == MODE_SI)
10650 {
10651 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10652 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10653 return "test{l}\t{%1, %k0|%k0, %1}";
10654 }
10655 return "test{b}\t{%1, %0|%0, %1}";
10656 }
10657 [(set_attr "type" "test")
10658 (set (attr "mode")
10659 (cond [(eq_attr "alternative" "2")
10660 (const_string "SI")
10661 (and (match_test "optimize_insn_for_size_p ()")
10662 (and (match_operand 0 "ext_QIreg_operand")
10663 (match_operand 1 "const_0_to_127_operand")))
10664 (const_string "SI")
10665 ]
10666 (const_string "QI")))
10667 (set_attr "pent_pair" "uv,np,np")])
10668
10669 (define_insn "*test<mode>_1"
10670 [(set (reg FLAGS_REG)
10671 (compare
10672 (and:SWI124
10673 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10674 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10675 (const_int 0)))]
10676 "ix86_match_ccmode (insn, CCNOmode)"
10677 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10678 [(set_attr "type" "test")
10679 (set_attr "mode" "<MODE>")
10680 (set_attr "pent_pair" "uv,uv,np")])
10681
10682 (define_expand "testqi_ext_1_ccno"
10683 [(set (reg:CCNO FLAGS_REG)
10684 (compare:CCNO
10685 (and:QI
10686 (subreg:QI
10687 (zero_extract:HI
10688 (match_operand:HI 0 "register_operand")
10689 (const_int 8)
10690 (const_int 8)) 0)
10691 (match_operand:QI 1 "const_int_operand"))
10692 (const_int 0)))])
10693
10694 (define_insn "*testqi_ext<mode>_1"
10695 [(set (reg FLAGS_REG)
10696 (compare
10697 (and:QI
10698 (subreg:QI
10699 (match_operator:SWI248 2 "extract_operator"
10700 [(match_operand 0 "int248_register_operand" "Q,Q")
10701 (const_int 8)
10702 (const_int 8)]) 0)
10703 (match_operand:QI 1 "general_x64constmem_operand" "QnBc,m"))
10704 (const_int 0)))]
10705 "ix86_match_ccmode (insn, CCNOmode)"
10706 "test{b}\t{%1, %h0|%h0, %1}"
10707 [(set_attr "isa" "*,nox64")
10708 (set_attr "type" "test")
10709 (set_attr "mode" "QI")])
10710
10711 (define_insn "*testqi_ext<mode>_2"
10712 [(set (reg FLAGS_REG)
10713 (compare
10714 (and:QI
10715 (subreg:QI
10716 (match_operator:SWI248 2 "extract_operator"
10717 [(match_operand 0 "int248_register_operand" "Q")
10718 (const_int 8)
10719 (const_int 8)]) 0)
10720 (subreg:QI
10721 (match_operator:SWI248 3 "extract_operator"
10722 [(match_operand 1 "int248_register_operand" "Q")
10723 (const_int 8)
10724 (const_int 8)]) 0))
10725 (const_int 0)))]
10726 "ix86_match_ccmode (insn, CCNOmode)"
10727 "test{b}\t{%h1, %h0|%h0, %h1}"
10728 [(set_attr "type" "test")
10729 (set_attr "mode" "QI")])
10730
10731 ;; Provide a *testti instruction that STV can implement using ptest.
10732 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10733 (define_insn_and_split "*testti_doubleword"
10734 [(set (reg:CCZ FLAGS_REG)
10735 (compare:CCZ
10736 (and:TI (match_operand:TI 0 "register_operand")
10737 (match_operand:TI 1 "general_operand"))
10738 (const_int 0)))]
10739 "TARGET_64BIT
10740 && ix86_pre_reload_split ()"
10741 "#"
10742 "&& 1"
10743 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10744 (clobber (reg:CC FLAGS_REG))])
10745 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10746 {
10747 operands[2] = gen_reg_rtx (TImode);
10748 if (!x86_64_hilo_general_operand (operands[1], TImode))
10749 operands[1] = force_reg (TImode, operands[1]);
10750 })
10751
10752 ;; Combine likes to form bit extractions for some tests. Humor it.
10753 (define_insn_and_split "*testqi_ext_3"
10754 [(set (match_operand 0 "flags_reg_operand")
10755 (match_operator 1 "compare_operator"
10756 [(zero_extract:SWI248
10757 (match_operand 2 "int_nonimmediate_operand" "rm")
10758 (match_operand 3 "const_int_operand")
10759 (match_operand 4 "const_int_operand"))
10760 (const_int 0)]))]
10761 "/* Ensure that resulting mask is zero or sign extended operand. */
10762 INTVAL (operands[4]) >= 0
10763 && ((INTVAL (operands[3]) > 0
10764 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
10765 || (<MODE>mode == DImode
10766 && INTVAL (operands[3]) > 32
10767 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
10768 && ix86_match_ccmode (insn,
10769 /* If zero_extract mode precision is the same
10770 as len, the SF of the zero_extract
10771 comparison will be the most significant
10772 extracted bit, but this could be matched
10773 after splitting only for pos 0 len all bits
10774 trivial extractions. Require CCZmode. */
10775 (GET_MODE_PRECISION (<MODE>mode)
10776 == INTVAL (operands[3]))
10777 /* Otherwise, require CCZmode if we'd use a mask
10778 with the most significant bit set and can't
10779 widen it to wider mode. *testdi_1 also
10780 requires CCZmode if the mask has bit
10781 31 set and all bits above it clear. */
10782 || (INTVAL (operands[3]) + INTVAL (operands[4])
10783 >= 32)
10784 /* We can't widen also if val is not a REG. */
10785 || (INTVAL (operands[3]) + INTVAL (operands[4])
10786 == GET_MODE_PRECISION (GET_MODE (operands[2]))
10787 && !register_operand (operands[2],
10788 GET_MODE (operands[2])))
10789 /* And we shouldn't widen if
10790 TARGET_PARTIAL_REG_STALL. */
10791 || (TARGET_PARTIAL_REG_STALL
10792 && (INTVAL (operands[3]) + INTVAL (operands[4])
10793 >= (paradoxical_subreg_p (operands[2])
10794 && (GET_MODE_CLASS
10795 (GET_MODE (SUBREG_REG (operands[2])))
10796 == MODE_INT)
10797 ? GET_MODE_PRECISION
10798 (GET_MODE (SUBREG_REG (operands[2])))
10799 : GET_MODE_PRECISION
10800 (GET_MODE (operands[2])))))
10801 ? CCZmode : CCNOmode)"
10802 "#"
10803 "&& 1"
10804 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10805 {
10806 rtx val = operands[2];
10807 HOST_WIDE_INT len = INTVAL (operands[3]);
10808 HOST_WIDE_INT pos = INTVAL (operands[4]);
10809 machine_mode mode = GET_MODE (val);
10810
10811 if (SUBREG_P (val))
10812 {
10813 machine_mode submode = GET_MODE (SUBREG_REG (val));
10814
10815 /* Narrow paradoxical subregs to prevent partial register stalls. */
10816 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
10817 && GET_MODE_CLASS (submode) == MODE_INT
10818 && (GET_MODE (operands[0]) == CCZmode
10819 || pos + len < GET_MODE_PRECISION (submode)
10820 || REG_P (SUBREG_REG (val))))
10821 {
10822 val = SUBREG_REG (val);
10823 mode = submode;
10824 }
10825 }
10826
10827 /* Small HImode tests can be converted to QImode. */
10828 if (pos + len <= 8
10829 && register_operand (val, HImode))
10830 {
10831 rtx nval = gen_lowpart (QImode, val);
10832 if (!MEM_P (nval)
10833 || GET_MODE (operands[0]) == CCZmode
10834 || pos + len < 8)
10835 {
10836 val = nval;
10837 mode = QImode;
10838 }
10839 }
10840
10841 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
10842
10843 /* If the mask is going to have the sign bit set in the mode
10844 we want to do the comparison in and user isn't interested just
10845 in the zero flag, then we must widen the target mode. */
10846 if (pos + len == GET_MODE_PRECISION (mode)
10847 && GET_MODE (operands[0]) != CCZmode)
10848 {
10849 gcc_assert (pos + len < 32 && !MEM_P (val));
10850 mode = SImode;
10851 val = gen_lowpart (mode, val);
10852 }
10853
10854 wide_int mask
10855 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
10856
10857 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
10858 })
10859
10860 ;; Split and;cmp (as optimized by combine) into not;test
10861 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
10862 (define_insn_and_split "*test<mode>_not"
10863 [(set (reg:CCZ FLAGS_REG)
10864 (compare:CCZ
10865 (and:SWI
10866 (not:SWI (match_operand:SWI 0 "register_operand"))
10867 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
10868 (const_int 0)))]
10869 "ix86_pre_reload_split ()
10870 && (!TARGET_BMI || !REG_P (operands[1]))"
10871 "#"
10872 "&& 1"
10873 [(set (match_dup 2) (not:SWI (match_dup 0)))
10874 (set (reg:CCZ FLAGS_REG)
10875 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
10876 (const_int 0)))]
10877 "operands[2] = gen_reg_rtx (<MODE>mode);")
10878
10879 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
10880 (define_insn_and_split "*test<mode>_not_doubleword"
10881 [(set (reg:CCZ FLAGS_REG)
10882 (compare:CCZ
10883 (and:DWI
10884 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
10885 (match_operand:DWI 1 "nonimmediate_operand"))
10886 (const_int 0)))]
10887 "ix86_pre_reload_split ()"
10888 "#"
10889 "&& 1"
10890 [(parallel
10891 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
10892 (clobber (reg:CC FLAGS_REG))])
10893 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10894 {
10895 operands[0] = force_reg (<MODE>mode, operands[0]);
10896 operands[2] = gen_reg_rtx (<MODE>mode);
10897 })
10898
10899 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
10900 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
10901 ;; this is relatively important trick.
10902 ;; Do the conversion only post-reload to avoid limiting of the register class
10903 ;; to QI regs.
10904 (define_split
10905 [(set (match_operand 0 "flags_reg_operand")
10906 (match_operator 1 "compare_operator"
10907 [(and (match_operand 2 "QIreg_operand")
10908 (match_operand 3 "const_int_operand"))
10909 (const_int 0)]))]
10910 "reload_completed
10911 && GET_MODE (operands[2]) != QImode
10912 && ((ix86_match_ccmode (insn, CCZmode)
10913 && !(INTVAL (operands[3]) & ~(255 << 8)))
10914 || (ix86_match_ccmode (insn, CCNOmode)
10915 && !(INTVAL (operands[3]) & ~(127 << 8))))"
10916 [(set (match_dup 0)
10917 (match_op_dup 1
10918 [(and:QI
10919 (subreg:QI
10920 (zero_extract:HI (match_dup 2)
10921 (const_int 8)
10922 (const_int 8)) 0)
10923 (match_dup 3))
10924 (const_int 0)]))]
10925 {
10926 operands[2] = gen_lowpart (HImode, operands[2]);
10927 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
10928 })
10929
10930 (define_split
10931 [(set (match_operand 0 "flags_reg_operand")
10932 (match_operator 1 "compare_operator"
10933 [(and (match_operand 2 "nonimmediate_operand")
10934 (match_operand 3 "const_int_operand"))
10935 (const_int 0)]))]
10936 "reload_completed
10937 && GET_MODE (operands[2]) != QImode
10938 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
10939 && ((ix86_match_ccmode (insn, CCZmode)
10940 && !(INTVAL (operands[3]) & ~255))
10941 || (ix86_match_ccmode (insn, CCNOmode)
10942 && !(INTVAL (operands[3]) & ~127)))"
10943 [(set (match_dup 0)
10944 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
10945 (const_int 0)]))]
10946 {
10947 operands[2] = gen_lowpart (QImode, operands[2]);
10948 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
10949 })
10950
10951 ;; %%% This used to optimize known byte-wide and operations to memory,
10952 ;; and sometimes to QImode registers. If this is considered useful,
10953 ;; it should be done with splitters.
10954
10955 (define_expand "and<mode>3"
10956 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
10957 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
10958 (match_operand:SDWIM 2 "<general_szext_operand>")))]
10959 ""
10960 {
10961 machine_mode mode = <MODE>mode;
10962
10963 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
10964 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
10965 operands[2] = force_reg (<MODE>mode, operands[2]);
10966
10967 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
10968 && const_int_operand (operands[2], <MODE>mode)
10969 && register_operand (operands[0], <MODE>mode)
10970 && !(TARGET_ZERO_EXTEND_WITH_AND
10971 && optimize_function_for_speed_p (cfun)))
10972 {
10973 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
10974
10975 if (ival == GET_MODE_MASK (SImode))
10976 mode = SImode;
10977 else if (ival == GET_MODE_MASK (HImode))
10978 mode = HImode;
10979 else if (ival == GET_MODE_MASK (QImode))
10980 mode = QImode;
10981 }
10982
10983 if (mode != <MODE>mode)
10984 emit_insn (gen_extend_insn
10985 (operands[0], gen_lowpart (mode, operands[1]),
10986 <MODE>mode, mode, 1));
10987 else
10988 ix86_expand_binary_operator (AND, <MODE>mode, operands);
10989
10990 DONE;
10991 })
10992
10993 (define_insn_and_split "*and<dwi>3_doubleword"
10994 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
10995 (and:<DWI>
10996 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
10997 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
10998 (clobber (reg:CC FLAGS_REG))]
10999 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
11000 "#"
11001 "&& reload_completed"
11002 [(const_int:DWIH 0)]
11003 {
11004 bool emit_insn_deleted_note_p = false;
11005
11006 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11007
11008 if (operands[2] == const0_rtx)
11009 emit_move_insn (operands[0], const0_rtx);
11010 else if (operands[2] == constm1_rtx)
11011 emit_insn_deleted_note_p = true;
11012 else
11013 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
11014
11015 if (operands[5] == const0_rtx)
11016 emit_move_insn (operands[3], const0_rtx);
11017 else if (operands[5] == constm1_rtx)
11018 {
11019 if (emit_insn_deleted_note_p)
11020 emit_note (NOTE_INSN_DELETED);
11021 }
11022 else
11023 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
11024
11025 DONE;
11026 })
11027
11028 (define_insn "*anddi_1"
11029 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
11030 (and:DI
11031 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
11032 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
11033 (clobber (reg:CC FLAGS_REG))]
11034 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
11035 "@
11036 and{l}\t{%k2, %k0|%k0, %k2}
11037 and{q}\t{%2, %0|%0, %2}
11038 and{q}\t{%2, %0|%0, %2}
11039 #
11040 #"
11041 [(set_attr "isa" "x64,x64,x64,x64,avx512bw")
11042 (set_attr "type" "alu,alu,alu,imovx,msklog")
11043 (set_attr "length_immediate" "*,*,*,0,*")
11044 (set (attr "prefix_rex")
11045 (if_then_else
11046 (and (eq_attr "type" "imovx")
11047 (and (match_test "INTVAL (operands[2]) == 0xff")
11048 (match_operand 1 "ext_QIreg_operand")))
11049 (const_string "1")
11050 (const_string "*")))
11051 (set_attr "mode" "SI,DI,DI,SI,DI")])
11052
11053 (define_insn_and_split "*anddi_1_btr"
11054 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11055 (and:DI
11056 (match_operand:DI 1 "nonimmediate_operand" "%0")
11057 (match_operand:DI 2 "const_int_operand" "n")))
11058 (clobber (reg:CC FLAGS_REG))]
11059 "TARGET_64BIT && TARGET_USE_BT
11060 && ix86_binary_operator_ok (AND, DImode, operands)
11061 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
11062 "#"
11063 "&& reload_completed"
11064 [(parallel [(set (zero_extract:DI (match_dup 0)
11065 (const_int 1)
11066 (match_dup 3))
11067 (const_int 0))
11068 (clobber (reg:CC FLAGS_REG))])]
11069 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
11070 [(set_attr "type" "alu1")
11071 (set_attr "prefix_0f" "1")
11072 (set_attr "znver1_decode" "double")
11073 (set_attr "mode" "DI")])
11074
11075 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11076 (define_split
11077 [(set (match_operand:DI 0 "register_operand")
11078 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11079 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11080 (clobber (reg:CC FLAGS_REG))]
11081 "TARGET_64BIT"
11082 [(parallel [(set (match_dup 0)
11083 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11084 (clobber (reg:CC FLAGS_REG))])]
11085 {
11086 if (GET_CODE (operands[2]) == SYMBOL_REF
11087 || GET_CODE (operands[2]) == LABEL_REF)
11088 {
11089 operands[2] = shallow_copy_rtx (operands[2]);
11090 PUT_MODE (operands[2], SImode);
11091 }
11092 else if (GET_CODE (operands[2]) == CONST)
11093 {
11094 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11095 operands[2] = copy_rtx (operands[2]);
11096 PUT_MODE (operands[2], SImode);
11097 PUT_MODE (XEXP (operands[2], 0), SImode);
11098 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11099 }
11100 else
11101 operands[2] = gen_lowpart (SImode, operands[2]);
11102 })
11103
11104 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11105 (define_insn "*andsi_1_zext"
11106 [(set (match_operand:DI 0 "register_operand" "=r")
11107 (zero_extend:DI
11108 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11109 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11110 (clobber (reg:CC FLAGS_REG))]
11111 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11112 "and{l}\t{%2, %k0|%k0, %2}"
11113 [(set_attr "type" "alu")
11114 (set_attr "mode" "SI")])
11115
11116 (define_insn "*and<mode>_1"
11117 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11118 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11119 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11120 (clobber (reg:CC FLAGS_REG))]
11121 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11122 "@
11123 and{<imodesuffix>}\t{%2, %0|%0, %2}
11124 and{<imodesuffix>}\t{%2, %0|%0, %2}
11125 #
11126 #"
11127 [(set (attr "isa")
11128 (cond [(eq_attr "alternative" "3")
11129 (if_then_else (eq_attr "mode" "SI")
11130 (const_string "avx512bw")
11131 (const_string "avx512f"))
11132 ]
11133 (const_string "*")))
11134 (set_attr "type" "alu,alu,imovx,msklog")
11135 (set_attr "length_immediate" "*,*,0,*")
11136 (set (attr "prefix_rex")
11137 (if_then_else
11138 (and (eq_attr "type" "imovx")
11139 (and (match_test "INTVAL (operands[2]) == 0xff")
11140 (match_operand 1 "ext_QIreg_operand")))
11141 (const_string "1")
11142 (const_string "*")))
11143 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11144
11145 (define_insn "*andqi_1"
11146 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11147 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11148 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11149 (clobber (reg:CC FLAGS_REG))]
11150 "ix86_binary_operator_ok (AND, QImode, operands)"
11151 "@
11152 and{b}\t{%2, %0|%0, %2}
11153 and{b}\t{%2, %0|%0, %2}
11154 and{l}\t{%k2, %k0|%k0, %k2}
11155 #"
11156 [(set_attr "type" "alu,alu,alu,msklog")
11157 (set (attr "mode")
11158 (cond [(eq_attr "alternative" "2")
11159 (const_string "SI")
11160 (and (eq_attr "alternative" "3")
11161 (match_test "!TARGET_AVX512DQ"))
11162 (const_string "HI")
11163 ]
11164 (const_string "QI")))
11165 ;; Potential partial reg stall on alternative 2.
11166 (set (attr "preferred_for_speed")
11167 (cond [(eq_attr "alternative" "2")
11168 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11169 (symbol_ref "true")))])
11170
11171 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11172 (define_insn_and_split "*and<mode>_1_slp"
11173 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11174 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11175 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11176 (clobber (reg:CC FLAGS_REG))]
11177 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11178 "@
11179 and{<imodesuffix>}\t{%2, %0|%0, %2}
11180 #"
11181 "&& reload_completed"
11182 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11183 (parallel
11184 [(set (strict_low_part (match_dup 0))
11185 (and:SWI12 (match_dup 0) (match_dup 2)))
11186 (clobber (reg:CC FLAGS_REG))])]
11187 ""
11188 [(set_attr "type" "alu")
11189 (set_attr "mode" "<MODE>")])
11190
11191 (define_split
11192 [(set (match_operand:SWI248 0 "register_operand")
11193 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11194 (match_operand:SWI248 2 "const_int_operand")))
11195 (clobber (reg:CC FLAGS_REG))]
11196 "reload_completed
11197 && (!REG_P (operands[1])
11198 || REGNO (operands[0]) != REGNO (operands[1]))"
11199 [(const_int 0)]
11200 {
11201 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11202 machine_mode mode;
11203
11204 if (ival == GET_MODE_MASK (SImode))
11205 mode = SImode;
11206 else if (ival == GET_MODE_MASK (HImode))
11207 mode = HImode;
11208 else if (ival == GET_MODE_MASK (QImode))
11209 mode = QImode;
11210 else
11211 gcc_unreachable ();
11212
11213 /* Zero extend to SImode to avoid partial register stalls. */
11214 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11215 operands[0] = gen_lowpart (SImode, operands[0]);
11216
11217 emit_insn (gen_extend_insn
11218 (operands[0], gen_lowpart (mode, operands[1]),
11219 GET_MODE (operands[0]), mode, 1));
11220 DONE;
11221 })
11222
11223 (define_split
11224 [(set (match_operand:SWI48 0 "register_operand")
11225 (and:SWI48 (match_dup 0)
11226 (const_int -65536)))
11227 (clobber (reg:CC FLAGS_REG))]
11228 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11229 || optimize_function_for_size_p (cfun)"
11230 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11231 "operands[1] = gen_lowpart (HImode, operands[0]);")
11232
11233 (define_split
11234 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11235 (and:SWI248 (match_dup 0)
11236 (const_int -256)))
11237 (clobber (reg:CC FLAGS_REG))]
11238 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11239 && reload_completed"
11240 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11241 "operands[1] = gen_lowpart (QImode, operands[0]);")
11242
11243 (define_split
11244 [(set (match_operand:SWI248 0 "QIreg_operand")
11245 (and:SWI248 (match_dup 0)
11246 (const_int -65281)))
11247 (clobber (reg:CC FLAGS_REG))]
11248 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11249 && reload_completed"
11250 [(parallel
11251 [(set (zero_extract:HI (match_dup 0)
11252 (const_int 8)
11253 (const_int 8))
11254 (subreg:HI
11255 (xor:QI
11256 (subreg:QI
11257 (zero_extract:HI (match_dup 0)
11258 (const_int 8)
11259 (const_int 8)) 0)
11260 (subreg:QI
11261 (zero_extract:HI (match_dup 0)
11262 (const_int 8)
11263 (const_int 8)) 0)) 0))
11264 (clobber (reg:CC FLAGS_REG))])]
11265 "operands[0] = gen_lowpart (HImode, operands[0]);")
11266
11267 (define_insn "*anddi_2"
11268 [(set (reg FLAGS_REG)
11269 (compare
11270 (and:DI
11271 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11272 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11273 (const_int 0)))
11274 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11275 (and:DI (match_dup 1) (match_dup 2)))]
11276 "TARGET_64BIT
11277 && ix86_match_ccmode
11278 (insn,
11279 /* If we are going to emit andl instead of andq, and the operands[2]
11280 constant might have the SImode sign bit set, make sure the sign
11281 flag isn't tested, because the instruction will set the sign flag
11282 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11283 conservatively assume it might have bit 31 set. */
11284 (satisfies_constraint_Z (operands[2])
11285 && (!CONST_INT_P (operands[2])
11286 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11287 ? CCZmode : CCNOmode)
11288 && ix86_binary_operator_ok (AND, DImode, operands)"
11289 "@
11290 and{l}\t{%k2, %k0|%k0, %k2}
11291 and{q}\t{%2, %0|%0, %2}
11292 and{q}\t{%2, %0|%0, %2}"
11293 [(set_attr "type" "alu")
11294 (set_attr "mode" "SI,DI,DI")])
11295
11296 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11297 (define_insn "*andsi_2_zext"
11298 [(set (reg FLAGS_REG)
11299 (compare (and:SI
11300 (match_operand:SI 1 "nonimmediate_operand" "%0")
11301 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11302 (const_int 0)))
11303 (set (match_operand:DI 0 "register_operand" "=r")
11304 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11305 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11306 && ix86_binary_operator_ok (AND, SImode, operands)"
11307 "and{l}\t{%2, %k0|%k0, %2}"
11308 [(set_attr "type" "alu")
11309 (set_attr "mode" "SI")])
11310
11311 (define_insn "*andqi_2_maybe_si"
11312 [(set (reg FLAGS_REG)
11313 (compare (and:QI
11314 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11315 (match_operand:QI 2 "general_operand" "qn,m,n"))
11316 (const_int 0)))
11317 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11318 (and:QI (match_dup 1) (match_dup 2)))]
11319 "ix86_binary_operator_ok (AND, QImode, operands)
11320 && ix86_match_ccmode (insn,
11321 CONST_INT_P (operands[2])
11322 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11323 {
11324 if (get_attr_mode (insn) == MODE_SI)
11325 {
11326 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11327 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11328 return "and{l}\t{%2, %k0|%k0, %2}";
11329 }
11330 return "and{b}\t{%2, %0|%0, %2}";
11331 }
11332 [(set_attr "type" "alu")
11333 (set (attr "mode")
11334 (cond [(eq_attr "alternative" "2")
11335 (const_string "SI")
11336 (and (match_test "optimize_insn_for_size_p ()")
11337 (and (match_operand 0 "ext_QIreg_operand")
11338 (match_operand 2 "const_0_to_127_operand")))
11339 (const_string "SI")
11340 ]
11341 (const_string "QI")))
11342 ;; Potential partial reg stall on alternative 2.
11343 (set (attr "preferred_for_speed")
11344 (cond [(eq_attr "alternative" "2")
11345 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11346 (symbol_ref "true")))])
11347
11348 (define_insn "*and<mode>_2"
11349 [(set (reg FLAGS_REG)
11350 (compare (and:SWI124
11351 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11352 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11353 (const_int 0)))
11354 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11355 (and:SWI124 (match_dup 1) (match_dup 2)))]
11356 "ix86_match_ccmode (insn, CCNOmode)
11357 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11358 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11359 [(set_attr "type" "alu")
11360 (set_attr "mode" "<MODE>")])
11361
11362 (define_insn "*andqi_ext<mode>_0"
11363 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
11364 (and:QI
11365 (subreg:QI
11366 (match_operator:SWI248 3 "extract_operator"
11367 [(match_operand 2 "int248_register_operand" "Q,Q")
11368 (const_int 8)
11369 (const_int 8)]) 0)
11370 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
11371 (clobber (reg:CC FLAGS_REG))]
11372 ""
11373 "and{b}\t{%h2, %0|%0, %h2}"
11374 [(set_attr "isa" "*,nox64")
11375 (set_attr "type" "alu")
11376 (set_attr "mode" "QI")])
11377
11378 (define_expand "andqi_ext_1"
11379 [(parallel
11380 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11381 (const_int 8)
11382 (const_int 8))
11383 (subreg:HI
11384 (and:QI
11385 (subreg:QI
11386 (zero_extract:HI (match_operand:HI 1 "register_operand")
11387 (const_int 8)
11388 (const_int 8)) 0)
11389 (match_operand:QI 2 "const_int_operand")) 0))
11390 (clobber (reg:CC FLAGS_REG))])])
11391
11392 (define_insn "*andqi_ext<mode>_1"
11393 [(set (zero_extract:SWI248
11394 (match_operand 0 "int248_register_operand" "+Q,Q")
11395 (const_int 8)
11396 (const_int 8))
11397 (subreg:SWI248
11398 (and:QI
11399 (subreg:QI
11400 (match_operator:SWI248 3 "extract_operator"
11401 [(match_operand 1 "int248_register_operand" "0,0")
11402 (const_int 8)
11403 (const_int 8)]) 0)
11404 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
11405 (clobber (reg:CC FLAGS_REG))]
11406 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11407 rtx_equal_p (operands[0], operands[1])"
11408 "and{b}\t{%2, %h0|%h0, %2}"
11409 [(set_attr "isa" "*,nox64")
11410 (set_attr "type" "alu")
11411 (set_attr "mode" "QI")])
11412
11413 ;; Generated by peephole translating test to and. This shows up
11414 ;; often in fp comparisons.
11415 (define_insn "*andqi_ext<mode>_1_cc"
11416 [(set (reg FLAGS_REG)
11417 (compare
11418 (and:QI
11419 (subreg:QI
11420 (match_operator:SWI248 3 "extract_operator"
11421 [(match_operand 1 "int248_register_operand" "0,0")
11422 (const_int 8)
11423 (const_int 8)]) 0)
11424 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
11425 (const_int 0)))
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_op_dup 3
11434 [(match_dup 1)
11435 (const_int 8)
11436 (const_int 8)]) 0)
11437 (match_dup 2)) 0))]
11438 "ix86_match_ccmode (insn, CCNOmode)
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 (define_insn "*andqi_ext<mode>_2"
11447 [(set (zero_extract:SWI248
11448 (match_operand 0 "int248_register_operand" "+Q")
11449 (const_int 8)
11450 (const_int 8))
11451 (subreg:SWI248
11452 (and:QI
11453 (subreg:QI
11454 (match_operator:SWI248 3 "extract_operator"
11455 [(match_operand 1 "int248_register_operand" "%0")
11456 (const_int 8)
11457 (const_int 8)]) 0)
11458 (subreg:QI
11459 (match_operator:SWI248 4 "extract_operator"
11460 [(match_operand 2 "int248_register_operand" "Q")
11461 (const_int 8)
11462 (const_int 8)]) 0)) 0))
11463 (clobber (reg:CC FLAGS_REG))]
11464 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11465 rtx_equal_p (operands[0], operands[1])
11466 || rtx_equal_p (operands[0], operands[2])"
11467 "and{b}\t{%h2, %h0|%h0, %h2}"
11468 [(set_attr "type" "alu")
11469 (set_attr "mode" "QI")])
11470
11471 ;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
11472
11473 ;; Convert wide AND instructions with immediate operand to shorter QImode
11474 ;; equivalents when possible.
11475 ;; Don't do the splitting with memory operands, since it introduces risk
11476 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
11477 ;; for size, but that can (should?) be handled by generic code instead.
11478 (define_split
11479 [(set (match_operand:SWI248 0 "QIreg_operand")
11480 (and:SWI248 (match_operand:SWI248 1 "register_operand")
11481 (match_operand:SWI248 2 "const_int_operand")))
11482 (clobber (reg:CC FLAGS_REG))]
11483 "reload_completed
11484 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11485 && !(~INTVAL (operands[2]) & ~(255 << 8))"
11486 [(parallel
11487 [(set (zero_extract:HI (match_dup 0)
11488 (const_int 8)
11489 (const_int 8))
11490 (subreg:HI
11491 (and:QI
11492 (subreg:QI
11493 (zero_extract:HI (match_dup 1)
11494 (const_int 8)
11495 (const_int 8)) 0)
11496 (match_dup 2)) 0))
11497 (clobber (reg:CC FLAGS_REG))])]
11498 {
11499 operands[0] = gen_lowpart (HImode, operands[0]);
11500 operands[1] = gen_lowpart (HImode, operands[1]);
11501 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11502 })
11503
11504 ;; Since AND can be encoded with sign extended immediate, this is only
11505 ;; profitable when 7th bit is not set.
11506 (define_split
11507 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11508 (and:SWI248 (match_operand:SWI248 1 "general_operand")
11509 (match_operand:SWI248 2 "const_int_operand")))
11510 (clobber (reg:CC FLAGS_REG))]
11511 "reload_completed
11512 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11513 && !(~INTVAL (operands[2]) & ~255)
11514 && !(INTVAL (operands[2]) & 128)"
11515 [(parallel [(set (strict_low_part (match_dup 0))
11516 (and:QI (match_dup 1)
11517 (match_dup 2)))
11518 (clobber (reg:CC FLAGS_REG))])]
11519 {
11520 operands[0] = gen_lowpart (QImode, operands[0]);
11521 operands[1] = gen_lowpart (QImode, operands[1]);
11522 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11523 })
11524
11525 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11526 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11527 (and:<DWI>
11528 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11529 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11530 (clobber (reg:CC FLAGS_REG))]
11531 "TARGET_BMI"
11532 "#"
11533 "&& reload_completed"
11534 [(parallel [(set (match_dup 0)
11535 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11536 (clobber (reg:CC FLAGS_REG))])
11537 (parallel [(set (match_dup 3)
11538 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11539 (clobber (reg:CC FLAGS_REG))])]
11540 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11541
11542 (define_insn_and_split "*andn<mode>3_doubleword"
11543 [(set (match_operand:DWI 0 "register_operand")
11544 (and:DWI
11545 (not:DWI (match_operand:DWI 1 "register_operand"))
11546 (match_operand:DWI 2 "nonimmediate_operand")))
11547 (clobber (reg:CC FLAGS_REG))]
11548 "!TARGET_BMI
11549 && ix86_pre_reload_split ()"
11550 "#"
11551 "&& 1"
11552 [(set (match_dup 3) (not:DWI (match_dup 1)))
11553 (parallel [(set (match_dup 0)
11554 (and:DWI (match_dup 3) (match_dup 2)))
11555 (clobber (reg:CC FLAGS_REG))])]
11556 "operands[3] = gen_reg_rtx (<MODE>mode);")
11557
11558 (define_insn "*andn<mode>_1"
11559 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11560 (and:SWI48
11561 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11562 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11563 (clobber (reg:CC FLAGS_REG))]
11564 "TARGET_BMI || TARGET_AVX512BW"
11565 "@
11566 andn\t{%2, %1, %0|%0, %1, %2}
11567 andn\t{%2, %1, %0|%0, %1, %2}
11568 #"
11569 [(set_attr "isa" "bmi,bmi,avx512bw")
11570 (set_attr "type" "bitmanip,bitmanip,msklog")
11571 (set_attr "btver2_decode" "direct, double,*")
11572 (set_attr "mode" "<MODE>")])
11573
11574 (define_insn "*andn<mode>_1"
11575 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11576 (and:SWI12
11577 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11578 (match_operand:SWI12 2 "register_operand" "r,k")))
11579 (clobber (reg:CC FLAGS_REG))]
11580 "TARGET_BMI || TARGET_AVX512BW"
11581 "@
11582 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
11583 #"
11584 [(set_attr "isa" "bmi,avx512f")
11585 (set_attr "type" "bitmanip,msklog")
11586 (set_attr "btver2_decode" "direct,*")
11587 (set (attr "mode")
11588 (cond [(eq_attr "alternative" "0")
11589 (const_string "SI")
11590 (and (eq_attr "alternative" "1")
11591 (match_test "!TARGET_AVX512DQ"))
11592 (const_string "HI")
11593 ]
11594 (const_string "<MODE>")))])
11595
11596 (define_insn "*andn_<mode>_ccno"
11597 [(set (reg FLAGS_REG)
11598 (compare
11599 (and:SWI48
11600 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
11601 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
11602 (const_int 0)))
11603 (clobber (match_scratch:SWI48 0 "=r,r"))]
11604 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
11605 "andn\t{%2, %1, %0|%0, %1, %2}"
11606 [(set_attr "type" "bitmanip")
11607 (set_attr "btver2_decode" "direct, double")
11608 (set_attr "mode" "<MODE>")])
11609
11610 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
11611 (define_split
11612 [(set (match_operand:SI 0 "register_operand")
11613 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
11614 (match_operand:SI 2 "nonimmediate_operand")))
11615 (clobber (reg:CC FLAGS_REG))]
11616 "reload_completed
11617 && optimize_insn_for_size_p () && optimize_size > 1
11618 && REGNO (operands[0]) == REGNO (operands[1])
11619 && LEGACY_INT_REG_P (operands[0])
11620 && !REX_INT_REG_P (operands[2])
11621 && !reg_overlap_mentioned_p (operands[0], operands[2])"
11622 [(set (match_dup 0) (not:SI (match_dup 1)))
11623 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
11624 (clobber (reg:CC FLAGS_REG))])])
11625
11626 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
11627 (define_split
11628 [(set (match_operand 0 "flags_reg_operand")
11629 (match_operator 1 "compare_operator"
11630 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
11631 (match_operand:SI 3 "nonimmediate_operand"))
11632 (const_int 0)]))
11633 (clobber (match_dup 2))]
11634 "reload_completed
11635 && optimize_insn_for_size_p () && optimize_size > 1
11636 && LEGACY_INT_REG_P (operands[2])
11637 && !REX_INT_REG_P (operands[3])
11638 && !reg_overlap_mentioned_p (operands[2], operands[3])"
11639 [(set (match_dup 2) (not:SI (match_dup 2)))
11640 (set (match_dup 0) (match_op_dup 1
11641 [(and:SI (match_dup 3) (match_dup 2))
11642 (const_int 0)]))])
11643
11644 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
11645 (define_split
11646 [(set (match_operand:SWI48 0 "register_operand")
11647 (xor:SWI48
11648 (xor:SWI48
11649 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11650 (match_operand:SWI48 2 "nonimmediate_operand"))
11651 (match_dup 1))
11652 (match_operand:SWI48 3 "nonimmediate_operand")))
11653 (clobber (reg:CC FLAGS_REG))]
11654 "TARGET_BMI"
11655 [(parallel
11656 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11657 (clobber (reg:CC FLAGS_REG))])
11658 (parallel
11659 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11660 (clobber (reg:CC FLAGS_REG))])]
11661 "operands[4] = gen_reg_rtx (<MODE>mode);")
11662
11663 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
11664 (define_split
11665 [(set (match_operand:SWI48 0 "register_operand")
11666 (xor:SWI48
11667 (xor:SWI48
11668 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11669 (match_operand:SWI48 2 "register_operand"))
11670 (match_dup 2))
11671 (match_operand:SWI48 3 "nonimmediate_operand")))
11672 (clobber (reg:CC FLAGS_REG))]
11673 "TARGET_BMI"
11674 [(parallel
11675 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11676 (clobber (reg:CC FLAGS_REG))])
11677 (parallel
11678 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11679 (clobber (reg:CC FLAGS_REG))])]
11680 "operands[4] = gen_reg_rtx (<MODE>mode);")
11681
11682 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
11683 (define_split
11684 [(set (match_operand:SWI48 0 "register_operand")
11685 (xor:SWI48
11686 (xor:SWI48
11687 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11688 (match_operand:SWI48 2 "nonimmediate_operand"))
11689 (match_operand:SWI48 3 "nonimmediate_operand"))
11690 (match_dup 1)))
11691 (clobber (reg:CC FLAGS_REG))]
11692 "TARGET_BMI"
11693 [(parallel
11694 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11695 (clobber (reg:CC FLAGS_REG))])
11696 (parallel
11697 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11698 (clobber (reg:CC FLAGS_REG))])]
11699 "operands[4] = gen_reg_rtx (<MODE>mode);")
11700
11701 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
11702 (define_split
11703 [(set (match_operand:SWI48 0 "register_operand")
11704 (xor:SWI48
11705 (xor:SWI48
11706 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11707 (match_operand:SWI48 2 "register_operand"))
11708 (match_operand:SWI48 3 "nonimmediate_operand"))
11709 (match_dup 2)))
11710 (clobber (reg:CC FLAGS_REG))]
11711 "TARGET_BMI"
11712 [(parallel
11713 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11714 (clobber (reg:CC FLAGS_REG))])
11715 (parallel
11716 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11717 (clobber (reg:CC FLAGS_REG))])]
11718 "operands[4] = gen_reg_rtx (<MODE>mode);")
11719 \f
11720 ;; Logical inclusive and exclusive OR instructions
11721
11722 ;; %%% This used to optimize known byte-wide and operations to memory.
11723 ;; If this is considered useful, it should be done with splitters.
11724
11725 (define_expand "<code><mode>3"
11726 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11727 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11728 (match_operand:SDWIM 2 "<general_operand>")))]
11729 ""
11730 {
11731 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11732 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11733 operands[2] = force_reg (<MODE>mode, operands[2]);
11734
11735 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
11736 DONE;
11737 })
11738
11739 (define_insn_and_split "*<code><dwi>3_doubleword"
11740 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11741 (any_or:<DWI>
11742 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11743 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11744 (clobber (reg:CC FLAGS_REG))]
11745 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
11746 "#"
11747 "&& reload_completed"
11748 [(const_int:DWIH 0)]
11749 {
11750 /* This insn may disappear completely when operands[2] == const0_rtx
11751 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
11752 bool emit_insn_deleted_note_p = false;
11753
11754 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11755
11756 if (operands[2] == const0_rtx)
11757 emit_insn_deleted_note_p = true;
11758 else if (operands[2] == constm1_rtx)
11759 {
11760 if (<CODE> == IOR)
11761 emit_move_insn (operands[0], constm1_rtx);
11762 else
11763 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
11764 }
11765 else
11766 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
11767
11768 if (operands[5] == const0_rtx)
11769 {
11770 if (emit_insn_deleted_note_p)
11771 emit_note (NOTE_INSN_DELETED);
11772 }
11773 else if (operands[5] == constm1_rtx)
11774 {
11775 if (<CODE> == IOR)
11776 emit_move_insn (operands[3], constm1_rtx);
11777 else
11778 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
11779 }
11780 else
11781 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
11782
11783 DONE;
11784 })
11785
11786 (define_insn "*<code><mode>_1"
11787 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11788 (any_or:SWI248
11789 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11790 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
11791 (clobber (reg:CC FLAGS_REG))]
11792 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11793 "@
11794 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11795 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11796 #"
11797 [(set (attr "isa")
11798 (cond [(eq_attr "alternative" "2")
11799 (if_then_else (eq_attr "mode" "SI,DI")
11800 (const_string "avx512bw")
11801 (const_string "avx512f"))
11802 ]
11803 (const_string "*")))
11804 (set_attr "type" "alu, alu, msklog")
11805 (set_attr "mode" "<MODE>")])
11806
11807 (define_insn_and_split "*notxor<mode>_1"
11808 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11809 (not:SWI248
11810 (xor:SWI248
11811 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11812 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
11813 (clobber (reg:CC FLAGS_REG))]
11814 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
11815 "#"
11816 "&& reload_completed"
11817 [(parallel
11818 [(set (match_dup 0)
11819 (xor:SWI248 (match_dup 1) (match_dup 2)))
11820 (clobber (reg:CC FLAGS_REG))])
11821 (set (match_dup 0)
11822 (not:SWI248 (match_dup 0)))]
11823 {
11824 if (MASK_REG_P (operands[0]))
11825 {
11826 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
11827 DONE;
11828 }
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 "*iordi_1_bts"
11841 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11842 (ior:DI
11843 (match_operand:DI 1 "nonimmediate_operand" "%0")
11844 (match_operand:DI 2 "const_int_operand" "n")))
11845 (clobber (reg:CC FLAGS_REG))]
11846 "TARGET_64BIT && TARGET_USE_BT
11847 && ix86_binary_operator_ok (IOR, DImode, operands)
11848 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
11849 "#"
11850 "&& reload_completed"
11851 [(parallel [(set (zero_extract:DI (match_dup 0)
11852 (const_int 1)
11853 (match_dup 3))
11854 (const_int 1))
11855 (clobber (reg:CC FLAGS_REG))])]
11856 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
11857 [(set_attr "type" "alu1")
11858 (set_attr "prefix_0f" "1")
11859 (set_attr "znver1_decode" "double")
11860 (set_attr "mode" "DI")])
11861
11862 (define_insn_and_split "*xordi_1_btc"
11863 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11864 (xor:DI
11865 (match_operand:DI 1 "nonimmediate_operand" "%0")
11866 (match_operand:DI 2 "const_int_operand" "n")))
11867 (clobber (reg:CC FLAGS_REG))]
11868 "TARGET_64BIT && TARGET_USE_BT
11869 && ix86_binary_operator_ok (XOR, DImode, operands)
11870 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
11871 "#"
11872 "&& reload_completed"
11873 [(parallel [(set (zero_extract:DI (match_dup 0)
11874 (const_int 1)
11875 (match_dup 3))
11876 (not:DI (zero_extract:DI (match_dup 0)
11877 (const_int 1)
11878 (match_dup 3))))
11879 (clobber (reg:CC FLAGS_REG))])]
11880 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
11881 [(set_attr "type" "alu1")
11882 (set_attr "prefix_0f" "1")
11883 (set_attr "znver1_decode" "double")
11884 (set_attr "mode" "DI")])
11885
11886 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
11887 (define_insn_and_split "*xor2andn"
11888 [(set (match_operand:SWI248 0 "register_operand")
11889 (xor:SWI248
11890 (and:SWI248
11891 (xor:SWI248
11892 (match_operand:SWI248 1 "nonimmediate_operand")
11893 (match_operand:SWI248 2 "nonimmediate_operand"))
11894 (match_operand:SWI248 3 "nonimmediate_operand"))
11895 (match_dup 1)))
11896 (clobber (reg:CC FLAGS_REG))]
11897 "TARGET_BMI && ix86_pre_reload_split ()"
11898 "#"
11899 "&& 1"
11900 [(parallel [(set (match_dup 4)
11901 (and:SWI248
11902 (not:SWI248
11903 (match_dup 3))
11904 (match_dup 1)))
11905 (clobber (reg:CC FLAGS_REG))])
11906 (parallel [(set (match_dup 5)
11907 (and:SWI248
11908 (match_dup 3)
11909 (match_dup 2)))
11910 (clobber (reg:CC FLAGS_REG))])
11911 (parallel [(set (match_dup 0)
11912 (ior:SWI248
11913 (match_dup 4)
11914 (match_dup 5)))
11915 (clobber (reg:CC FLAGS_REG))])]
11916 {
11917 operands[1] = force_reg (<MODE>mode, operands[1]);
11918 operands[3] = force_reg (<MODE>mode, operands[3]);
11919 operands[4] = gen_reg_rtx (<MODE>mode);
11920 operands[5] = gen_reg_rtx (<MODE>mode);
11921 })
11922
11923 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11924 (define_insn "*<code>si_1_zext"
11925 [(set (match_operand:DI 0 "register_operand" "=r")
11926 (zero_extend:DI
11927 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11928 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11929 (clobber (reg:CC FLAGS_REG))]
11930 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11931 "<logic>{l}\t{%2, %k0|%k0, %2}"
11932 [(set_attr "type" "alu")
11933 (set_attr "mode" "SI")])
11934
11935 (define_insn "*<code>si_1_zext_imm"
11936 [(set (match_operand:DI 0 "register_operand" "=r")
11937 (any_or:DI
11938 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
11939 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
11940 (clobber (reg:CC FLAGS_REG))]
11941 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11942 "<logic>{l}\t{%2, %k0|%k0, %2}"
11943 [(set_attr "type" "alu")
11944 (set_attr "mode" "SI")])
11945
11946 (define_insn "*<code>qi_1"
11947 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11948 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11949 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11950 (clobber (reg:CC FLAGS_REG))]
11951 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
11952 "@
11953 <logic>{b}\t{%2, %0|%0, %2}
11954 <logic>{b}\t{%2, %0|%0, %2}
11955 <logic>{l}\t{%k2, %k0|%k0, %k2}
11956 #"
11957 [(set_attr "isa" "*,*,*,avx512f")
11958 (set_attr "type" "alu,alu,alu,msklog")
11959 (set (attr "mode")
11960 (cond [(eq_attr "alternative" "2")
11961 (const_string "SI")
11962 (and (eq_attr "alternative" "3")
11963 (match_test "!TARGET_AVX512DQ"))
11964 (const_string "HI")
11965 ]
11966 (const_string "QI")))
11967 ;; Potential partial reg stall on alternative 2.
11968 (set (attr "preferred_for_speed")
11969 (cond [(eq_attr "alternative" "2")
11970 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11971 (symbol_ref "true")))])
11972
11973 (define_insn_and_split "*notxorqi_1"
11974 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11975 (not:QI
11976 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11977 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
11978 (clobber (reg:CC FLAGS_REG))]
11979 "ix86_binary_operator_ok (XOR, QImode, operands)"
11980 "#"
11981 "&& reload_completed"
11982 [(parallel
11983 [(set (match_dup 0)
11984 (xor:QI (match_dup 1) (match_dup 2)))
11985 (clobber (reg:CC FLAGS_REG))])
11986 (set (match_dup 0)
11987 (not:QI (match_dup 0)))]
11988 {
11989 if (mask_reg_operand (operands[0], QImode))
11990 {
11991 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
11992 DONE;
11993 }
11994 }
11995 [(set_attr "isa" "*,*,*,avx512f")
11996 (set_attr "type" "alu,alu,alu,msklog")
11997 (set (attr "mode")
11998 (cond [(eq_attr "alternative" "2")
11999 (const_string "SI")
12000 (and (eq_attr "alternative" "3")
12001 (match_test "!TARGET_AVX512DQ"))
12002 (const_string "HI")
12003 ]
12004 (const_string "QI")))
12005 ;; Potential partial reg stall on alternative 2.
12006 (set (attr "preferred_for_speed")
12007 (cond [(eq_attr "alternative" "2")
12008 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
12009 (symbol_ref "true")))])
12010
12011 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12012 (define_insn_and_split "*<code><mode>_1_slp"
12013 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12014 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
12015 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
12016 (clobber (reg:CC FLAGS_REG))]
12017 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12018 "@
12019 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
12020 #"
12021 "&& reload_completed"
12022 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12023 (parallel
12024 [(set (strict_low_part (match_dup 0))
12025 (any_or:SWI12 (match_dup 0) (match_dup 2)))
12026 (clobber (reg:CC FLAGS_REG))])]
12027 ""
12028 [(set_attr "type" "alu")
12029 (set_attr "mode" "<MODE>")])
12030
12031 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
12032 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
12033 ;; This eliminates sign extension after logic operation.
12034
12035 (define_split
12036 [(set (match_operand:SWI248 0 "register_operand")
12037 (sign_extend:SWI248
12038 (any_logic:QI (match_operand:QI 1 "memory_operand")
12039 (match_operand:QI 2 "const_int_operand"))))]
12040 ""
12041 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
12042 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
12043 "operands[3] = gen_reg_rtx (<MODE>mode);")
12044
12045 (define_split
12046 [(set (match_operand:SWI48 0 "register_operand")
12047 (sign_extend:SWI48
12048 (any_logic:HI (match_operand:HI 1 "memory_operand")
12049 (match_operand:HI 2 "const_int_operand"))))]
12050 ""
12051 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
12052 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
12053 "operands[3] = gen_reg_rtx (<MODE>mode);")
12054
12055 (define_split
12056 [(set (match_operand:DI 0 "register_operand")
12057 (sign_extend:DI
12058 (any_logic:SI (match_operand:SI 1 "memory_operand")
12059 (match_operand:SI 2 "const_int_operand"))))]
12060 "TARGET_64BIT"
12061 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
12062 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
12063 "operands[3] = gen_reg_rtx (DImode);")
12064
12065 (define_insn "*<code><mode>_2"
12066 [(set (reg FLAGS_REG)
12067 (compare (any_or:SWI
12068 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
12069 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
12070 (const_int 0)))
12071 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12072 (any_or:SWI (match_dup 1) (match_dup 2)))]
12073 "ix86_match_ccmode (insn, CCNOmode)
12074 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12075 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12076 [(set_attr "type" "alu")
12077 (set_attr "mode" "<MODE>")])
12078
12079 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12080 ;; ??? Special case for immediate operand is missing - it is tricky.
12081 (define_insn "*<code>si_2_zext"
12082 [(set (reg FLAGS_REG)
12083 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12084 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12085 (const_int 0)))
12086 (set (match_operand:DI 0 "register_operand" "=r")
12087 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12088 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12089 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12090 "<logic>{l}\t{%2, %k0|%k0, %2}"
12091 [(set_attr "type" "alu")
12092 (set_attr "mode" "SI")])
12093
12094 (define_insn "*<code>si_2_zext_imm"
12095 [(set (reg FLAGS_REG)
12096 (compare (any_or:SI
12097 (match_operand:SI 1 "nonimmediate_operand" "%0")
12098 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12099 (const_int 0)))
12100 (set (match_operand:DI 0 "register_operand" "=r")
12101 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12102 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12103 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12104 "<logic>{l}\t{%2, %k0|%k0, %2}"
12105 [(set_attr "type" "alu")
12106 (set_attr "mode" "SI")])
12107
12108 (define_insn "*<code><mode>_3"
12109 [(set (reg FLAGS_REG)
12110 (compare (any_or:SWI
12111 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12112 (match_operand:SWI 2 "<general_operand>" "<g>"))
12113 (const_int 0)))
12114 (clobber (match_scratch:SWI 0 "=<r>"))]
12115 "ix86_match_ccmode (insn, CCNOmode)
12116 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12117 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12118 [(set_attr "type" "alu")
12119 (set_attr "mode" "<MODE>")])
12120
12121 (define_insn "*<code>qi_ext<mode>_0"
12122 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
12123 (any_or:QI
12124 (subreg:QI
12125 (match_operator:SWI248 3 "extract_operator"
12126 [(match_operand 2 "int248_register_operand" "Q,Q")
12127 (const_int 8)
12128 (const_int 8)]) 0)
12129 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
12130 (clobber (reg:CC FLAGS_REG))]
12131 ""
12132 "<logic>{b}\t{%h2, %0|%0, %h2}"
12133 [(set_attr "isa" "*,nox64")
12134 (set_attr "type" "alu")
12135 (set_attr "mode" "QI")])
12136
12137 (define_insn "*<code>qi_ext<mode>_1"
12138 [(set (zero_extract:SWI248
12139 (match_operand 0 "int248_register_operand" "+Q,Q")
12140 (const_int 8)
12141 (const_int 8))
12142 (subreg:SWI248
12143 (any_or:QI
12144 (subreg:QI
12145 (match_operator:SWI248 3 "extract_operator"
12146 [(match_operand 1 "int248_register_operand" "0,0")
12147 (const_int 8)
12148 (const_int 8)]) 0)
12149 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
12150 (clobber (reg:CC FLAGS_REG))]
12151 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12152 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12153 && rtx_equal_p (operands[0], operands[1])"
12154 "<logic>{b}\t{%2, %h0|%h0, %2}"
12155 [(set_attr "isa" "*,nox64")
12156 (set_attr "type" "alu")
12157 (set_attr "mode" "QI")])
12158
12159 (define_insn "*<code>qi_ext<mode>_2"
12160 [(set (zero_extract:SWI248
12161 (match_operand 0 "int248_register_operand" "+Q")
12162 (const_int 8)
12163 (const_int 8))
12164 (subreg:SWI248
12165 (any_or:QI
12166 (subreg:QI
12167 (match_operator:SWI248 3 "extract_operator"
12168 [(match_operand 1 "int248_register_operand" "%0")
12169 (const_int 8)
12170 (const_int 8)]) 0)
12171 (subreg:QI
12172 (match_operator:SWI248 4 "extract_operator"
12173 [(match_operand 2 "int248_register_operand" "Q")
12174 (const_int 8)
12175 (const_int 8)]) 0)) 0))
12176 (clobber (reg:CC FLAGS_REG))]
12177 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12178 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12179 && (rtx_equal_p (operands[0], operands[1])
12180 || rtx_equal_p (operands[0], operands[2]))"
12181 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12182 [(set_attr "type" "alu")
12183 (set_attr "mode" "QI")])
12184
12185 (define_insn "*<code>qi_ext<mode>_3"
12186 [(set (zero_extract:SWI248
12187 (match_operand 0 "int248_register_operand" "+Q")
12188 (const_int 8)
12189 (const_int 8))
12190 (zero_extract:SWI248
12191 (any_logic:SWI248
12192 (match_operand 1 "int248_register_operand" "%0")
12193 (match_operand 2 "int248_register_operand" "Q"))
12194 (const_int 8)
12195 (const_int 8)))
12196 (clobber (reg:CC FLAGS_REG))]
12197 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12198 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12199 && (rtx_equal_p (operands[0], operands[1])
12200 || rtx_equal_p (operands[0], operands[2]))"
12201 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12202 [(set_attr "type" "alu")
12203 (set_attr "mode" "QI")])
12204
12205 ;; Convert wide OR instructions with immediate operand to shorter QImode
12206 ;; equivalents when possible.
12207 ;; Don't do the splitting with memory operands, since it introduces risk
12208 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12209 ;; for size, but that can (should?) be handled by generic code instead.
12210 (define_split
12211 [(set (match_operand:SWI248 0 "QIreg_operand")
12212 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12213 (match_operand:SWI248 2 "const_int_operand")))
12214 (clobber (reg:CC FLAGS_REG))]
12215 "reload_completed
12216 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12217 && !(INTVAL (operands[2]) & ~(255 << 8))"
12218 [(parallel
12219 [(set (zero_extract:HI (match_dup 0)
12220 (const_int 8)
12221 (const_int 8))
12222 (subreg:HI
12223 (any_or:QI
12224 (subreg:QI
12225 (zero_extract:HI (match_dup 1)
12226 (const_int 8)
12227 (const_int 8)) 0)
12228 (match_dup 2)) 0))
12229 (clobber (reg:CC FLAGS_REG))])]
12230 {
12231 /* Handle the case where INTVAL (operands[2]) == 0. */
12232 if (operands[2] == const0_rtx)
12233 {
12234 if (!rtx_equal_p (operands[0], operands[1]))
12235 emit_move_insn (operands[0], operands[1]);
12236 else
12237 emit_note (NOTE_INSN_DELETED);
12238 DONE;
12239 }
12240 operands[0] = gen_lowpart (HImode, operands[0]);
12241 operands[1] = gen_lowpart (HImode, operands[1]);
12242 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12243 })
12244
12245 ;; Since OR can be encoded with sign extended immediate, this is only
12246 ;; profitable when 7th bit is set.
12247 (define_split
12248 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12249 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12250 (match_operand:SWI248 2 "const_int_operand")))
12251 (clobber (reg:CC FLAGS_REG))]
12252 "reload_completed
12253 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12254 && !(INTVAL (operands[2]) & ~255)
12255 && (INTVAL (operands[2]) & 128)"
12256 [(parallel [(set (strict_low_part (match_dup 0))
12257 (any_or:QI (match_dup 1)
12258 (match_dup 2)))
12259 (clobber (reg:CC FLAGS_REG))])]
12260 {
12261 operands[0] = gen_lowpart (QImode, operands[0]);
12262 operands[1] = gen_lowpart (QImode, operands[1]);
12263 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12264 })
12265
12266 (define_expand "xorqi_ext_1_cc"
12267 [(parallel
12268 [(set (reg:CCNO FLAGS_REG)
12269 (compare:CCNO
12270 (xor:QI
12271 (subreg:QI
12272 (zero_extract:HI (match_operand:HI 1 "register_operand")
12273 (const_int 8)
12274 (const_int 8)) 0)
12275 (match_operand:QI 2 "const_int_operand"))
12276 (const_int 0)))
12277 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12278 (const_int 8)
12279 (const_int 8))
12280 (subreg:HI
12281 (xor:QI
12282 (subreg:QI
12283 (zero_extract:HI (match_dup 1)
12284 (const_int 8)
12285 (const_int 8)) 0)
12286 (match_dup 2)) 0))])])
12287
12288 (define_insn "*xorqi_ext<mode>_1_cc"
12289 [(set (reg FLAGS_REG)
12290 (compare
12291 (xor:QI
12292 (subreg:QI
12293 (match_operator:SWI248 3 "extract_operator"
12294 [(match_operand 1 "int248_register_operand" "0,0")
12295 (const_int 8)
12296 (const_int 8)]) 0)
12297 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
12298 (const_int 0)))
12299 (set (zero_extract:SWI248
12300 (match_operand 0 "int248_register_operand" "+Q,Q")
12301 (const_int 8)
12302 (const_int 8))
12303 (subreg:SWI248
12304 (xor:QI
12305 (subreg:QI
12306 (match_op_dup 3
12307 [(match_dup 1)
12308 (const_int 8)
12309 (const_int 8)]) 0)
12310 (match_dup 2)) 0))]
12311 "ix86_match_ccmode (insn, CCNOmode)
12312 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12313 && rtx_equal_p (operands[0], operands[1])"
12314 "xor{b}\t{%2, %h0|%h0, %2}"
12315 [(set_attr "isa" "*,nox64")
12316 (set_attr "type" "alu")
12317 (set_attr "mode" "QI")])
12318
12319 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12320 (define_peephole2
12321 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12322 (const_int 0))
12323 (clobber (reg:CC FLAGS_REG))])
12324 (parallel [(set (match_dup 0)
12325 (any_or_plus:SWI (match_dup 0)
12326 (match_operand:SWI 1 "<general_operand>")))
12327 (clobber (reg:CC FLAGS_REG))])]
12328 ""
12329 [(set (match_dup 0) (match_dup 1))])
12330
12331 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12332 (define_insn_and_split "*concat<mode><dwi>3_1"
12333 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12334 (any_or_plus:<DWI>
12335 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12336 (match_operand:QI 2 "const_int_operand"))
12337 (zero_extend:<DWI>
12338 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12339 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12340 "#"
12341 "&& reload_completed"
12342 [(const_int 0)]
12343 {
12344 split_double_concat (<DWI>mode, operands[0], operands[3],
12345 gen_lowpart (<MODE>mode, operands[1]));
12346 DONE;
12347 })
12348
12349 (define_insn_and_split "*concat<mode><dwi>3_2"
12350 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12351 (any_or_plus:<DWI>
12352 (zero_extend:<DWI>
12353 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12354 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12355 (match_operand:QI 3 "const_int_operand"))))]
12356 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12357 "#"
12358 "&& reload_completed"
12359 [(const_int 0)]
12360 {
12361 split_double_concat (<DWI>mode, operands[0], operands[1],
12362 gen_lowpart (<MODE>mode, operands[2]));
12363 DONE;
12364 })
12365
12366 (define_insn_and_split "*concat<mode><dwi>3_3"
12367 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12368 (any_or_plus:<DWI>
12369 (ashift:<DWI>
12370 (zero_extend:<DWI>
12371 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12372 (match_operand:QI 2 "const_int_operand"))
12373 (zero_extend:<DWI>
12374 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m"))))]
12375 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12376 "#"
12377 "&& reload_completed"
12378 [(const_int 0)]
12379 {
12380 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12381 DONE;
12382 })
12383
12384 (define_insn_and_split "*concat<mode><dwi>3_4"
12385 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12386 (any_or_plus:<DWI>
12387 (zero_extend:<DWI>
12388 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12389 (ashift:<DWI>
12390 (zero_extend:<DWI>
12391 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12392 (match_operand:QI 3 "const_int_operand"))))]
12393 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12394 "#"
12395 "&& reload_completed"
12396 [(const_int 0)]
12397 {
12398 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12399 DONE;
12400 })
12401
12402 (define_insn_and_split "*concat<half><mode>3_5"
12403 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12404 (any_or_plus:DWI
12405 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12406 (match_operand:QI 2 "const_int_operand"))
12407 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12408 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12409 && (<MODE>mode == DImode
12410 ? CONST_INT_P (operands[3])
12411 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12412 : CONST_INT_P (operands[3])
12413 ? INTVAL (operands[3]) >= 0
12414 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12415 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12416 && !(CONST_INT_P (operands[3])
12417 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12418 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12419 0)),
12420 VOIDmode))"
12421 "#"
12422 "&& reload_completed"
12423 [(const_int 0)]
12424 {
12425 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12426 split_double_concat (<MODE>mode, operands[0], op3,
12427 gen_lowpart (<HALF>mode, operands[1]));
12428 DONE;
12429 }
12430 [(set_attr "isa" "*,nox64,x64")])
12431
12432 (define_insn_and_split "*concat<mode><dwi>3_6"
12433 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12434 (any_or_plus:<DWI>
12435 (ashift:<DWI>
12436 (zero_extend:<DWI>
12437 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12438 (match_operand:QI 2 "const_int_operand"))
12439 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12440 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12441 && (<DWI>mode == DImode
12442 ? CONST_INT_P (operands[3])
12443 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12444 : CONST_INT_P (operands[3])
12445 ? INTVAL (operands[3]) >= 0
12446 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12447 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12448 && !(CONST_INT_P (operands[3])
12449 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12450 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12451 0)),
12452 VOIDmode))"
12453 "#"
12454 "&& reload_completed"
12455 [(const_int 0)]
12456 {
12457 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12458 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12459 DONE;
12460 }
12461 [(set_attr "isa" "*,nox64,x64,*")])
12462
12463 (define_insn_and_split "*concat<mode><dwi>3_7"
12464 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12465 (any_or_plus:<DWI>
12466 (zero_extend:<DWI>
12467 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12468 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12469 "<DWI>mode == DImode
12470 ? CONST_INT_P (operands[2])
12471 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12472 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12473 : CONST_WIDE_INT_P (operands[2])
12474 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12475 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12476 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12477 1)),
12478 VOIDmode)"
12479 "#"
12480 "&& reload_completed"
12481 [(const_int 0)]
12482 {
12483 rtx op2;
12484 if (<DWI>mode == DImode)
12485 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12486 else
12487 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12488 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12489 DONE;
12490 }
12491 [(set_attr "isa" "*,nox64,x64,*")])
12492 \f
12493 ;; Negation instructions
12494
12495 (define_expand "neg<mode>2"
12496 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12497 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12498 ""
12499 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12500
12501 (define_insn_and_split "*neg<dwi>2_doubleword"
12502 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12503 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12504 (clobber (reg:CC FLAGS_REG))]
12505 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12506 "#"
12507 "&& reload_completed"
12508 [(parallel
12509 [(set (reg:CCC FLAGS_REG)
12510 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12511 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12512 (parallel
12513 [(set (match_dup 2)
12514 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12515 (match_dup 3))
12516 (const_int 0)))
12517 (clobber (reg:CC FLAGS_REG))])
12518 (parallel
12519 [(set (match_dup 2)
12520 (neg:DWIH (match_dup 2)))
12521 (clobber (reg:CC FLAGS_REG))])]
12522 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12523
12524 ;; Convert:
12525 ;; mov %esi, %edx
12526 ;; negl %eax
12527 ;; adcl $0, %edx
12528 ;; negl %edx
12529 ;; to:
12530 ;; xorl %edx, %edx
12531 ;; negl %eax
12532 ;; sbbl %esi, %edx
12533
12534 (define_peephole2
12535 [(set (match_operand:SWI48 0 "general_reg_operand")
12536 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12537 (parallel
12538 [(set (reg:CCC FLAGS_REG)
12539 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12540 (const_int 0)] UNSPEC_CC_NE))
12541 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12542 (parallel
12543 [(set (match_dup 0)
12544 (plus:SWI48 (plus:SWI48
12545 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12546 (match_dup 0))
12547 (const_int 0)))
12548 (clobber (reg:CC FLAGS_REG))])
12549 (parallel
12550 [(set (match_dup 0)
12551 (neg:SWI48 (match_dup 0)))
12552 (clobber (reg:CC FLAGS_REG))])]
12553 "REGNO (operands[0]) != REGNO (operands[2])
12554 && !reg_mentioned_p (operands[0], operands[1])
12555 && !reg_mentioned_p (operands[2], operands[1])"
12556 [(parallel
12557 [(set (reg:CCC FLAGS_REG)
12558 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12559 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12560 (parallel
12561 [(set (match_dup 0)
12562 (minus:SWI48 (minus:SWI48
12563 (match_dup 0)
12564 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12565 (match_dup 1)))
12566 (clobber (reg:CC FLAGS_REG))])]
12567 "ix86_expand_clear (operands[0]);")
12568
12569 ;; Convert:
12570 ;; xorl %edx, %edx
12571 ;; negl %eax
12572 ;; adcl $0, %edx
12573 ;; negl %edx
12574 ;; to:
12575 ;; negl %eax
12576 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12577
12578 (define_peephole2
12579 [(parallel
12580 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12581 (clobber (reg:CC FLAGS_REG))])
12582 (parallel
12583 [(set (reg:CCC FLAGS_REG)
12584 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12585 (const_int 0)] UNSPEC_CC_NE))
12586 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12587 (parallel
12588 [(set (match_dup 0)
12589 (plus:SWI48 (plus:SWI48
12590 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12591 (match_dup 0))
12592 (const_int 0)))
12593 (clobber (reg:CC FLAGS_REG))])
12594 (parallel
12595 [(set (match_dup 0)
12596 (neg:SWI48 (match_dup 0)))
12597 (clobber (reg:CC FLAGS_REG))])]
12598 "REGNO (operands[0]) != REGNO (operands[1])"
12599 [(parallel
12600 [(set (reg:CCC FLAGS_REG)
12601 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12602 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12603 (parallel
12604 [(set (match_dup 0)
12605 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12606 (const_int -1)
12607 (const_int 0)))
12608 (clobber (reg:CC FLAGS_REG))])])
12609
12610 (define_insn "*neg<mode>_1"
12611 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12612 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12613 (clobber (reg:CC FLAGS_REG))]
12614 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12615 "neg{<imodesuffix>}\t%0"
12616 [(set_attr "type" "negnot")
12617 (set_attr "mode" "<MODE>")])
12618
12619 (define_insn "*negsi_1_zext"
12620 [(set (match_operand:DI 0 "register_operand" "=r")
12621 (zero_extend:DI
12622 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12623 (clobber (reg:CC FLAGS_REG))]
12624 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12625 "neg{l}\t%k0"
12626 [(set_attr "type" "negnot")
12627 (set_attr "mode" "SI")])
12628
12629 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12630 (define_insn_and_split "*neg<mode>_1_slp"
12631 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12632 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12633 (clobber (reg:CC FLAGS_REG))]
12634 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12635 "@
12636 neg{<imodesuffix>}\t%0
12637 #"
12638 "&& reload_completed"
12639 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12640 (parallel
12641 [(set (strict_low_part (match_dup 0))
12642 (neg:SWI12 (match_dup 0)))
12643 (clobber (reg:CC FLAGS_REG))])]
12644 ""
12645 [(set_attr "type" "negnot")
12646 (set_attr "mode" "<MODE>")])
12647
12648 (define_insn "*neg<mode>_2"
12649 [(set (reg FLAGS_REG)
12650 (compare
12651 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12652 (const_int 0)))
12653 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12654 (neg:SWI (match_dup 1)))]
12655 "ix86_match_ccmode (insn, CCGOCmode)
12656 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12657 "neg{<imodesuffix>}\t%0"
12658 [(set_attr "type" "negnot")
12659 (set_attr "mode" "<MODE>")])
12660
12661 (define_insn "*negsi_2_zext"
12662 [(set (reg FLAGS_REG)
12663 (compare
12664 (neg:SI (match_operand:SI 1 "register_operand" "0"))
12665 (const_int 0)))
12666 (set (match_operand:DI 0 "register_operand" "=r")
12667 (zero_extend:DI
12668 (neg:SI (match_dup 1))))]
12669 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12670 && ix86_unary_operator_ok (NEG, SImode, operands)"
12671 "neg{l}\t%k0"
12672 [(set_attr "type" "negnot")
12673 (set_attr "mode" "SI")])
12674
12675 (define_insn "*neg<mode>_ccc_1"
12676 [(set (reg:CCC FLAGS_REG)
12677 (unspec:CCC
12678 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12679 (const_int 0)] UNSPEC_CC_NE))
12680 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12681 (neg:SWI (match_dup 1)))]
12682 ""
12683 "neg{<imodesuffix>}\t%0"
12684 [(set_attr "type" "negnot")
12685 (set_attr "mode" "<MODE>")])
12686
12687 (define_insn "*neg<mode>_ccc_2"
12688 [(set (reg:CCC FLAGS_REG)
12689 (unspec:CCC
12690 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12691 (const_int 0)] UNSPEC_CC_NE))
12692 (clobber (match_scratch:SWI 0 "=<r>"))]
12693 ""
12694 "neg{<imodesuffix>}\t%0"
12695 [(set_attr "type" "negnot")
12696 (set_attr "mode" "<MODE>")])
12697
12698 (define_expand "x86_neg<mode>_ccc"
12699 [(parallel
12700 [(set (reg:CCC FLAGS_REG)
12701 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12702 (const_int 0)] UNSPEC_CC_NE))
12703 (set (match_operand:SWI48 0 "register_operand")
12704 (neg:SWI48 (match_dup 1)))])])
12705
12706 (define_insn "*negqi_ext<mode>_2"
12707 [(set (zero_extract:SWI248
12708 (match_operand 0 "int248_register_operand" "+Q")
12709 (const_int 8)
12710 (const_int 8))
12711 (subreg:SWI248
12712 (neg:QI
12713 (subreg:QI
12714 (match_operator:SWI248 2 "extract_operator"
12715 [(match_operand 1 "int248_register_operand" "0")
12716 (const_int 8)
12717 (const_int 8)]) 0)) 0))
12718 (clobber (reg:CC FLAGS_REG))]
12719 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
12720 rtx_equal_p (operands[0], operands[1])"
12721 "neg{b}\t%h0"
12722 [(set_attr "type" "negnot")
12723 (set_attr "mode" "QI")])
12724
12725 ;; Negate with jump on overflow.
12726 (define_expand "negv<mode>3"
12727 [(parallel [(set (reg:CCO FLAGS_REG)
12728 (unspec:CCO
12729 [(match_operand:SWI 1 "register_operand")
12730 (match_dup 3)] UNSPEC_CC_NE))
12731 (set (match_operand:SWI 0 "register_operand")
12732 (neg:SWI (match_dup 1)))])
12733 (set (pc) (if_then_else
12734 (eq (reg:CCO FLAGS_REG) (const_int 0))
12735 (label_ref (match_operand 2))
12736 (pc)))]
12737 ""
12738 {
12739 operands[3]
12740 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
12741 <MODE>mode);
12742 })
12743
12744 (define_insn "*negv<mode>3"
12745 [(set (reg:CCO FLAGS_REG)
12746 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
12747 (match_operand:SWI 2 "const_int_operand")]
12748 UNSPEC_CC_NE))
12749 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12750 (neg:SWI (match_dup 1)))]
12751 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
12752 && mode_signbit_p (<MODE>mode, operands[2])"
12753 "neg{<imodesuffix>}\t%0"
12754 [(set_attr "type" "negnot")
12755 (set_attr "mode" "<MODE>")])
12756
12757 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
12758 (define_peephole2
12759 [(set (match_operand:SWI 0 "general_reg_operand")
12760 (match_operand:SWI 1 "general_reg_operand"))
12761 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
12762 (clobber (reg:CC FLAGS_REG))])
12763 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
12764 ""
12765 [(set (match_dup 0) (match_dup 1))
12766 (parallel [(set (reg:CCZ FLAGS_REG)
12767 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
12768 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
12769
12770 ;; Special expand pattern to handle integer mode abs
12771
12772 (define_expand "abs<mode>2"
12773 [(parallel
12774 [(set (match_operand:SDWIM 0 "register_operand")
12775 (abs:SDWIM
12776 (match_operand:SDWIM 1 "general_operand")))
12777 (clobber (reg:CC FLAGS_REG))])]
12778 "TARGET_CMOVE
12779 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
12780 {
12781 if (TARGET_EXPAND_ABS)
12782 {
12783 machine_mode mode = <MODE>mode;
12784 operands[1] = force_reg (mode, operands[1]);
12785
12786 /* Generate rtx abs using:
12787 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
12788
12789 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
12790 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
12791 shift_amount, NULL_RTX,
12792 0, OPTAB_DIRECT);
12793 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
12794 operands[0], 0, OPTAB_DIRECT);
12795 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
12796 operands[0], 0, OPTAB_DIRECT);
12797 if (!rtx_equal_p (minus_dst, operands[0]))
12798 emit_move_insn (operands[0], minus_dst);
12799 DONE;
12800 }
12801 })
12802
12803 (define_insn_and_split "*abs<dwi>2_doubleword"
12804 [(set (match_operand:<DWI> 0 "register_operand")
12805 (abs:<DWI>
12806 (match_operand:<DWI> 1 "general_operand")))
12807 (clobber (reg:CC FLAGS_REG))]
12808 "TARGET_CMOVE
12809 && ix86_pre_reload_split ()"
12810 "#"
12811 "&& 1"
12812 [(parallel
12813 [(set (reg:CCC FLAGS_REG)
12814 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12815 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12816 (parallel
12817 [(set (match_dup 5)
12818 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12819 (match_dup 4))
12820 (const_int 0)))
12821 (clobber (reg:CC FLAGS_REG))])
12822 (parallel
12823 [(set (reg:CCGOC FLAGS_REG)
12824 (compare:CCGOC
12825 (neg:DWIH (match_dup 5))
12826 (const_int 0)))
12827 (set (match_dup 5)
12828 (neg:DWIH (match_dup 5)))])
12829 (set (match_dup 0)
12830 (if_then_else:DWIH
12831 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12832 (match_dup 2)
12833 (match_dup 1)))
12834 (set (match_dup 3)
12835 (if_then_else:DWIH
12836 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12837 (match_dup 5)
12838 (match_dup 4)))]
12839 {
12840 operands[1] = force_reg (<DWI>mode, operands[1]);
12841 operands[2] = gen_reg_rtx (<DWI>mode);
12842
12843 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12844 })
12845
12846 (define_insn_and_split "*nabs<dwi>2_doubleword"
12847 [(set (match_operand:<DWI> 0 "register_operand")
12848 (neg:<DWI>
12849 (abs:<DWI>
12850 (match_operand:<DWI> 1 "general_operand"))))
12851 (clobber (reg:CC FLAGS_REG))]
12852 "TARGET_CMOVE
12853 && ix86_pre_reload_split ()"
12854 "#"
12855 "&& 1"
12856 [(parallel
12857 [(set (reg:CCC FLAGS_REG)
12858 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12859 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12860 (parallel
12861 [(set (match_dup 5)
12862 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12863 (match_dup 4))
12864 (const_int 0)))
12865 (clobber (reg:CC FLAGS_REG))])
12866 (parallel
12867 [(set (reg:CCGOC FLAGS_REG)
12868 (compare:CCGOC
12869 (neg:DWIH (match_dup 5))
12870 (const_int 0)))
12871 (set (match_dup 5)
12872 (neg:DWIH (match_dup 5)))])
12873 (set (match_dup 0)
12874 (if_then_else:DWIH
12875 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12876 (match_dup 2)
12877 (match_dup 1)))
12878 (set (match_dup 3)
12879 (if_then_else:DWIH
12880 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12881 (match_dup 5)
12882 (match_dup 4)))]
12883 {
12884 operands[1] = force_reg (<DWI>mode, operands[1]);
12885 operands[2] = gen_reg_rtx (<DWI>mode);
12886
12887 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12888 })
12889
12890 (define_insn_and_split "*abs<mode>2_1"
12891 [(set (match_operand:SWI 0 "register_operand")
12892 (abs:SWI
12893 (match_operand:SWI 1 "general_operand")))
12894 (clobber (reg:CC FLAGS_REG))]
12895 "TARGET_CMOVE
12896 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
12897 && ix86_pre_reload_split ()"
12898 "#"
12899 "&& 1"
12900 [(parallel
12901 [(set (reg:CCGOC FLAGS_REG)
12902 (compare:CCGOC
12903 (neg:SWI (match_dup 1))
12904 (const_int 0)))
12905 (set (match_dup 2)
12906 (neg:SWI (match_dup 1)))])
12907 (set (match_dup 0)
12908 (if_then_else:SWI
12909 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12910 (match_dup 2)
12911 (match_dup 1)))]
12912 {
12913 operands[1] = force_reg (<MODE>mode, operands[1]);
12914 operands[2] = gen_reg_rtx (<MODE>mode);
12915 })
12916
12917 (define_insn_and_split "*nabs<mode>2_1"
12918 [(set (match_operand:SWI 0 "register_operand")
12919 (neg:SWI
12920 (abs:SWI
12921 (match_operand:SWI 1 "general_operand"))))
12922 (clobber (reg:CC FLAGS_REG))]
12923 "TARGET_CMOVE
12924 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
12925 && ix86_pre_reload_split ()"
12926 "#"
12927 "&& 1"
12928 [(parallel
12929 [(set (reg:CCGOC FLAGS_REG)
12930 (compare:CCGOC
12931 (neg:SWI (match_dup 1))
12932 (const_int 0)))
12933 (set (match_dup 2)
12934 (neg:SWI (match_dup 1)))])
12935 (set (match_dup 0)
12936 (if_then_else:SWI
12937 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12938 (match_dup 2)
12939 (match_dup 1)))]
12940 {
12941 operands[1] = force_reg (<MODE>mode, operands[1]);
12942 operands[2] = gen_reg_rtx (<MODE>mode);
12943 })
12944
12945 (define_expand "<code>tf2"
12946 [(set (match_operand:TF 0 "register_operand")
12947 (absneg:TF (match_operand:TF 1 "register_operand")))]
12948 "TARGET_SSE"
12949 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
12950
12951 (define_insn_and_split "*<code>tf2_1"
12952 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
12953 (absneg:TF
12954 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
12955 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
12956 "TARGET_SSE"
12957 "#"
12958 "&& reload_completed"
12959 [(set (match_dup 0)
12960 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
12961 {
12962 if (TARGET_AVX)
12963 {
12964 if (MEM_P (operands[1]))
12965 std::swap (operands[1], operands[2]);
12966 }
12967 else
12968 {
12969 if (operands_match_p (operands[0], operands[2]))
12970 std::swap (operands[1], operands[2]);
12971 }
12972 }
12973 [(set_attr "isa" "noavx,noavx,avx,avx")])
12974
12975 (define_insn_and_split "*nabstf2_1"
12976 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
12977 (neg:TF
12978 (abs:TF
12979 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
12980 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
12981 "TARGET_SSE"
12982 "#"
12983 "&& reload_completed"
12984 [(set (match_dup 0)
12985 (ior:TF (match_dup 1) (match_dup 2)))]
12986 {
12987 if (TARGET_AVX)
12988 {
12989 if (MEM_P (operands[1]))
12990 std::swap (operands[1], operands[2]);
12991 }
12992 else
12993 {
12994 if (operands_match_p (operands[0], operands[2]))
12995 std::swap (operands[1], operands[2]);
12996 }
12997 }
12998 [(set_attr "isa" "noavx,noavx,avx,avx")])
12999
13000 (define_expand "<code>hf2"
13001 [(set (match_operand:HF 0 "register_operand")
13002 (absneg:HF (match_operand:HF 1 "register_operand")))]
13003 "TARGET_AVX512FP16"
13004 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
13005
13006 (define_expand "<code><mode>2"
13007 [(set (match_operand:X87MODEF 0 "register_operand")
13008 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
13009 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13010 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13011
13012 ;; Changing of sign for FP values is doable using integer unit too.
13013 (define_insn "*<code><mode>2_i387_1"
13014 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
13015 (absneg:X87MODEF
13016 (match_operand:X87MODEF 1 "register_operand" "0,0")))
13017 (clobber (reg:CC FLAGS_REG))]
13018 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13019 "#")
13020
13021 (define_split
13022 [(set (match_operand:X87MODEF 0 "fp_register_operand")
13023 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
13024 (clobber (reg:CC FLAGS_REG))]
13025 "TARGET_80387 && reload_completed"
13026 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
13027
13028 (define_split
13029 [(set (match_operand:X87MODEF 0 "general_reg_operand")
13030 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
13031 (clobber (reg:CC FLAGS_REG))]
13032 "TARGET_80387 && reload_completed"
13033 [(const_int 0)]
13034 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13035
13036 (define_insn_and_split "*<code>hf2_1"
13037 [(set (match_operand:HF 0 "register_operand" "=Yv")
13038 (absneg:HF
13039 (match_operand:HF 1 "register_operand" "Yv")))
13040 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
13041 (clobber (reg:CC FLAGS_REG))]
13042 "TARGET_AVX512FP16"
13043 "#"
13044 "&& reload_completed"
13045 [(set (match_dup 0)
13046 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
13047 {
13048 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
13049 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
13050 })
13051
13052 (define_insn "*<code><mode>2_1"
13053 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
13054 (absneg:MODEF
13055 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
13056 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
13057 (clobber (reg:CC FLAGS_REG))]
13058 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13059 "#"
13060 [(set_attr "isa" "noavx,noavx,avx,*,*")
13061 (set (attr "enabled")
13062 (if_then_else
13063 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
13064 (if_then_else
13065 (eq_attr "alternative" "3,4")
13066 (symbol_ref "TARGET_MIX_SSE_I387")
13067 (const_string "*"))
13068 (if_then_else
13069 (eq_attr "alternative" "3,4")
13070 (symbol_ref "true")
13071 (symbol_ref "false"))))])
13072
13073 (define_split
13074 [(set (match_operand:MODEF 0 "sse_reg_operand")
13075 (absneg:MODEF
13076 (match_operand:MODEF 1 "sse_reg_operand")))
13077 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13078 (clobber (reg:CC FLAGS_REG))]
13079 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13080 && reload_completed"
13081 [(set (match_dup 0)
13082 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13083 {
13084 machine_mode mode = <MODE>mode;
13085 machine_mode vmode = <ssevecmodef>mode;
13086
13087 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13088 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13089
13090 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13091 std::swap (operands[1], operands[2]);
13092 })
13093
13094 (define_split
13095 [(set (match_operand:MODEF 0 "fp_register_operand")
13096 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13097 (use (match_operand 2))
13098 (clobber (reg:CC FLAGS_REG))]
13099 "TARGET_80387 && reload_completed"
13100 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13101
13102 (define_split
13103 [(set (match_operand:MODEF 0 "general_reg_operand")
13104 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13105 (use (match_operand 2))
13106 (clobber (reg:CC FLAGS_REG))]
13107 "TARGET_80387 && reload_completed"
13108 [(const_int 0)]
13109 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13110
13111 (define_insn_and_split "*nabs<mode>2_1"
13112 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13113 (neg:MODEF
13114 (abs:MODEF
13115 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13116 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13117 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13118 "#"
13119 "&& reload_completed"
13120 [(set (match_dup 0)
13121 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13122 {
13123 machine_mode mode = <MODE>mode;
13124 machine_mode vmode = <ssevecmodef>mode;
13125
13126 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13127 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13128
13129 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13130 std::swap (operands[1], operands[2]);
13131 }
13132 [(set_attr "isa" "noavx,noavx,avx")])
13133
13134 ;; Conditionalize these after reload. If they match before reload, we
13135 ;; lose the clobber and ability to use integer instructions.
13136
13137 (define_insn "*<code><mode>2_i387"
13138 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13139 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13140 "TARGET_80387 && reload_completed"
13141 "<absneg_mnemonic>"
13142 [(set_attr "type" "fsgn")
13143 (set_attr "mode" "<MODE>")])
13144
13145 ;; Copysign instructions
13146
13147 (define_expand "copysign<mode>3"
13148 [(match_operand:SSEMODEF 0 "register_operand")
13149 (match_operand:SSEMODEF 1 "nonmemory_operand")
13150 (match_operand:SSEMODEF 2 "register_operand")]
13151 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13152 || (TARGET_SSE && (<MODE>mode == TFmode))
13153 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13154 "ix86_expand_copysign (operands); DONE;")
13155
13156 (define_expand "xorsign<mode>3"
13157 [(match_operand:MODEFH 0 "register_operand")
13158 (match_operand:MODEFH 1 "register_operand")
13159 (match_operand:MODEFH 2 "register_operand")]
13160 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13161 || <MODE>mode == HFmode"
13162 {
13163 if (rtx_equal_p (operands[1], operands[2]))
13164 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13165 else
13166 ix86_expand_xorsign (operands);
13167 DONE;
13168 })
13169 \f
13170 ;; One complement instructions
13171
13172 (define_expand "one_cmpl<mode>2"
13173 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13174 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13175 ""
13176 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13177
13178 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13179 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13180 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13181 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13182 "#"
13183 "&& reload_completed"
13184 [(set (match_dup 0)
13185 (not:DWIH (match_dup 1)))
13186 (set (match_dup 2)
13187 (not:DWIH (match_dup 3)))]
13188 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13189
13190 (define_insn "*one_cmpl<mode>2_1"
13191 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13192 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13193 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13194 "@
13195 not{<imodesuffix>}\t%0
13196 #"
13197 [(set (attr "isa")
13198 (cond [(eq_attr "alternative" "1")
13199 (if_then_else (eq_attr "mode" "SI,DI")
13200 (const_string "avx512bw")
13201 (const_string "avx512f"))
13202 ]
13203 (const_string "*")))
13204 (set_attr "type" "negnot,msklog")
13205 (set_attr "mode" "<MODE>")])
13206
13207 (define_insn "*one_cmplsi2_1_zext"
13208 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13209 (zero_extend:DI
13210 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13211 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13212 "@
13213 not{l}\t%k0
13214 #"
13215 [(set_attr "isa" "x64,avx512bw")
13216 (set_attr "type" "negnot,msklog")
13217 (set_attr "mode" "SI,SI")])
13218
13219 (define_insn "*one_cmplqi2_1"
13220 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13221 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13222 "ix86_unary_operator_ok (NOT, QImode, operands)"
13223 "@
13224 not{b}\t%0
13225 not{l}\t%k0
13226 #"
13227 [(set_attr "isa" "*,*,avx512f")
13228 (set_attr "type" "negnot,negnot,msklog")
13229 (set (attr "mode")
13230 (cond [(eq_attr "alternative" "1")
13231 (const_string "SI")
13232 (and (eq_attr "alternative" "2")
13233 (match_test "!TARGET_AVX512DQ"))
13234 (const_string "HI")
13235 ]
13236 (const_string "QI")))
13237 ;; Potential partial reg stall on alternative 1.
13238 (set (attr "preferred_for_speed")
13239 (cond [(eq_attr "alternative" "1")
13240 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13241 (symbol_ref "true")))])
13242
13243 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13244 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13245 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13246 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13247 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13248 "@
13249 not{<imodesuffix>}\t%0
13250 #"
13251 "&& reload_completed"
13252 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13253 (set (strict_low_part (match_dup 0))
13254 (not:SWI12 (match_dup 0)))]
13255 ""
13256 [(set_attr "type" "negnot")
13257 (set_attr "mode" "<MODE>")])
13258
13259 (define_insn "*one_cmpl<mode>2_2"
13260 [(set (reg FLAGS_REG)
13261 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13262 (const_int 0)))
13263 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13264 (not:SWI (match_dup 1)))]
13265 "ix86_match_ccmode (insn, CCNOmode)
13266 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13267 "#"
13268 [(set_attr "type" "alu1")
13269 (set_attr "mode" "<MODE>")])
13270
13271 (define_split
13272 [(set (match_operand 0 "flags_reg_operand")
13273 (match_operator 2 "compare_operator"
13274 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13275 (const_int 0)]))
13276 (set (match_operand:SWI 1 "nonimmediate_operand")
13277 (not:SWI (match_dup 3)))]
13278 "ix86_match_ccmode (insn, CCNOmode)"
13279 [(parallel [(set (match_dup 0)
13280 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13281 (const_int 0)]))
13282 (set (match_dup 1)
13283 (xor:SWI (match_dup 3) (const_int -1)))])])
13284
13285 (define_insn "*one_cmplsi2_2_zext"
13286 [(set (reg FLAGS_REG)
13287 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13288 (const_int 0)))
13289 (set (match_operand:DI 0 "register_operand" "=r")
13290 (zero_extend:DI (not:SI (match_dup 1))))]
13291 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13292 && ix86_unary_operator_ok (NOT, SImode, operands)"
13293 "#"
13294 [(set_attr "type" "alu1")
13295 (set_attr "mode" "SI")])
13296
13297 (define_split
13298 [(set (match_operand 0 "flags_reg_operand")
13299 (match_operator 2 "compare_operator"
13300 [(not:SI (match_operand:SI 3 "register_operand"))
13301 (const_int 0)]))
13302 (set (match_operand:DI 1 "register_operand")
13303 (zero_extend:DI (not:SI (match_dup 3))))]
13304 "ix86_match_ccmode (insn, CCNOmode)"
13305 [(parallel [(set (match_dup 0)
13306 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13307 (const_int 0)]))
13308 (set (match_dup 1)
13309 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13310 \f
13311 ;; Shift instructions
13312
13313 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13314 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13315 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13316 ;; from the assembler input.
13317 ;;
13318 ;; This instruction shifts the target reg/mem as usual, but instead of
13319 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13320 ;; is a left shift double, bits are taken from the high order bits of
13321 ;; reg, else if the insn is a shift right double, bits are taken from the
13322 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13323 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13324 ;;
13325 ;; Since sh[lr]d does not change the `reg' operand, that is done
13326 ;; separately, making all shifts emit pairs of shift double and normal
13327 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13328 ;; support a 63 bit shift, each shift where the count is in a reg expands
13329 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13330 ;;
13331 ;; If the shift count is a constant, we need never emit more than one
13332 ;; shift pair, instead using moves and sign extension for counts greater
13333 ;; than 31.
13334
13335 (define_expand "ashl<mode>3"
13336 [(set (match_operand:SDWIM 0 "<shift_operand>")
13337 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13338 (match_operand:QI 2 "nonmemory_operand")))]
13339 ""
13340 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13341
13342 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13343 [(set (match_operand:<DWI> 0 "register_operand")
13344 (ashift:<DWI>
13345 (match_operand:<DWI> 1 "register_operand")
13346 (subreg:QI
13347 (and
13348 (match_operand 2 "int248_register_operand" "c")
13349 (match_operand 3 "const_int_operand")) 0)))
13350 (clobber (reg:CC FLAGS_REG))]
13351 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13352 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13353 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13354 && ix86_pre_reload_split ()"
13355 "#"
13356 "&& 1"
13357 [(parallel
13358 [(set (match_dup 6)
13359 (ior:DWIH (ashift:DWIH (match_dup 6)
13360 (and:QI (match_dup 2) (match_dup 8)))
13361 (subreg:DWIH
13362 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13363 (minus:QI (match_dup 9)
13364 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13365 (clobber (reg:CC FLAGS_REG))])
13366 (parallel
13367 [(set (match_dup 4)
13368 (ashift:DWIH (match_dup 5) (match_dup 2)))
13369 (clobber (reg:CC FLAGS_REG))])]
13370 {
13371 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13372 {
13373 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13374 operands[2] = gen_lowpart (QImode, operands[2]);
13375 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13376 operands[2]));
13377 DONE;
13378 }
13379
13380 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13381
13382 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13383 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13384
13385 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13386 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13387 {
13388 rtx xops[3];
13389 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13390 xops[1] = operands[2];
13391 xops[2] = GEN_INT (INTVAL (operands[3])
13392 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13393 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13394 operands[2] = xops[0];
13395 }
13396
13397 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13398 operands[2] = gen_lowpart (QImode, operands[2]);
13399
13400 if (!rtx_equal_p (operands[6], operands[7]))
13401 emit_move_insn (operands[6], operands[7]);
13402 })
13403
13404 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13405 [(set (match_operand:<DWI> 0 "register_operand")
13406 (ashift:<DWI>
13407 (match_operand:<DWI> 1 "register_operand")
13408 (and:QI
13409 (match_operand:QI 2 "register_operand" "c")
13410 (match_operand:QI 3 "const_int_operand"))))
13411 (clobber (reg:CC FLAGS_REG))]
13412 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13413 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13414 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13415 && ix86_pre_reload_split ()"
13416 "#"
13417 "&& 1"
13418 [(parallel
13419 [(set (match_dup 6)
13420 (ior:DWIH (ashift:DWIH (match_dup 6)
13421 (and:QI (match_dup 2) (match_dup 8)))
13422 (subreg:DWIH
13423 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13424 (minus:QI (match_dup 9)
13425 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13426 (clobber (reg:CC FLAGS_REG))])
13427 (parallel
13428 [(set (match_dup 4)
13429 (ashift:DWIH (match_dup 5) (match_dup 2)))
13430 (clobber (reg:CC FLAGS_REG))])]
13431 {
13432 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13433 {
13434 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13435 operands[2]));
13436 DONE;
13437 }
13438
13439 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13440
13441 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13442 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13443
13444 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13445 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13446 {
13447 rtx tem = gen_reg_rtx (QImode);
13448 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13449 operands[2] = tem;
13450 }
13451
13452 if (!rtx_equal_p (operands[6], operands[7]))
13453 emit_move_insn (operands[6], operands[7]);
13454 })
13455
13456 (define_insn "ashl<mode>3_doubleword"
13457 [(set (match_operand:DWI 0 "register_operand" "=&r")
13458 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13459 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13460 (clobber (reg:CC FLAGS_REG))]
13461 ""
13462 "#"
13463 [(set_attr "type" "multi")])
13464
13465 (define_split
13466 [(set (match_operand:DWI 0 "register_operand")
13467 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13468 (match_operand:QI 2 "nonmemory_operand")))
13469 (clobber (reg:CC FLAGS_REG))]
13470 "epilogue_completed"
13471 [(const_int 0)]
13472 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13473
13474 ;; By default we don't ask for a scratch register, because when DWImode
13475 ;; values are manipulated, registers are already at a premium. But if
13476 ;; we have one handy, we won't turn it away.
13477
13478 (define_peephole2
13479 [(match_scratch:DWIH 3 "r")
13480 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13481 (ashift:<DWI>
13482 (match_operand:<DWI> 1 "nonmemory_operand")
13483 (match_operand:QI 2 "nonmemory_operand")))
13484 (clobber (reg:CC FLAGS_REG))])
13485 (match_dup 3)]
13486 "TARGET_CMOVE"
13487 [(const_int 0)]
13488 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13489
13490 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13491 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13492 (ashift:<DWI>
13493 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13494 (match_operand:QI 2 "const_int_operand")))
13495 (clobber (reg:CC FLAGS_REG))]
13496 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13497 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13498 "#"
13499 "&& reload_completed"
13500 [(const_int 0)]
13501 {
13502 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13503 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13504 if (!rtx_equal_p (operands[3], operands[1]))
13505 emit_move_insn (operands[3], operands[1]);
13506 if (bits > 0)
13507 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13508 ix86_expand_clear (operands[0]);
13509 DONE;
13510 })
13511
13512 (define_insn "x86_64_shld"
13513 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13514 (ior:DI (ashift:DI (match_dup 0)
13515 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13516 (const_int 63)))
13517 (subreg:DI
13518 (lshiftrt:TI
13519 (zero_extend:TI
13520 (match_operand:DI 1 "register_operand" "r"))
13521 (minus:QI (const_int 64)
13522 (and:QI (match_dup 2) (const_int 63)))) 0)))
13523 (clobber (reg:CC FLAGS_REG))]
13524 "TARGET_64BIT"
13525 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13526 [(set_attr "type" "ishift")
13527 (set_attr "prefix_0f" "1")
13528 (set_attr "mode" "DI")
13529 (set_attr "athlon_decode" "vector")
13530 (set_attr "amdfam10_decode" "vector")
13531 (set_attr "bdver1_decode" "vector")])
13532
13533 (define_insn "x86_64_shld_1"
13534 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13535 (ior:DI (ashift:DI (match_dup 0)
13536 (match_operand:QI 2 "const_0_to_63_operand"))
13537 (subreg:DI
13538 (lshiftrt:TI
13539 (zero_extend:TI
13540 (match_operand:DI 1 "register_operand" "r"))
13541 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13542 (clobber (reg:CC FLAGS_REG))]
13543 "TARGET_64BIT
13544 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13545 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13546 [(set_attr "type" "ishift")
13547 (set_attr "prefix_0f" "1")
13548 (set_attr "mode" "DI")
13549 (set_attr "length_immediate" "1")
13550 (set_attr "athlon_decode" "vector")
13551 (set_attr "amdfam10_decode" "vector")
13552 (set_attr "bdver1_decode" "vector")])
13553
13554 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13555 [(set (match_operand:DI 0 "nonimmediate_operand")
13556 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13557 (match_operand:QI 2 "const_0_to_63_operand"))
13558 (lshiftrt:DI
13559 (match_operand:DI 1 "nonimmediate_operand")
13560 (match_operand:QI 3 "const_0_to_63_operand"))))
13561 (clobber (reg:CC FLAGS_REG))]
13562 "TARGET_64BIT
13563 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13564 && ix86_pre_reload_split ()"
13565 "#"
13566 "&& 1"
13567 [(const_int 0)]
13568 {
13569 if (rtx_equal_p (operands[4], operands[0]))
13570 {
13571 operands[1] = force_reg (DImode, operands[1]);
13572 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13573 }
13574 else if (rtx_equal_p (operands[1], operands[0]))
13575 {
13576 operands[4] = force_reg (DImode, operands[4]);
13577 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13578 }
13579 else
13580 {
13581 operands[1] = force_reg (DImode, operands[1]);
13582 rtx tmp = gen_reg_rtx (DImode);
13583 emit_move_insn (tmp, operands[4]);
13584 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13585 emit_move_insn (operands[0], tmp);
13586 }
13587 DONE;
13588 })
13589
13590 (define_insn_and_split "*x86_64_shld_2"
13591 [(set (match_operand:DI 0 "nonimmediate_operand")
13592 (ior:DI (ashift:DI (match_dup 0)
13593 (match_operand:QI 2 "nonmemory_operand"))
13594 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13595 (minus:QI (const_int 64) (match_dup 2)))))
13596 (clobber (reg:CC FLAGS_REG))]
13597 "TARGET_64BIT && ix86_pre_reload_split ()"
13598 "#"
13599 "&& 1"
13600 [(parallel [(set (match_dup 0)
13601 (ior:DI (ashift:DI (match_dup 0)
13602 (and:QI (match_dup 2) (const_int 63)))
13603 (subreg:DI
13604 (lshiftrt:TI
13605 (zero_extend:TI (match_dup 1))
13606 (minus:QI (const_int 64)
13607 (and:QI (match_dup 2)
13608 (const_int 63)))) 0)))
13609 (clobber (reg:CC FLAGS_REG))])])
13610
13611 (define_insn "x86_shld"
13612 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13613 (ior:SI (ashift:SI (match_dup 0)
13614 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13615 (const_int 31)))
13616 (subreg:SI
13617 (lshiftrt:DI
13618 (zero_extend:DI
13619 (match_operand:SI 1 "register_operand" "r"))
13620 (minus:QI (const_int 32)
13621 (and:QI (match_dup 2) (const_int 31)))) 0)))
13622 (clobber (reg:CC FLAGS_REG))]
13623 ""
13624 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13625 [(set_attr "type" "ishift")
13626 (set_attr "prefix_0f" "1")
13627 (set_attr "mode" "SI")
13628 (set_attr "pent_pair" "np")
13629 (set_attr "athlon_decode" "vector")
13630 (set_attr "amdfam10_decode" "vector")
13631 (set_attr "bdver1_decode" "vector")])
13632
13633 (define_insn "x86_shld_1"
13634 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13635 (ior:SI (ashift:SI (match_dup 0)
13636 (match_operand:QI 2 "const_0_to_31_operand"))
13637 (subreg:SI
13638 (lshiftrt:DI
13639 (zero_extend:DI
13640 (match_operand:SI 1 "register_operand" "r"))
13641 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13642 (clobber (reg:CC FLAGS_REG))]
13643 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13644 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13645 [(set_attr "type" "ishift")
13646 (set_attr "prefix_0f" "1")
13647 (set_attr "length_immediate" "1")
13648 (set_attr "mode" "SI")
13649 (set_attr "pent_pair" "np")
13650 (set_attr "athlon_decode" "vector")
13651 (set_attr "amdfam10_decode" "vector")
13652 (set_attr "bdver1_decode" "vector")])
13653
13654 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13655 [(set (match_operand:SI 0 "nonimmediate_operand")
13656 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13657 (match_operand:QI 2 "const_0_to_31_operand"))
13658 (lshiftrt:SI
13659 (match_operand:SI 1 "nonimmediate_operand")
13660 (match_operand:QI 3 "const_0_to_31_operand"))))
13661 (clobber (reg:CC FLAGS_REG))]
13662 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
13663 && ix86_pre_reload_split ()"
13664 "#"
13665 "&& 1"
13666 [(const_int 0)]
13667 {
13668 if (rtx_equal_p (operands[4], operands[0]))
13669 {
13670 operands[1] = force_reg (SImode, operands[1]);
13671 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13672 }
13673 else if (rtx_equal_p (operands[1], operands[0]))
13674 {
13675 operands[4] = force_reg (SImode, operands[4]);
13676 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13677 }
13678 else
13679 {
13680 operands[1] = force_reg (SImode, operands[1]);
13681 rtx tmp = gen_reg_rtx (SImode);
13682 emit_move_insn (tmp, operands[4]);
13683 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
13684 emit_move_insn (operands[0], tmp);
13685 }
13686 DONE;
13687 })
13688
13689 (define_insn_and_split "*x86_shld_2"
13690 [(set (match_operand:SI 0 "nonimmediate_operand")
13691 (ior:SI (ashift:SI (match_dup 0)
13692 (match_operand:QI 2 "nonmemory_operand"))
13693 (lshiftrt:SI (match_operand:SI 1 "register_operand")
13694 (minus:QI (const_int 32) (match_dup 2)))))
13695 (clobber (reg:CC FLAGS_REG))]
13696 "TARGET_64BIT && ix86_pre_reload_split ()"
13697 "#"
13698 "&& 1"
13699 [(parallel [(set (match_dup 0)
13700 (ior:SI (ashift:SI (match_dup 0)
13701 (and:QI (match_dup 2) (const_int 31)))
13702 (subreg:SI
13703 (lshiftrt:DI
13704 (zero_extend:DI (match_dup 1))
13705 (minus:QI (const_int 32)
13706 (and:QI (match_dup 2)
13707 (const_int 31)))) 0)))
13708 (clobber (reg:CC FLAGS_REG))])])
13709
13710 (define_expand "@x86_shift<mode>_adj_1"
13711 [(set (reg:CCZ FLAGS_REG)
13712 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
13713 (match_dup 4))
13714 (const_int 0)))
13715 (set (match_operand:SWI48 0 "register_operand")
13716 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13717 (match_operand:SWI48 1 "register_operand")
13718 (match_dup 0)))
13719 (set (match_dup 1)
13720 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13721 (match_operand:SWI48 3 "register_operand")
13722 (match_dup 1)))]
13723 "TARGET_CMOVE"
13724 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
13725
13726 (define_expand "@x86_shift<mode>_adj_2"
13727 [(use (match_operand:SWI48 0 "register_operand"))
13728 (use (match_operand:SWI48 1 "register_operand"))
13729 (use (match_operand:QI 2 "register_operand"))]
13730 ""
13731 {
13732 rtx_code_label *label = gen_label_rtx ();
13733 rtx tmp;
13734
13735 emit_insn (gen_testqi_ccz_1 (operands[2],
13736 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
13737
13738 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13739 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13740 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13741 gen_rtx_LABEL_REF (VOIDmode, label),
13742 pc_rtx);
13743 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
13744 JUMP_LABEL (tmp) = label;
13745
13746 emit_move_insn (operands[0], operands[1]);
13747 ix86_expand_clear (operands[1]);
13748
13749 emit_label (label);
13750 LABEL_NUSES (label) = 1;
13751
13752 DONE;
13753 })
13754
13755 ;; Avoid useless masking of count operand.
13756 (define_insn_and_split "*ashl<mode>3_mask"
13757 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13758 (ashift:SWI48
13759 (match_operand:SWI48 1 "nonimmediate_operand")
13760 (subreg:QI
13761 (and
13762 (match_operand 2 "int248_register_operand" "c,r")
13763 (match_operand 3 "const_int_operand")) 0)))
13764 (clobber (reg:CC FLAGS_REG))]
13765 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13766 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13767 == GET_MODE_BITSIZE (<MODE>mode)-1
13768 && ix86_pre_reload_split ()"
13769 "#"
13770 "&& 1"
13771 [(parallel
13772 [(set (match_dup 0)
13773 (ashift:SWI48 (match_dup 1)
13774 (match_dup 2)))
13775 (clobber (reg:CC FLAGS_REG))])]
13776 {
13777 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13778 operands[2] = gen_lowpart (QImode, operands[2]);
13779 }
13780 [(set_attr "isa" "*,bmi2")])
13781
13782 (define_insn_and_split "*ashl<mode>3_mask_1"
13783 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13784 (ashift:SWI48
13785 (match_operand:SWI48 1 "nonimmediate_operand")
13786 (and:QI
13787 (match_operand:QI 2 "register_operand" "c,r")
13788 (match_operand:QI 3 "const_int_operand"))))
13789 (clobber (reg:CC FLAGS_REG))]
13790 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13791 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13792 == GET_MODE_BITSIZE (<MODE>mode)-1
13793 && ix86_pre_reload_split ()"
13794 "#"
13795 "&& 1"
13796 [(parallel
13797 [(set (match_dup 0)
13798 (ashift:SWI48 (match_dup 1)
13799 (match_dup 2)))
13800 (clobber (reg:CC FLAGS_REG))])]
13801 ""
13802 [(set_attr "isa" "*,bmi2")])
13803
13804 (define_insn "*bmi2_ashl<mode>3_1"
13805 [(set (match_operand:SWI48 0 "register_operand" "=r")
13806 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13807 (match_operand:SWI48 2 "register_operand" "r")))]
13808 "TARGET_BMI2"
13809 "shlx\t{%2, %1, %0|%0, %1, %2}"
13810 [(set_attr "type" "ishiftx")
13811 (set_attr "mode" "<MODE>")])
13812
13813 (define_insn "*ashl<mode>3_1"
13814 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
13815 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
13816 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
13817 (clobber (reg:CC FLAGS_REG))]
13818 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
13819 {
13820 switch (get_attr_type (insn))
13821 {
13822 case TYPE_LEA:
13823 case TYPE_ISHIFTX:
13824 case TYPE_MSKLOG:
13825 return "#";
13826
13827 case TYPE_ALU:
13828 gcc_assert (operands[2] == const1_rtx);
13829 gcc_assert (rtx_equal_p (operands[0], operands[1]));
13830 return "add{<imodesuffix>}\t%0, %0";
13831
13832 default:
13833 if (operands[2] == const1_rtx
13834 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13835 return "sal{<imodesuffix>}\t%0";
13836 else
13837 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
13838 }
13839 }
13840 [(set_attr "isa" "*,*,bmi2,avx512bw")
13841 (set (attr "type")
13842 (cond [(eq_attr "alternative" "1")
13843 (const_string "lea")
13844 (eq_attr "alternative" "2")
13845 (const_string "ishiftx")
13846 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
13847 (match_operand 0 "register_operand"))
13848 (match_operand 2 "const1_operand"))
13849 (const_string "alu")
13850 (eq_attr "alternative" "3")
13851 (const_string "msklog")
13852 ]
13853 (const_string "ishift")))
13854 (set (attr "length_immediate")
13855 (if_then_else
13856 (ior (eq_attr "type" "alu")
13857 (and (eq_attr "type" "ishift")
13858 (and (match_operand 2 "const1_operand")
13859 (ior (match_test "TARGET_SHIFT1")
13860 (match_test "optimize_function_for_size_p (cfun)")))))
13861 (const_string "0")
13862 (const_string "*")))
13863 (set_attr "mode" "<MODE>")])
13864
13865 ;; Convert shift to the shiftx pattern to avoid flags dependency.
13866 (define_split
13867 [(set (match_operand:SWI48 0 "register_operand")
13868 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
13869 (match_operand:QI 2 "register_operand")))
13870 (clobber (reg:CC FLAGS_REG))]
13871 "TARGET_BMI2 && reload_completed"
13872 [(set (match_dup 0)
13873 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
13874 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
13875
13876 (define_insn "*bmi2_ashlsi3_1_zext"
13877 [(set (match_operand:DI 0 "register_operand" "=r")
13878 (zero_extend:DI
13879 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
13880 (match_operand:SI 2 "register_operand" "r"))))]
13881 "TARGET_64BIT && TARGET_BMI2"
13882 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
13883 [(set_attr "type" "ishiftx")
13884 (set_attr "mode" "SI")])
13885
13886 (define_insn "*ashlsi3_1_zext"
13887 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
13888 (zero_extend:DI
13889 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
13890 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
13891 (clobber (reg:CC FLAGS_REG))]
13892 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
13893 {
13894 switch (get_attr_type (insn))
13895 {
13896 case TYPE_LEA:
13897 case TYPE_ISHIFTX:
13898 return "#";
13899
13900 case TYPE_ALU:
13901 gcc_assert (operands[2] == const1_rtx);
13902 return "add{l}\t%k0, %k0";
13903
13904 default:
13905 if (operands[2] == const1_rtx
13906 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13907 return "sal{l}\t%k0";
13908 else
13909 return "sal{l}\t{%2, %k0|%k0, %2}";
13910 }
13911 }
13912 [(set_attr "isa" "*,*,bmi2")
13913 (set (attr "type")
13914 (cond [(eq_attr "alternative" "1")
13915 (const_string "lea")
13916 (eq_attr "alternative" "2")
13917 (const_string "ishiftx")
13918 (and (match_test "TARGET_DOUBLE_WITH_ADD")
13919 (match_operand 2 "const1_operand"))
13920 (const_string "alu")
13921 ]
13922 (const_string "ishift")))
13923 (set (attr "length_immediate")
13924 (if_then_else
13925 (ior (eq_attr "type" "alu")
13926 (and (eq_attr "type" "ishift")
13927 (and (match_operand 2 "const1_operand")
13928 (ior (match_test "TARGET_SHIFT1")
13929 (match_test "optimize_function_for_size_p (cfun)")))))
13930 (const_string "0")
13931 (const_string "*")))
13932 (set_attr "mode" "SI")])
13933
13934 ;; Convert shift to the shiftx pattern to avoid flags dependency.
13935 (define_split
13936 [(set (match_operand:DI 0 "register_operand")
13937 (zero_extend:DI
13938 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
13939 (match_operand:QI 2 "register_operand"))))
13940 (clobber (reg:CC FLAGS_REG))]
13941 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
13942 [(set (match_dup 0)
13943 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
13944 "operands[2] = gen_lowpart (SImode, operands[2]);")
13945
13946 (define_insn "*ashlhi3_1"
13947 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
13948 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
13949 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
13950 (clobber (reg:CC FLAGS_REG))]
13951 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
13952 {
13953 switch (get_attr_type (insn))
13954 {
13955 case TYPE_LEA:
13956 case TYPE_MSKLOG:
13957 return "#";
13958
13959 case TYPE_ALU:
13960 gcc_assert (operands[2] == const1_rtx);
13961 return "add{w}\t%0, %0";
13962
13963 default:
13964 if (operands[2] == const1_rtx
13965 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13966 return "sal{w}\t%0";
13967 else
13968 return "sal{w}\t{%2, %0|%0, %2}";
13969 }
13970 }
13971 [(set_attr "isa" "*,*,avx512f")
13972 (set (attr "type")
13973 (cond [(eq_attr "alternative" "1")
13974 (const_string "lea")
13975 (eq_attr "alternative" "2")
13976 (const_string "msklog")
13977 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
13978 (match_operand 0 "register_operand"))
13979 (match_operand 2 "const1_operand"))
13980 (const_string "alu")
13981 ]
13982 (const_string "ishift")))
13983 (set (attr "length_immediate")
13984 (if_then_else
13985 (ior (eq_attr "type" "alu")
13986 (and (eq_attr "type" "ishift")
13987 (and (match_operand 2 "const1_operand")
13988 (ior (match_test "TARGET_SHIFT1")
13989 (match_test "optimize_function_for_size_p (cfun)")))))
13990 (const_string "0")
13991 (const_string "*")))
13992 (set_attr "mode" "HI,SI,HI")])
13993
13994 (define_insn "*ashlqi3_1"
13995 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
13996 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
13997 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
13998 (clobber (reg:CC FLAGS_REG))]
13999 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
14000 {
14001 switch (get_attr_type (insn))
14002 {
14003 case TYPE_LEA:
14004 case TYPE_MSKLOG:
14005 return "#";
14006
14007 case TYPE_ALU:
14008 gcc_assert (operands[2] == const1_rtx);
14009 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
14010 return "add{l}\t%k0, %k0";
14011 else
14012 return "add{b}\t%0, %0";
14013
14014 default:
14015 if (operands[2] == const1_rtx
14016 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14017 {
14018 if (get_attr_mode (insn) == MODE_SI)
14019 return "sal{l}\t%k0";
14020 else
14021 return "sal{b}\t%0";
14022 }
14023 else
14024 {
14025 if (get_attr_mode (insn) == MODE_SI)
14026 return "sal{l}\t{%2, %k0|%k0, %2}";
14027 else
14028 return "sal{b}\t{%2, %0|%0, %2}";
14029 }
14030 }
14031 }
14032 [(set_attr "isa" "*,*,*,avx512dq")
14033 (set (attr "type")
14034 (cond [(eq_attr "alternative" "2")
14035 (const_string "lea")
14036 (eq_attr "alternative" "3")
14037 (const_string "msklog")
14038 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14039 (match_operand 0 "register_operand"))
14040 (match_operand 2 "const1_operand"))
14041 (const_string "alu")
14042 ]
14043 (const_string "ishift")))
14044 (set (attr "length_immediate")
14045 (if_then_else
14046 (ior (eq_attr "type" "alu")
14047 (and (eq_attr "type" "ishift")
14048 (and (match_operand 2 "const1_operand")
14049 (ior (match_test "TARGET_SHIFT1")
14050 (match_test "optimize_function_for_size_p (cfun)")))))
14051 (const_string "0")
14052 (const_string "*")))
14053 (set_attr "mode" "QI,SI,SI,QI")
14054 ;; Potential partial reg stall on alternative 1.
14055 (set (attr "preferred_for_speed")
14056 (cond [(eq_attr "alternative" "1")
14057 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
14058 (symbol_ref "true")))])
14059
14060 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14061 (define_insn_and_split "*ashl<mode>3_1_slp"
14062 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14063 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14064 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14065 (clobber (reg:CC FLAGS_REG))]
14066 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14067 {
14068 if (which_alternative)
14069 return "#";
14070
14071 switch (get_attr_type (insn))
14072 {
14073 case TYPE_ALU:
14074 gcc_assert (operands[2] == const1_rtx);
14075 return "add{<imodesuffix>}\t%0, %0";
14076
14077 default:
14078 if (operands[2] == const1_rtx
14079 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14080 return "sal{<imodesuffix>}\t%0";
14081 else
14082 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14083 }
14084 }
14085 "&& reload_completed"
14086 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14087 (parallel
14088 [(set (strict_low_part (match_dup 0))
14089 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14090 (clobber (reg:CC FLAGS_REG))])]
14091 ""
14092 [(set (attr "type")
14093 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14094 (match_operand 2 "const1_operand"))
14095 (const_string "alu")
14096 ]
14097 (const_string "ishift")))
14098 (set (attr "length_immediate")
14099 (if_then_else
14100 (ior (eq_attr "type" "alu")
14101 (and (eq_attr "type" "ishift")
14102 (and (match_operand 2 "const1_operand")
14103 (ior (match_test "TARGET_SHIFT1")
14104 (match_test "optimize_function_for_size_p (cfun)")))))
14105 (const_string "0")
14106 (const_string "*")))
14107 (set_attr "mode" "<MODE>")])
14108
14109 ;; Convert ashift to the lea pattern to avoid flags dependency.
14110 (define_split
14111 [(set (match_operand:SWI 0 "general_reg_operand")
14112 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14113 (match_operand 2 "const_0_to_3_operand")))
14114 (clobber (reg:CC FLAGS_REG))]
14115 "reload_completed
14116 && REGNO (operands[0]) != REGNO (operands[1])"
14117 [(set (match_dup 0)
14118 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14119 {
14120 if (<MODE>mode != <LEAMODE>mode)
14121 {
14122 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14123 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14124 }
14125 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14126 })
14127
14128 ;; Convert ashift to the lea pattern to avoid flags dependency.
14129 (define_split
14130 [(set (match_operand:DI 0 "general_reg_operand")
14131 (zero_extend:DI
14132 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14133 (match_operand 2 "const_0_to_3_operand"))))
14134 (clobber (reg:CC FLAGS_REG))]
14135 "TARGET_64BIT && reload_completed
14136 && REGNO (operands[0]) != REGNO (operands[1])"
14137 [(set (match_dup 0)
14138 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14139 {
14140 operands[1] = gen_lowpart (SImode, operands[1]);
14141 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14142 })
14143
14144 ;; This pattern can't accept a variable shift count, since shifts by
14145 ;; zero don't affect the flags. We assume that shifts by constant
14146 ;; zero are optimized away.
14147 (define_insn "*ashl<mode>3_cmp"
14148 [(set (reg FLAGS_REG)
14149 (compare
14150 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14151 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14152 (const_int 0)))
14153 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14154 (ashift:SWI (match_dup 1) (match_dup 2)))]
14155 "(optimize_function_for_size_p (cfun)
14156 || !TARGET_PARTIAL_FLAG_REG_STALL
14157 || (operands[2] == const1_rtx
14158 && (TARGET_SHIFT1
14159 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14160 && ix86_match_ccmode (insn, CCGOCmode)
14161 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14162 {
14163 switch (get_attr_type (insn))
14164 {
14165 case TYPE_ALU:
14166 gcc_assert (operands[2] == const1_rtx);
14167 return "add{<imodesuffix>}\t%0, %0";
14168
14169 default:
14170 if (operands[2] == const1_rtx
14171 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14172 return "sal{<imodesuffix>}\t%0";
14173 else
14174 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14175 }
14176 }
14177 [(set (attr "type")
14178 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14179 (match_operand 0 "register_operand"))
14180 (match_operand 2 "const1_operand"))
14181 (const_string "alu")
14182 ]
14183 (const_string "ishift")))
14184 (set (attr "length_immediate")
14185 (if_then_else
14186 (ior (eq_attr "type" "alu")
14187 (and (eq_attr "type" "ishift")
14188 (and (match_operand 2 "const1_operand")
14189 (ior (match_test "TARGET_SHIFT1")
14190 (match_test "optimize_function_for_size_p (cfun)")))))
14191 (const_string "0")
14192 (const_string "*")))
14193 (set_attr "mode" "<MODE>")])
14194
14195 (define_insn "*ashlsi3_cmp_zext"
14196 [(set (reg FLAGS_REG)
14197 (compare
14198 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14199 (match_operand:QI 2 "const_1_to_31_operand"))
14200 (const_int 0)))
14201 (set (match_operand:DI 0 "register_operand" "=r")
14202 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14203 "TARGET_64BIT
14204 && (optimize_function_for_size_p (cfun)
14205 || !TARGET_PARTIAL_FLAG_REG_STALL
14206 || (operands[2] == const1_rtx
14207 && (TARGET_SHIFT1
14208 || TARGET_DOUBLE_WITH_ADD)))
14209 && ix86_match_ccmode (insn, CCGOCmode)
14210 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14211 {
14212 switch (get_attr_type (insn))
14213 {
14214 case TYPE_ALU:
14215 gcc_assert (operands[2] == const1_rtx);
14216 return "add{l}\t%k0, %k0";
14217
14218 default:
14219 if (operands[2] == const1_rtx
14220 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14221 return "sal{l}\t%k0";
14222 else
14223 return "sal{l}\t{%2, %k0|%k0, %2}";
14224 }
14225 }
14226 [(set (attr "type")
14227 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14228 (match_operand 2 "const1_operand"))
14229 (const_string "alu")
14230 ]
14231 (const_string "ishift")))
14232 (set (attr "length_immediate")
14233 (if_then_else
14234 (ior (eq_attr "type" "alu")
14235 (and (eq_attr "type" "ishift")
14236 (and (match_operand 2 "const1_operand")
14237 (ior (match_test "TARGET_SHIFT1")
14238 (match_test "optimize_function_for_size_p (cfun)")))))
14239 (const_string "0")
14240 (const_string "*")))
14241 (set_attr "mode" "SI")])
14242
14243 (define_insn "*ashl<mode>3_cconly"
14244 [(set (reg FLAGS_REG)
14245 (compare
14246 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14247 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14248 (const_int 0)))
14249 (clobber (match_scratch:SWI 0 "=<r>"))]
14250 "(optimize_function_for_size_p (cfun)
14251 || !TARGET_PARTIAL_FLAG_REG_STALL
14252 || (operands[2] == const1_rtx
14253 && (TARGET_SHIFT1
14254 || TARGET_DOUBLE_WITH_ADD)))
14255 && ix86_match_ccmode (insn, CCGOCmode)"
14256 {
14257 switch (get_attr_type (insn))
14258 {
14259 case TYPE_ALU:
14260 gcc_assert (operands[2] == const1_rtx);
14261 return "add{<imodesuffix>}\t%0, %0";
14262
14263 default:
14264 if (operands[2] == const1_rtx
14265 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14266 return "sal{<imodesuffix>}\t%0";
14267 else
14268 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14269 }
14270 }
14271 [(set (attr "type")
14272 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14273 (match_operand 0 "register_operand"))
14274 (match_operand 2 "const1_operand"))
14275 (const_string "alu")
14276 ]
14277 (const_string "ishift")))
14278 (set (attr "length_immediate")
14279 (if_then_else
14280 (ior (eq_attr "type" "alu")
14281 (and (eq_attr "type" "ishift")
14282 (and (match_operand 2 "const1_operand")
14283 (ior (match_test "TARGET_SHIFT1")
14284 (match_test "optimize_function_for_size_p (cfun)")))))
14285 (const_string "0")
14286 (const_string "*")))
14287 (set_attr "mode" "<MODE>")])
14288
14289 (define_insn "*ashlqi_ext<mode>_2"
14290 [(set (zero_extract:SWI248
14291 (match_operand 0 "int248_register_operand" "+Q")
14292 (const_int 8)
14293 (const_int 8))
14294 (subreg:SWI248
14295 (ashift:QI
14296 (subreg:QI
14297 (match_operator:SWI248 3 "extract_operator"
14298 [(match_operand 1 "int248_register_operand" "0")
14299 (const_int 8)
14300 (const_int 8)]) 0)
14301 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
14302 (clobber (reg:CC FLAGS_REG))]
14303 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
14304 rtx_equal_p (operands[0], operands[1])"
14305 {
14306 switch (get_attr_type (insn))
14307 {
14308 case TYPE_ALU:
14309 gcc_assert (operands[2] == const1_rtx);
14310 return "add{b}\t%h0, %h0";
14311
14312 default:
14313 if (operands[2] == const1_rtx
14314 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14315 return "sal{b}\t%h0";
14316 else
14317 return "sal{b}\t{%2, %h0|%h0, %2}";
14318 }
14319 }
14320 [(set (attr "type")
14321 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14322 (match_operand 2 "const1_operand"))
14323 (const_string "alu")
14324 ]
14325 (const_string "ishift")))
14326 (set (attr "length_immediate")
14327 (if_then_else
14328 (ior (eq_attr "type" "alu")
14329 (and (eq_attr "type" "ishift")
14330 (and (match_operand 2 "const1_operand")
14331 (ior (match_test "TARGET_SHIFT1")
14332 (match_test "optimize_function_for_size_p (cfun)")))))
14333 (const_string "0")
14334 (const_string "*")))
14335 (set_attr "mode" "QI")])
14336
14337 ;; See comment above `ashl<mode>3' about how this works.
14338
14339 (define_expand "<insn><mode>3"
14340 [(set (match_operand:SDWIM 0 "<shift_operand>")
14341 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14342 (match_operand:QI 2 "nonmemory_operand")))]
14343 ""
14344 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14345
14346 ;; Avoid useless masking of count operand.
14347 (define_insn_and_split "*<insn><mode>3_mask"
14348 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14349 (any_shiftrt:SWI48
14350 (match_operand:SWI48 1 "nonimmediate_operand")
14351 (subreg:QI
14352 (and
14353 (match_operand 2 "int248_register_operand" "c,r")
14354 (match_operand 3 "const_int_operand")) 0)))
14355 (clobber (reg:CC FLAGS_REG))]
14356 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14357 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14358 == GET_MODE_BITSIZE (<MODE>mode)-1
14359 && ix86_pre_reload_split ()"
14360 "#"
14361 "&& 1"
14362 [(parallel
14363 [(set (match_dup 0)
14364 (any_shiftrt:SWI48 (match_dup 1)
14365 (match_dup 2)))
14366 (clobber (reg:CC FLAGS_REG))])]
14367 {
14368 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14369 operands[2] = gen_lowpart (QImode, operands[2]);
14370 }
14371 [(set_attr "isa" "*,bmi2")])
14372
14373 (define_insn_and_split "*<insn><mode>3_mask_1"
14374 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14375 (any_shiftrt:SWI48
14376 (match_operand:SWI48 1 "nonimmediate_operand")
14377 (and:QI
14378 (match_operand:QI 2 "register_operand" "c,r")
14379 (match_operand:QI 3 "const_int_operand"))))
14380 (clobber (reg:CC FLAGS_REG))]
14381 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14382 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14383 == GET_MODE_BITSIZE (<MODE>mode)-1
14384 && ix86_pre_reload_split ()"
14385 "#"
14386 "&& 1"
14387 [(parallel
14388 [(set (match_dup 0)
14389 (any_shiftrt:SWI48 (match_dup 1)
14390 (match_dup 2)))
14391 (clobber (reg:CC FLAGS_REG))])]
14392 ""
14393 [(set_attr "isa" "*,bmi2")])
14394
14395 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14396 [(set (match_operand:<DWI> 0 "register_operand")
14397 (any_shiftrt:<DWI>
14398 (match_operand:<DWI> 1 "register_operand")
14399 (subreg:QI
14400 (and
14401 (match_operand 2 "int248_register_operand" "c")
14402 (match_operand 3 "const_int_operand")) 0)))
14403 (clobber (reg:CC FLAGS_REG))]
14404 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14405 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14406 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14407 && ix86_pre_reload_split ()"
14408 "#"
14409 "&& 1"
14410 [(parallel
14411 [(set (match_dup 4)
14412 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14413 (and:QI (match_dup 2) (match_dup 8)))
14414 (subreg:DWIH
14415 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14416 (minus:QI (match_dup 9)
14417 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14418 (clobber (reg:CC FLAGS_REG))])
14419 (parallel
14420 [(set (match_dup 6)
14421 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14422 (clobber (reg:CC FLAGS_REG))])]
14423 {
14424 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14425 {
14426 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14427 operands[2] = gen_lowpart (QImode, operands[2]);
14428 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14429 operands[2]));
14430 DONE;
14431 }
14432
14433 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14434
14435 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14436 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14437
14438 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14439 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14440 {
14441 rtx xops[3];
14442 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14443 xops[1] = operands[2];
14444 xops[2] = GEN_INT (INTVAL (operands[3])
14445 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14446 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14447 operands[2] = xops[0];
14448 }
14449
14450 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14451 operands[2] = gen_lowpart (QImode, operands[2]);
14452
14453 if (!rtx_equal_p (operands[4], operands[5]))
14454 emit_move_insn (operands[4], operands[5]);
14455 })
14456
14457 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14458 [(set (match_operand:<DWI> 0 "register_operand")
14459 (any_shiftrt:<DWI>
14460 (match_operand:<DWI> 1 "register_operand")
14461 (and:QI
14462 (match_operand:QI 2 "register_operand" "c")
14463 (match_operand:QI 3 "const_int_operand"))))
14464 (clobber (reg:CC FLAGS_REG))]
14465 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14466 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14467 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14468 && ix86_pre_reload_split ()"
14469 "#"
14470 "&& 1"
14471 [(parallel
14472 [(set (match_dup 4)
14473 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14474 (and:QI (match_dup 2) (match_dup 8)))
14475 (subreg:DWIH
14476 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14477 (minus:QI (match_dup 9)
14478 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14479 (clobber (reg:CC FLAGS_REG))])
14480 (parallel
14481 [(set (match_dup 6)
14482 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14483 (clobber (reg:CC FLAGS_REG))])]
14484 {
14485 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14486 {
14487 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14488 operands[2]));
14489 DONE;
14490 }
14491
14492 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14493
14494 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14495 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14496
14497 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14498 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14499 {
14500 rtx tem = gen_reg_rtx (QImode);
14501 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14502 operands[2] = tem;
14503 }
14504
14505 if (!rtx_equal_p (operands[4], operands[5]))
14506 emit_move_insn (operands[4], operands[5]);
14507 })
14508
14509 (define_insn_and_split "<insn><mode>3_doubleword"
14510 [(set (match_operand:DWI 0 "register_operand" "=&r")
14511 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14512 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14513 (clobber (reg:CC FLAGS_REG))]
14514 ""
14515 "#"
14516 "epilogue_completed"
14517 [(const_int 0)]
14518 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14519 [(set_attr "type" "multi")])
14520
14521 ;; By default we don't ask for a scratch register, because when DWImode
14522 ;; values are manipulated, registers are already at a premium. But if
14523 ;; we have one handy, we won't turn it away.
14524
14525 (define_peephole2
14526 [(match_scratch:DWIH 3 "r")
14527 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14528 (any_shiftrt:<DWI>
14529 (match_operand:<DWI> 1 "register_operand")
14530 (match_operand:QI 2 "nonmemory_operand")))
14531 (clobber (reg:CC FLAGS_REG))])
14532 (match_dup 3)]
14533 "TARGET_CMOVE"
14534 [(const_int 0)]
14535 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14536
14537 (define_insn "x86_64_shrd"
14538 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14539 (ior:DI (lshiftrt:DI (match_dup 0)
14540 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14541 (const_int 63)))
14542 (subreg:DI
14543 (ashift:TI
14544 (zero_extend:TI
14545 (match_operand:DI 1 "register_operand" "r"))
14546 (minus:QI (const_int 64)
14547 (and:QI (match_dup 2) (const_int 63)))) 0)))
14548 (clobber (reg:CC FLAGS_REG))]
14549 "TARGET_64BIT"
14550 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14551 [(set_attr "type" "ishift")
14552 (set_attr "prefix_0f" "1")
14553 (set_attr "mode" "DI")
14554 (set_attr "athlon_decode" "vector")
14555 (set_attr "amdfam10_decode" "vector")
14556 (set_attr "bdver1_decode" "vector")])
14557
14558 (define_insn "x86_64_shrd_1"
14559 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14560 (ior:DI (lshiftrt:DI (match_dup 0)
14561 (match_operand:QI 2 "const_0_to_63_operand"))
14562 (subreg:DI
14563 (ashift:TI
14564 (zero_extend:TI
14565 (match_operand:DI 1 "register_operand" "r"))
14566 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14567 (clobber (reg:CC FLAGS_REG))]
14568 "TARGET_64BIT
14569 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14570 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14571 [(set_attr "type" "ishift")
14572 (set_attr "prefix_0f" "1")
14573 (set_attr "length_immediate" "1")
14574 (set_attr "mode" "DI")
14575 (set_attr "athlon_decode" "vector")
14576 (set_attr "amdfam10_decode" "vector")
14577 (set_attr "bdver1_decode" "vector")])
14578
14579 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14580 [(set (match_operand:DI 0 "nonimmediate_operand")
14581 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14582 (match_operand:QI 2 "const_0_to_63_operand"))
14583 (ashift:DI
14584 (match_operand:DI 1 "nonimmediate_operand")
14585 (match_operand:QI 3 "const_0_to_63_operand"))))
14586 (clobber (reg:CC FLAGS_REG))]
14587 "TARGET_64BIT
14588 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14589 && ix86_pre_reload_split ()"
14590 "#"
14591 "&& 1"
14592 [(const_int 0)]
14593 {
14594 if (rtx_equal_p (operands[4], operands[0]))
14595 {
14596 operands[1] = force_reg (DImode, operands[1]);
14597 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14598 }
14599 else if (rtx_equal_p (operands[1], operands[0]))
14600 {
14601 operands[4] = force_reg (DImode, operands[4]);
14602 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14603 }
14604 else
14605 {
14606 operands[1] = force_reg (DImode, operands[1]);
14607 rtx tmp = gen_reg_rtx (DImode);
14608 emit_move_insn (tmp, operands[4]);
14609 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14610 emit_move_insn (operands[0], tmp);
14611 }
14612 DONE;
14613 })
14614
14615 (define_insn_and_split "*x86_64_shrd_2"
14616 [(set (match_operand:DI 0 "nonimmediate_operand")
14617 (ior:DI (lshiftrt:DI (match_dup 0)
14618 (match_operand:QI 2 "nonmemory_operand"))
14619 (ashift:DI (match_operand:DI 1 "register_operand")
14620 (minus:QI (const_int 64) (match_dup 2)))))
14621 (clobber (reg:CC FLAGS_REG))]
14622 "TARGET_64BIT && ix86_pre_reload_split ()"
14623 "#"
14624 "&& 1"
14625 [(parallel [(set (match_dup 0)
14626 (ior:DI (lshiftrt:DI (match_dup 0)
14627 (and:QI (match_dup 2) (const_int 63)))
14628 (subreg:DI
14629 (ashift:TI
14630 (zero_extend:TI (match_dup 1))
14631 (minus:QI (const_int 64)
14632 (and:QI (match_dup 2)
14633 (const_int 63)))) 0)))
14634 (clobber (reg:CC FLAGS_REG))])])
14635
14636 (define_insn "x86_shrd"
14637 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14638 (ior:SI (lshiftrt:SI (match_dup 0)
14639 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14640 (const_int 31)))
14641 (subreg:SI
14642 (ashift:DI
14643 (zero_extend:DI
14644 (match_operand:SI 1 "register_operand" "r"))
14645 (minus:QI (const_int 32)
14646 (and:QI (match_dup 2) (const_int 31)))) 0)))
14647 (clobber (reg:CC FLAGS_REG))]
14648 ""
14649 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
14650 [(set_attr "type" "ishift")
14651 (set_attr "prefix_0f" "1")
14652 (set_attr "mode" "SI")
14653 (set_attr "pent_pair" "np")
14654 (set_attr "athlon_decode" "vector")
14655 (set_attr "amdfam10_decode" "vector")
14656 (set_attr "bdver1_decode" "vector")])
14657
14658 (define_insn "x86_shrd_1"
14659 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14660 (ior:SI (lshiftrt:SI (match_dup 0)
14661 (match_operand:QI 2 "const_0_to_31_operand"))
14662 (subreg:SI
14663 (ashift:DI
14664 (zero_extend:DI
14665 (match_operand:SI 1 "register_operand" "r"))
14666 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14667 (clobber (reg:CC FLAGS_REG))]
14668 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14669 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
14670 [(set_attr "type" "ishift")
14671 (set_attr "prefix_0f" "1")
14672 (set_attr "length_immediate" "1")
14673 (set_attr "mode" "SI")
14674 (set_attr "pent_pair" "np")
14675 (set_attr "athlon_decode" "vector")
14676 (set_attr "amdfam10_decode" "vector")
14677 (set_attr "bdver1_decode" "vector")])
14678
14679 (define_insn_and_split "*x86_shrd_shld_1_nozext"
14680 [(set (match_operand:SI 0 "nonimmediate_operand")
14681 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
14682 (match_operand:QI 2 "const_0_to_31_operand"))
14683 (ashift:SI
14684 (match_operand:SI 1 "nonimmediate_operand")
14685 (match_operand:QI 3 "const_0_to_31_operand"))))
14686 (clobber (reg:CC FLAGS_REG))]
14687 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14688 && ix86_pre_reload_split ()"
14689 "#"
14690 "&& 1"
14691 [(const_int 0)]
14692 {
14693 if (rtx_equal_p (operands[4], operands[0]))
14694 {
14695 operands[1] = force_reg (SImode, operands[1]);
14696 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14697 }
14698 else if (rtx_equal_p (operands[1], operands[0]))
14699 {
14700 operands[4] = force_reg (SImode, operands[4]);
14701 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14702 }
14703 else
14704 {
14705 operands[1] = force_reg (SImode, operands[1]);
14706 rtx tmp = gen_reg_rtx (SImode);
14707 emit_move_insn (tmp, operands[4]);
14708 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14709 emit_move_insn (operands[0], tmp);
14710 }
14711 DONE;
14712 })
14713
14714 (define_insn_and_split "*x86_shrd_2"
14715 [(set (match_operand:SI 0 "nonimmediate_operand")
14716 (ior:SI (lshiftrt:SI (match_dup 0)
14717 (match_operand:QI 2 "nonmemory_operand"))
14718 (ashift:SI (match_operand:SI 1 "register_operand")
14719 (minus:QI (const_int 32) (match_dup 2)))))
14720 (clobber (reg:CC FLAGS_REG))]
14721 "TARGET_64BIT && ix86_pre_reload_split ()"
14722 "#"
14723 "&& 1"
14724 [(parallel [(set (match_dup 0)
14725 (ior:SI (lshiftrt:SI (match_dup 0)
14726 (and:QI (match_dup 2) (const_int 31)))
14727 (subreg:SI
14728 (ashift:DI
14729 (zero_extend:DI (match_dup 1))
14730 (minus:QI (const_int 32)
14731 (and:QI (match_dup 2)
14732 (const_int 31)))) 0)))
14733 (clobber (reg:CC FLAGS_REG))])])
14734
14735 ;; Base name for insn mnemonic.
14736 (define_mode_attr cvt_mnemonic
14737 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
14738
14739 (define_insn "ashr<mode>3_cvt"
14740 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
14741 (ashiftrt:SWI48
14742 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
14743 (match_operand:QI 2 "const_int_operand")))
14744 (clobber (reg:CC FLAGS_REG))]
14745 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
14746 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14747 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14748 "@
14749 <cvt_mnemonic>
14750 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
14751 [(set_attr "type" "imovx,ishift")
14752 (set_attr "prefix_0f" "0,*")
14753 (set_attr "length_immediate" "0,*")
14754 (set_attr "modrm" "0,1")
14755 (set_attr "mode" "<MODE>")])
14756
14757 (define_insn "*ashrsi3_cvt_zext"
14758 [(set (match_operand:DI 0 "register_operand" "=*d,r")
14759 (zero_extend:DI
14760 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
14761 (match_operand:QI 2 "const_int_operand"))))
14762 (clobber (reg:CC FLAGS_REG))]
14763 "TARGET_64BIT && INTVAL (operands[2]) == 31
14764 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14765 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
14766 "@
14767 {cltd|cdq}
14768 sar{l}\t{%2, %k0|%k0, %2}"
14769 [(set_attr "type" "imovx,ishift")
14770 (set_attr "prefix_0f" "0,*")
14771 (set_attr "length_immediate" "0,*")
14772 (set_attr "modrm" "0,1")
14773 (set_attr "mode" "SI")])
14774
14775 (define_expand "@x86_shift<mode>_adj_3"
14776 [(use (match_operand:SWI48 0 "register_operand"))
14777 (use (match_operand:SWI48 1 "register_operand"))
14778 (use (match_operand:QI 2 "register_operand"))]
14779 ""
14780 {
14781 rtx_code_label *label = gen_label_rtx ();
14782 rtx tmp;
14783
14784 emit_insn (gen_testqi_ccz_1 (operands[2],
14785 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14786
14787 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14788 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14789 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14790 gen_rtx_LABEL_REF (VOIDmode, label),
14791 pc_rtx);
14792 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14793 JUMP_LABEL (tmp) = label;
14794
14795 emit_move_insn (operands[0], operands[1]);
14796 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
14797 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
14798 emit_label (label);
14799 LABEL_NUSES (label) = 1;
14800
14801 DONE;
14802 })
14803
14804 (define_insn "*bmi2_<insn><mode>3_1"
14805 [(set (match_operand:SWI48 0 "register_operand" "=r")
14806 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14807 (match_operand:SWI48 2 "register_operand" "r")))]
14808 "TARGET_BMI2"
14809 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
14810 [(set_attr "type" "ishiftx")
14811 (set_attr "mode" "<MODE>")])
14812
14813 (define_insn "*ashr<mode>3_1"
14814 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
14815 (ashiftrt:SWI48
14816 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
14817 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
14818 (clobber (reg:CC FLAGS_REG))]
14819 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14820 {
14821 switch (get_attr_type (insn))
14822 {
14823 case TYPE_ISHIFTX:
14824 return "#";
14825
14826 default:
14827 if (operands[2] == const1_rtx
14828 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14829 return "sar{<imodesuffix>}\t%0";
14830 else
14831 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
14832 }
14833 }
14834 [(set_attr "isa" "*,bmi2")
14835 (set_attr "type" "ishift,ishiftx")
14836 (set (attr "length_immediate")
14837 (if_then_else
14838 (and (match_operand 2 "const1_operand")
14839 (ior (match_test "TARGET_SHIFT1")
14840 (match_test "optimize_function_for_size_p (cfun)")))
14841 (const_string "0")
14842 (const_string "*")))
14843 (set_attr "mode" "<MODE>")])
14844
14845 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
14846 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
14847 (define_insn_and_split "*highpartdisi2"
14848 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
14849 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
14850 (const_int 32)))
14851 (clobber (reg:CC FLAGS_REG))]
14852 "TARGET_64BIT"
14853 "#"
14854 "&& reload_completed"
14855 [(parallel
14856 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
14857 (clobber (reg:CC FLAGS_REG))])]
14858 {
14859 if (SSE_REG_P (operands[0]))
14860 {
14861 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
14862 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
14863 const1_rtx, const1_rtx,
14864 GEN_INT (5), GEN_INT (5)));
14865 DONE;
14866 }
14867 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
14868 })
14869
14870 (define_insn "*lshr<mode>3_1"
14871 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
14872 (lshiftrt:SWI48
14873 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
14874 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
14875 (clobber (reg:CC FLAGS_REG))]
14876 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
14877 {
14878 switch (get_attr_type (insn))
14879 {
14880 case TYPE_ISHIFTX:
14881 case TYPE_MSKLOG:
14882 return "#";
14883
14884 default:
14885 if (operands[2] == const1_rtx
14886 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14887 return "shr{<imodesuffix>}\t%0";
14888 else
14889 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
14890 }
14891 }
14892 [(set_attr "isa" "*,bmi2,avx512bw")
14893 (set_attr "type" "ishift,ishiftx,msklog")
14894 (set (attr "length_immediate")
14895 (if_then_else
14896 (and (and (match_operand 2 "const1_operand")
14897 (eq_attr "alternative" "0"))
14898 (ior (match_test "TARGET_SHIFT1")
14899 (match_test "optimize_function_for_size_p (cfun)")))
14900 (const_string "0")
14901 (const_string "*")))
14902 (set_attr "mode" "<MODE>")])
14903
14904 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14905 (define_split
14906 [(set (match_operand:SWI48 0 "register_operand")
14907 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14908 (match_operand:QI 2 "register_operand")))
14909 (clobber (reg:CC FLAGS_REG))]
14910 "TARGET_BMI2 && reload_completed"
14911 [(set (match_dup 0)
14912 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
14913 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14914
14915 (define_insn "*bmi2_<insn>si3_1_zext"
14916 [(set (match_operand:DI 0 "register_operand" "=r")
14917 (zero_extend:DI
14918 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14919 (match_operand:SI 2 "register_operand" "r"))))]
14920 "TARGET_64BIT && TARGET_BMI2"
14921 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
14922 [(set_attr "type" "ishiftx")
14923 (set_attr "mode" "SI")])
14924
14925 (define_insn "*<insn>si3_1_zext"
14926 [(set (match_operand:DI 0 "register_operand" "=r,r")
14927 (zero_extend:DI
14928 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
14929 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
14930 (clobber (reg:CC FLAGS_REG))]
14931 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
14932 {
14933 switch (get_attr_type (insn))
14934 {
14935 case TYPE_ISHIFTX:
14936 return "#";
14937
14938 default:
14939 if (operands[2] == const1_rtx
14940 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14941 return "<shift>{l}\t%k0";
14942 else
14943 return "<shift>{l}\t{%2, %k0|%k0, %2}";
14944 }
14945 }
14946 [(set_attr "isa" "*,bmi2")
14947 (set_attr "type" "ishift,ishiftx")
14948 (set (attr "length_immediate")
14949 (if_then_else
14950 (and (match_operand 2 "const1_operand")
14951 (ior (match_test "TARGET_SHIFT1")
14952 (match_test "optimize_function_for_size_p (cfun)")))
14953 (const_string "0")
14954 (const_string "*")))
14955 (set_attr "mode" "SI")])
14956
14957 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14958 (define_split
14959 [(set (match_operand:DI 0 "register_operand")
14960 (zero_extend:DI
14961 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
14962 (match_operand:QI 2 "register_operand"))))
14963 (clobber (reg:CC FLAGS_REG))]
14964 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14965 [(set (match_dup 0)
14966 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
14967 "operands[2] = gen_lowpart (SImode, operands[2]);")
14968
14969 (define_insn "*ashr<mode>3_1"
14970 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
14971 (ashiftrt:SWI12
14972 (match_operand:SWI12 1 "nonimmediate_operand" "0")
14973 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
14974 (clobber (reg:CC FLAGS_REG))]
14975 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14976 {
14977 if (operands[2] == const1_rtx
14978 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14979 return "sar{<imodesuffix>}\t%0";
14980 else
14981 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
14982 }
14983 [(set_attr "type" "ishift")
14984 (set (attr "length_immediate")
14985 (if_then_else
14986 (and (match_operand 2 "const1_operand")
14987 (ior (match_test "TARGET_SHIFT1")
14988 (match_test "optimize_function_for_size_p (cfun)")))
14989 (const_string "0")
14990 (const_string "*")))
14991 (set_attr "mode" "<MODE>")])
14992
14993 (define_insn "*lshrqi3_1"
14994 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
14995 (lshiftrt:QI
14996 (match_operand:QI 1 "nonimmediate_operand" "0, k")
14997 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
14998 (clobber (reg:CC FLAGS_REG))]
14999 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
15000 {
15001 switch (get_attr_type (insn))
15002 {
15003 case TYPE_ISHIFT:
15004 if (operands[2] == const1_rtx
15005 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15006 return "shr{b}\t%0";
15007 else
15008 return "shr{b}\t{%2, %0|%0, %2}";
15009 case TYPE_MSKLOG:
15010 return "#";
15011 default:
15012 gcc_unreachable ();
15013 }
15014 }
15015 [(set_attr "isa" "*,avx512dq")
15016 (set_attr "type" "ishift,msklog")
15017 (set (attr "length_immediate")
15018 (if_then_else
15019 (and (and (match_operand 2 "const1_operand")
15020 (eq_attr "alternative" "0"))
15021 (ior (match_test "TARGET_SHIFT1")
15022 (match_test "optimize_function_for_size_p (cfun)")))
15023 (const_string "0")
15024 (const_string "*")))
15025 (set_attr "mode" "QI")])
15026
15027 (define_insn "*lshrhi3_1"
15028 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
15029 (lshiftrt:HI
15030 (match_operand:HI 1 "nonimmediate_operand" "0, k")
15031 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
15032 (clobber (reg:CC FLAGS_REG))]
15033 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
15034 {
15035 switch (get_attr_type (insn))
15036 {
15037 case TYPE_ISHIFT:
15038 if (operands[2] == const1_rtx
15039 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15040 return "shr{w}\t%0";
15041 else
15042 return "shr{w}\t{%2, %0|%0, %2}";
15043 case TYPE_MSKLOG:
15044 return "#";
15045 default:
15046 gcc_unreachable ();
15047 }
15048 }
15049 [(set_attr "isa" "*, avx512f")
15050 (set_attr "type" "ishift,msklog")
15051 (set (attr "length_immediate")
15052 (if_then_else
15053 (and (and (match_operand 2 "const1_operand")
15054 (eq_attr "alternative" "0"))
15055 (ior (match_test "TARGET_SHIFT1")
15056 (match_test "optimize_function_for_size_p (cfun)")))
15057 (const_string "0")
15058 (const_string "*")))
15059 (set_attr "mode" "HI")])
15060
15061 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15062 (define_insn_and_split "*<insn><mode>3_1_slp"
15063 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15064 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15065 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15066 (clobber (reg:CC FLAGS_REG))]
15067 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15068 {
15069 if (which_alternative)
15070 return "#";
15071
15072 if (operands[2] == const1_rtx
15073 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15074 return "<shift>{<imodesuffix>}\t%0";
15075 else
15076 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15077 }
15078 "&& reload_completed"
15079 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15080 (parallel
15081 [(set (strict_low_part (match_dup 0))
15082 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15083 (clobber (reg:CC FLAGS_REG))])]
15084 ""
15085 [(set_attr "type" "ishift")
15086 (set (attr "length_immediate")
15087 (if_then_else
15088 (and (match_operand 2 "const1_operand")
15089 (ior (match_test "TARGET_SHIFT1")
15090 (match_test "optimize_function_for_size_p (cfun)")))
15091 (const_string "0")
15092 (const_string "*")))
15093 (set_attr "mode" "<MODE>")])
15094
15095 ;; This pattern can't accept a variable shift count, since shifts by
15096 ;; zero don't affect the flags. We assume that shifts by constant
15097 ;; zero are optimized away.
15098 (define_insn "*<insn><mode>3_cmp"
15099 [(set (reg FLAGS_REG)
15100 (compare
15101 (any_shiftrt:SWI
15102 (match_operand:SWI 1 "nonimmediate_operand" "0")
15103 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15104 (const_int 0)))
15105 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15106 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15107 "(optimize_function_for_size_p (cfun)
15108 || !TARGET_PARTIAL_FLAG_REG_STALL
15109 || (operands[2] == const1_rtx
15110 && TARGET_SHIFT1))
15111 && ix86_match_ccmode (insn, CCGOCmode)
15112 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15113 {
15114 if (operands[2] == const1_rtx
15115 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15116 return "<shift>{<imodesuffix>}\t%0";
15117 else
15118 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15119 }
15120 [(set_attr "type" "ishift")
15121 (set (attr "length_immediate")
15122 (if_then_else
15123 (and (match_operand 2 "const1_operand")
15124 (ior (match_test "TARGET_SHIFT1")
15125 (match_test "optimize_function_for_size_p (cfun)")))
15126 (const_string "0")
15127 (const_string "*")))
15128 (set_attr "mode" "<MODE>")])
15129
15130 (define_insn "*<insn>si3_cmp_zext"
15131 [(set (reg FLAGS_REG)
15132 (compare
15133 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15134 (match_operand:QI 2 "const_1_to_31_operand"))
15135 (const_int 0)))
15136 (set (match_operand:DI 0 "register_operand" "=r")
15137 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15138 "TARGET_64BIT
15139 && (optimize_function_for_size_p (cfun)
15140 || !TARGET_PARTIAL_FLAG_REG_STALL
15141 || (operands[2] == const1_rtx
15142 && TARGET_SHIFT1))
15143 && ix86_match_ccmode (insn, CCGOCmode)
15144 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15145 {
15146 if (operands[2] == const1_rtx
15147 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15148 return "<shift>{l}\t%k0";
15149 else
15150 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15151 }
15152 [(set_attr "type" "ishift")
15153 (set (attr "length_immediate")
15154 (if_then_else
15155 (and (match_operand 2 "const1_operand")
15156 (ior (match_test "TARGET_SHIFT1")
15157 (match_test "optimize_function_for_size_p (cfun)")))
15158 (const_string "0")
15159 (const_string "*")))
15160 (set_attr "mode" "SI")])
15161
15162 (define_insn "*<insn><mode>3_cconly"
15163 [(set (reg FLAGS_REG)
15164 (compare
15165 (any_shiftrt:SWI
15166 (match_operand:SWI 1 "register_operand" "0")
15167 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15168 (const_int 0)))
15169 (clobber (match_scratch:SWI 0 "=<r>"))]
15170 "(optimize_function_for_size_p (cfun)
15171 || !TARGET_PARTIAL_FLAG_REG_STALL
15172 || (operands[2] == const1_rtx
15173 && TARGET_SHIFT1))
15174 && ix86_match_ccmode (insn, CCGOCmode)"
15175 {
15176 if (operands[2] == const1_rtx
15177 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15178 return "<shift>{<imodesuffix>}\t%0";
15179 else
15180 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15181 }
15182 [(set_attr "type" "ishift")
15183 (set (attr "length_immediate")
15184 (if_then_else
15185 (and (match_operand 2 "const1_operand")
15186 (ior (match_test "TARGET_SHIFT1")
15187 (match_test "optimize_function_for_size_p (cfun)")))
15188 (const_string "0")
15189 (const_string "*")))
15190 (set_attr "mode" "<MODE>")])
15191
15192 (define_insn "*<insn>qi_ext<mode>_2"
15193 [(set (zero_extract:SWI248
15194 (match_operand 0 "int248_register_operand" "+Q")
15195 (const_int 8)
15196 (const_int 8))
15197 (subreg:SWI248
15198 (any_shiftrt:QI
15199 (subreg:QI
15200 (match_operator:SWI248 3 "extract_operator"
15201 [(match_operand 1 "int248_register_operand" "0")
15202 (const_int 8)
15203 (const_int 8)]) 0)
15204 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
15205 (clobber (reg:CC FLAGS_REG))]
15206 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
15207 rtx_equal_p (operands[0], operands[1])"
15208 {
15209 if (operands[2] == const1_rtx
15210 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15211 return "<shift>{b}\t%h0";
15212 else
15213 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15214 }
15215 [(set_attr "type" "ishift")
15216 (set (attr "length_immediate")
15217 (if_then_else
15218 (and (match_operand 2 "const1_operand")
15219 (ior (match_test "TARGET_SHIFT1")
15220 (match_test "optimize_function_for_size_p (cfun)")))
15221 (const_string "0")
15222 (const_string "*")))
15223 (set_attr "mode" "QI")])
15224 \f
15225 ;; Rotate instructions
15226
15227 (define_expand "<insn>ti3"
15228 [(set (match_operand:TI 0 "register_operand")
15229 (any_rotate:TI (match_operand:TI 1 "register_operand")
15230 (match_operand:QI 2 "nonmemory_operand")))]
15231 "TARGET_64BIT"
15232 {
15233 if (const_1_to_63_operand (operands[2], VOIDmode))
15234 emit_insn (gen_ix86_<insn>ti3_doubleword
15235 (operands[0], operands[1], operands[2]));
15236 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15237 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15238 else
15239 {
15240 rtx amount = force_reg (QImode, operands[2]);
15241 rtx src_lo = gen_lowpart (DImode, operands[1]);
15242 rtx src_hi = gen_highpart (DImode, operands[1]);
15243 rtx tmp_lo = gen_reg_rtx (DImode);
15244 rtx tmp_hi = gen_reg_rtx (DImode);
15245 emit_move_insn (tmp_lo, src_lo);
15246 emit_move_insn (tmp_hi, src_hi);
15247 rtx (*shiftd) (rtx, rtx, rtx)
15248 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15249 emit_insn (shiftd (tmp_lo, src_hi, amount));
15250 emit_insn (shiftd (tmp_hi, src_lo, amount));
15251 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15252 rtx dst_hi = gen_highpart (DImode, operands[0]);
15253 emit_move_insn (dst_lo, tmp_lo);
15254 emit_move_insn (dst_hi, tmp_hi);
15255 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15256 }
15257 DONE;
15258 })
15259
15260 (define_expand "<insn>di3"
15261 [(set (match_operand:DI 0 "shiftdi_operand")
15262 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15263 (match_operand:QI 2 "nonmemory_operand")))]
15264 ""
15265 {
15266 if (TARGET_64BIT)
15267 ix86_expand_binary_operator (<CODE>, DImode, operands);
15268 else if (const_1_to_31_operand (operands[2], VOIDmode))
15269 emit_insn (gen_ix86_<insn>di3_doubleword
15270 (operands[0], operands[1], operands[2]));
15271 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15272 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15273 else
15274 FAIL;
15275
15276 DONE;
15277 })
15278
15279 (define_expand "<insn><mode>3"
15280 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15281 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15282 (match_operand:QI 2 "nonmemory_operand")))]
15283 ""
15284 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15285
15286 ;; Avoid useless masking of count operand.
15287 (define_insn_and_split "*<insn><mode>3_mask"
15288 [(set (match_operand:SWI 0 "nonimmediate_operand")
15289 (any_rotate:SWI
15290 (match_operand:SWI 1 "nonimmediate_operand")
15291 (subreg:QI
15292 (and
15293 (match_operand 2 "int248_register_operand" "c")
15294 (match_operand 3 "const_int_operand")) 0)))
15295 (clobber (reg:CC FLAGS_REG))]
15296 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15297 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15298 == GET_MODE_BITSIZE (<MODE>mode)-1
15299 && ix86_pre_reload_split ()"
15300 "#"
15301 "&& 1"
15302 [(parallel
15303 [(set (match_dup 0)
15304 (any_rotate:SWI (match_dup 1)
15305 (match_dup 2)))
15306 (clobber (reg:CC FLAGS_REG))])]
15307 {
15308 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15309 operands[2] = gen_lowpart (QImode, operands[2]);
15310 })
15311
15312 (define_split
15313 [(set (match_operand:SWI 0 "register_operand")
15314 (any_rotate:SWI
15315 (match_operand:SWI 1 "const_int_operand")
15316 (subreg:QI
15317 (and
15318 (match_operand 2 "int248_register_operand")
15319 (match_operand 3 "const_int_operand")) 0)))]
15320 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15321 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15322 [(set (match_dup 4) (match_dup 1))
15323 (set (match_dup 0)
15324 (any_rotate:SWI (match_dup 4)
15325 (subreg:QI (match_dup 2) 0)))]
15326 "operands[4] = gen_reg_rtx (<MODE>mode);")
15327
15328 (define_insn_and_split "*<insn><mode>3_mask_1"
15329 [(set (match_operand:SWI 0 "nonimmediate_operand")
15330 (any_rotate:SWI
15331 (match_operand:SWI 1 "nonimmediate_operand")
15332 (and:QI
15333 (match_operand:QI 2 "register_operand" "c")
15334 (match_operand:QI 3 "const_int_operand"))))
15335 (clobber (reg:CC FLAGS_REG))]
15336 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15337 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15338 == GET_MODE_BITSIZE (<MODE>mode)-1
15339 && ix86_pre_reload_split ()"
15340 "#"
15341 "&& 1"
15342 [(parallel
15343 [(set (match_dup 0)
15344 (any_rotate:SWI (match_dup 1)
15345 (match_dup 2)))
15346 (clobber (reg:CC FLAGS_REG))])])
15347
15348 (define_split
15349 [(set (match_operand:SWI 0 "register_operand")
15350 (any_rotate:SWI
15351 (match_operand:SWI 1 "const_int_operand")
15352 (and:QI
15353 (match_operand:QI 2 "register_operand")
15354 (match_operand:QI 3 "const_int_operand"))))]
15355 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15356 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15357 [(set (match_dup 4) (match_dup 1))
15358 (set (match_dup 0)
15359 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15360 "operands[4] = gen_reg_rtx (<MODE>mode);")
15361
15362 ;; Implement rotation using two double-precision
15363 ;; shift instructions and a scratch register.
15364
15365 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15366 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15367 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15368 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15369 (clobber (reg:CC FLAGS_REG))
15370 (clobber (match_scratch:DWIH 3 "=&r"))]
15371 ""
15372 "#"
15373 "reload_completed"
15374 [(set (match_dup 3) (match_dup 4))
15375 (parallel
15376 [(set (match_dup 4)
15377 (ior:DWIH (ashift:DWIH (match_dup 4)
15378 (and:QI (match_dup 2) (match_dup 6)))
15379 (subreg:DWIH
15380 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15381 (minus:QI (match_dup 7)
15382 (and:QI (match_dup 2)
15383 (match_dup 6)))) 0)))
15384 (clobber (reg:CC FLAGS_REG))])
15385 (parallel
15386 [(set (match_dup 5)
15387 (ior:DWIH (ashift:DWIH (match_dup 5)
15388 (and:QI (match_dup 2) (match_dup 6)))
15389 (subreg:DWIH
15390 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15391 (minus:QI (match_dup 7)
15392 (and:QI (match_dup 2)
15393 (match_dup 6)))) 0)))
15394 (clobber (reg:CC FLAGS_REG))])]
15395 {
15396 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15397 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15398
15399 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15400 })
15401
15402 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15403 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15404 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15405 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15406 (clobber (reg:CC FLAGS_REG))
15407 (clobber (match_scratch:DWIH 3 "=&r"))]
15408 ""
15409 "#"
15410 "reload_completed"
15411 [(set (match_dup 3) (match_dup 4))
15412 (parallel
15413 [(set (match_dup 4)
15414 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15415 (and:QI (match_dup 2) (match_dup 6)))
15416 (subreg:DWIH
15417 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15418 (minus:QI (match_dup 7)
15419 (and:QI (match_dup 2)
15420 (match_dup 6)))) 0)))
15421 (clobber (reg:CC FLAGS_REG))])
15422 (parallel
15423 [(set (match_dup 5)
15424 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15425 (and:QI (match_dup 2) (match_dup 6)))
15426 (subreg:DWIH
15427 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15428 (minus:QI (match_dup 7)
15429 (and:QI (match_dup 2)
15430 (match_dup 6)))) 0)))
15431 (clobber (reg:CC FLAGS_REG))])]
15432 {
15433 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15434 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15435
15436 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15437 })
15438
15439 (define_insn_and_split "<insn>32di2_doubleword"
15440 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
15441 (any_rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,r,o")
15442 (const_int 32)))]
15443 "!TARGET_64BIT"
15444 "#"
15445 "&& reload_completed"
15446 [(set (match_dup 0) (match_dup 3))
15447 (set (match_dup 2) (match_dup 1))]
15448 {
15449 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15450 if (rtx_equal_p (operands[0], operands[1]))
15451 {
15452 emit_insn (gen_swapsi (operands[0], operands[2]));
15453 DONE;
15454 }
15455 })
15456
15457 (define_insn_and_split "<insn>64ti2_doubleword"
15458 [(set (match_operand:TI 0 "register_operand" "=r,r,r")
15459 (any_rotate:TI (match_operand:TI 1 "nonimmediate_operand" "0,r,o")
15460 (const_int 64)))]
15461 "TARGET_64BIT"
15462 "#"
15463 "&& reload_completed"
15464 [(set (match_dup 0) (match_dup 3))
15465 (set (match_dup 2) (match_dup 1))]
15466 {
15467 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15468 if (rtx_equal_p (operands[0], operands[1]))
15469 {
15470 emit_insn (gen_swapdi (operands[0], operands[2]));
15471 DONE;
15472 }
15473 })
15474
15475 (define_mode_attr rorx_immediate_operand
15476 [(SI "const_0_to_31_operand")
15477 (DI "const_0_to_63_operand")])
15478
15479 (define_insn "*bmi2_rorx<mode>3_1"
15480 [(set (match_operand:SWI48 0 "register_operand" "=r")
15481 (rotatert:SWI48
15482 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15483 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15484 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15485 "rorx\t{%2, %1, %0|%0, %1, %2}"
15486 [(set_attr "type" "rotatex")
15487 (set_attr "mode" "<MODE>")])
15488
15489 (define_insn "*<insn><mode>3_1"
15490 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15491 (any_rotate:SWI48
15492 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15493 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15494 (clobber (reg:CC FLAGS_REG))]
15495 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15496 {
15497 switch (get_attr_type (insn))
15498 {
15499 case TYPE_ROTATEX:
15500 return "#";
15501
15502 default:
15503 if (operands[2] == const1_rtx
15504 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15505 return "<rotate>{<imodesuffix>}\t%0";
15506 else
15507 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15508 }
15509 }
15510 [(set_attr "isa" "*,bmi2")
15511 (set_attr "type" "rotate,rotatex")
15512 (set (attr "preferred_for_size")
15513 (cond [(eq_attr "alternative" "0")
15514 (symbol_ref "true")]
15515 (symbol_ref "false")))
15516 (set (attr "length_immediate")
15517 (if_then_else
15518 (and (eq_attr "type" "rotate")
15519 (and (match_operand 2 "const1_operand")
15520 (ior (match_test "TARGET_SHIFT1")
15521 (match_test "optimize_function_for_size_p (cfun)"))))
15522 (const_string "0")
15523 (const_string "*")))
15524 (set_attr "mode" "<MODE>")])
15525
15526 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15527 (define_split
15528 [(set (match_operand:SWI48 0 "register_operand")
15529 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15530 (match_operand:QI 2 "const_int_operand")))
15531 (clobber (reg:CC FLAGS_REG))]
15532 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15533 [(set (match_dup 0)
15534 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15535 {
15536 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15537
15538 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15539 })
15540
15541 (define_split
15542 [(set (match_operand:SWI48 0 "register_operand")
15543 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15544 (match_operand:QI 2 "const_int_operand")))
15545 (clobber (reg:CC FLAGS_REG))]
15546 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15547 [(set (match_dup 0)
15548 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15549
15550 (define_insn "*bmi2_rorxsi3_1_zext"
15551 [(set (match_operand:DI 0 "register_operand" "=r")
15552 (zero_extend:DI
15553 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15554 (match_operand:QI 2 "const_0_to_31_operand"))))]
15555 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15556 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
15557 [(set_attr "type" "rotatex")
15558 (set_attr "mode" "SI")])
15559
15560 (define_insn "*<insn>si3_1_zext"
15561 [(set (match_operand:DI 0 "register_operand" "=r,r")
15562 (zero_extend:DI
15563 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15564 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
15565 (clobber (reg:CC FLAGS_REG))]
15566 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15567 {
15568 switch (get_attr_type (insn))
15569 {
15570 case TYPE_ROTATEX:
15571 return "#";
15572
15573 default:
15574 if (operands[2] == const1_rtx
15575 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15576 return "<rotate>{l}\t%k0";
15577 else
15578 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
15579 }
15580 }
15581 [(set_attr "isa" "*,bmi2")
15582 (set_attr "type" "rotate,rotatex")
15583 (set (attr "preferred_for_size")
15584 (cond [(eq_attr "alternative" "0")
15585 (symbol_ref "true")]
15586 (symbol_ref "false")))
15587 (set (attr "length_immediate")
15588 (if_then_else
15589 (and (eq_attr "type" "rotate")
15590 (and (match_operand 2 "const1_operand")
15591 (ior (match_test "TARGET_SHIFT1")
15592 (match_test "optimize_function_for_size_p (cfun)"))))
15593 (const_string "0")
15594 (const_string "*")))
15595 (set_attr "mode" "SI")])
15596
15597 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15598 (define_split
15599 [(set (match_operand:DI 0 "register_operand")
15600 (zero_extend:DI
15601 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
15602 (match_operand:QI 2 "const_int_operand"))))
15603 (clobber (reg:CC FLAGS_REG))]
15604 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15605 && !optimize_function_for_size_p (cfun)"
15606 [(set (match_dup 0)
15607 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
15608 {
15609 int bitsize = GET_MODE_BITSIZE (SImode);
15610
15611 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15612 })
15613
15614 (define_split
15615 [(set (match_operand:DI 0 "register_operand")
15616 (zero_extend:DI
15617 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
15618 (match_operand:QI 2 "const_int_operand"))))
15619 (clobber (reg:CC FLAGS_REG))]
15620 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15621 && !optimize_function_for_size_p (cfun)"
15622 [(set (match_dup 0)
15623 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
15624
15625 (define_insn "*<insn><mode>3_1"
15626 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15627 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15628 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15629 (clobber (reg:CC FLAGS_REG))]
15630 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15631 {
15632 if (operands[2] == const1_rtx
15633 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15634 return "<rotate>{<imodesuffix>}\t%0";
15635 else
15636 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15637 }
15638 [(set_attr "type" "rotate")
15639 (set (attr "length_immediate")
15640 (if_then_else
15641 (and (match_operand 2 "const1_operand")
15642 (ior (match_test "TARGET_SHIFT1")
15643 (match_test "optimize_function_for_size_p (cfun)")))
15644 (const_string "0")
15645 (const_string "*")))
15646 (set_attr "mode" "<MODE>")])
15647
15648 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15649 (define_insn_and_split "*<insn><mode>3_1_slp"
15650 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15651 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15652 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15653 (clobber (reg:CC FLAGS_REG))]
15654 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15655 {
15656 if (which_alternative)
15657 return "#";
15658
15659 if (operands[2] == const1_rtx
15660 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15661 return "<rotate>{<imodesuffix>}\t%0";
15662 else
15663 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15664 }
15665 "&& reload_completed"
15666 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15667 (parallel
15668 [(set (strict_low_part (match_dup 0))
15669 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
15670 (clobber (reg:CC FLAGS_REG))])]
15671 ""
15672 [(set_attr "type" "rotate")
15673 (set (attr "length_immediate")
15674 (if_then_else
15675 (and (match_operand 2 "const1_operand")
15676 (ior (match_test "TARGET_SHIFT1")
15677 (match_test "optimize_function_for_size_p (cfun)")))
15678 (const_string "0")
15679 (const_string "*")))
15680 (set_attr "mode" "<MODE>")])
15681
15682 (define_split
15683 [(set (match_operand:HI 0 "QIreg_operand")
15684 (any_rotate:HI (match_dup 0) (const_int 8)))
15685 (clobber (reg:CC FLAGS_REG))]
15686 "reload_completed
15687 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
15688 [(parallel [(set (strict_low_part (match_dup 0))
15689 (bswap:HI (match_dup 0)))
15690 (clobber (reg:CC FLAGS_REG))])])
15691 \f
15692 ;; Bit set / bit test instructions
15693
15694 ;; %%% bts, btr, btc
15695
15696 ;; These instructions are *slow* when applied to memory.
15697
15698 (define_code_attr btsc [(ior "bts") (xor "btc")])
15699
15700 (define_insn "*<btsc><mode>"
15701 [(set (match_operand:SWI48 0 "register_operand" "=r")
15702 (any_or:SWI48
15703 (ashift:SWI48 (const_int 1)
15704 (match_operand:QI 2 "register_operand" "r"))
15705 (match_operand:SWI48 1 "register_operand" "0")))
15706 (clobber (reg:CC FLAGS_REG))]
15707 "TARGET_USE_BT"
15708 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15709 [(set_attr "type" "alu1")
15710 (set_attr "prefix_0f" "1")
15711 (set_attr "znver1_decode" "double")
15712 (set_attr "mode" "<MODE>")])
15713
15714 ;; Avoid useless masking of count operand.
15715 (define_insn_and_split "*<btsc><mode>_mask"
15716 [(set (match_operand:SWI48 0 "register_operand")
15717 (any_or:SWI48
15718 (ashift:SWI48
15719 (const_int 1)
15720 (subreg:QI
15721 (and
15722 (match_operand 1 "int248_register_operand")
15723 (match_operand 2 "const_int_operand")) 0))
15724 (match_operand:SWI48 3 "register_operand")))
15725 (clobber (reg:CC FLAGS_REG))]
15726 "TARGET_USE_BT
15727 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15728 == GET_MODE_BITSIZE (<MODE>mode)-1
15729 && ix86_pre_reload_split ()"
15730 "#"
15731 "&& 1"
15732 [(parallel
15733 [(set (match_dup 0)
15734 (any_or:SWI48
15735 (ashift:SWI48 (const_int 1)
15736 (match_dup 1))
15737 (match_dup 3)))
15738 (clobber (reg:CC FLAGS_REG))])]
15739 {
15740 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
15741 operands[1] = gen_lowpart (QImode, operands[1]);
15742 })
15743
15744 (define_insn_and_split "*<btsc><mode>_mask_1"
15745 [(set (match_operand:SWI48 0 "register_operand")
15746 (any_or:SWI48
15747 (ashift:SWI48
15748 (const_int 1)
15749 (and:QI
15750 (match_operand:QI 1 "register_operand")
15751 (match_operand:QI 2 "const_int_operand")))
15752 (match_operand:SWI48 3 "register_operand")))
15753 (clobber (reg:CC FLAGS_REG))]
15754 "TARGET_USE_BT
15755 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15756 == GET_MODE_BITSIZE (<MODE>mode)-1
15757 && ix86_pre_reload_split ()"
15758 "#"
15759 "&& 1"
15760 [(parallel
15761 [(set (match_dup 0)
15762 (any_or:SWI48
15763 (ashift:SWI48 (const_int 1)
15764 (match_dup 1))
15765 (match_dup 3)))
15766 (clobber (reg:CC FLAGS_REG))])])
15767
15768 (define_insn "*btr<mode>"
15769 [(set (match_operand:SWI48 0 "register_operand" "=r")
15770 (and:SWI48
15771 (rotate:SWI48 (const_int -2)
15772 (match_operand:QI 2 "register_operand" "r"))
15773 (match_operand:SWI48 1 "register_operand" "0")))
15774 (clobber (reg:CC FLAGS_REG))]
15775 "TARGET_USE_BT"
15776 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15777 [(set_attr "type" "alu1")
15778 (set_attr "prefix_0f" "1")
15779 (set_attr "znver1_decode" "double")
15780 (set_attr "mode" "<MODE>")])
15781
15782 ;; Avoid useless masking of count operand.
15783 (define_insn_and_split "*btr<mode>_mask"
15784 [(set (match_operand:SWI48 0 "register_operand")
15785 (and:SWI48
15786 (rotate:SWI48
15787 (const_int -2)
15788 (subreg:QI
15789 (and
15790 (match_operand 1 "int248_register_operand")
15791 (match_operand 2 "const_int_operand")) 0))
15792 (match_operand:SWI48 3 "register_operand")))
15793 (clobber (reg:CC FLAGS_REG))]
15794 "TARGET_USE_BT
15795 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15796 == GET_MODE_BITSIZE (<MODE>mode)-1
15797 && ix86_pre_reload_split ()"
15798 "#"
15799 "&& 1"
15800 [(parallel
15801 [(set (match_dup 0)
15802 (and:SWI48
15803 (rotate:SWI48 (const_int -2)
15804 (match_dup 1))
15805 (match_dup 3)))
15806 (clobber (reg:CC FLAGS_REG))])]
15807 {
15808 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
15809 operands[1] = gen_lowpart (QImode, operands[1]);
15810 })
15811
15812 (define_insn_and_split "*btr<mode>_mask_1"
15813 [(set (match_operand:SWI48 0 "register_operand")
15814 (and:SWI48
15815 (rotate:SWI48
15816 (const_int -2)
15817 (and:QI
15818 (match_operand:QI 1 "register_operand")
15819 (match_operand:QI 2 "const_int_operand")))
15820 (match_operand:SWI48 3 "register_operand")))
15821 (clobber (reg:CC FLAGS_REG))]
15822 "TARGET_USE_BT
15823 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15824 == GET_MODE_BITSIZE (<MODE>mode)-1
15825 && ix86_pre_reload_split ()"
15826 "#"
15827 "&& 1"
15828 [(parallel
15829 [(set (match_dup 0)
15830 (and:SWI48
15831 (rotate:SWI48 (const_int -2)
15832 (match_dup 1))
15833 (match_dup 3)))
15834 (clobber (reg:CC FLAGS_REG))])])
15835
15836 (define_insn_and_split "*btr<mode>_1"
15837 [(set (match_operand:SWI12 0 "register_operand")
15838 (and:SWI12
15839 (subreg:SWI12
15840 (rotate:SI (const_int -2)
15841 (match_operand:QI 2 "register_operand")) 0)
15842 (match_operand:SWI12 1 "nonimmediate_operand")))
15843 (clobber (reg:CC FLAGS_REG))]
15844 "TARGET_USE_BT && ix86_pre_reload_split ()"
15845 "#"
15846 "&& 1"
15847 [(parallel
15848 [(set (match_dup 0)
15849 (and:SI (rotate:SI (const_int -2) (match_dup 2))
15850 (match_dup 1)))
15851 (clobber (reg:CC FLAGS_REG))])]
15852 {
15853 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15854 operands[1] = force_reg (<MODE>mode, operands[1]);
15855 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
15856 })
15857
15858 (define_insn_and_split "*btr<mode>_2"
15859 [(set (zero_extract:HI
15860 (match_operand:SWI12 0 "nonimmediate_operand")
15861 (const_int 1)
15862 (zero_extend:SI (match_operand:QI 1 "register_operand")))
15863 (const_int 0))
15864 (clobber (reg:CC FLAGS_REG))]
15865 "TARGET_USE_BT && ix86_pre_reload_split ()"
15866 "#"
15867 "&& MEM_P (operands[0])"
15868 [(set (match_dup 2) (match_dup 0))
15869 (parallel
15870 [(set (match_dup 3)
15871 (and:SI (rotate:SI (const_int -2) (match_dup 1))
15872 (match_dup 4)))
15873 (clobber (reg:CC FLAGS_REG))])
15874 (set (match_dup 0) (match_dup 5))]
15875 {
15876 operands[2] = gen_reg_rtx (<MODE>mode);
15877 operands[5] = gen_reg_rtx (<MODE>mode);
15878 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
15879 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
15880 })
15881
15882 (define_split
15883 [(set (zero_extract:HI
15884 (match_operand:SWI12 0 "register_operand")
15885 (const_int 1)
15886 (zero_extend:SI (match_operand:QI 1 "register_operand")))
15887 (const_int 0))
15888 (clobber (reg:CC FLAGS_REG))]
15889 "TARGET_USE_BT && ix86_pre_reload_split ()"
15890 [(parallel
15891 [(set (match_dup 0)
15892 (and:SI (rotate:SI (const_int -2) (match_dup 1))
15893 (match_dup 2)))
15894 (clobber (reg:CC FLAGS_REG))])]
15895 {
15896 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15897 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15898 })
15899
15900 ;; These instructions are never faster than the corresponding
15901 ;; and/ior/xor operations when using immediate operand, so with
15902 ;; 32-bit there's no point. But in 64-bit, we can't hold the
15903 ;; relevant immediates within the instruction itself, so operating
15904 ;; on bits in the high 32-bits of a register becomes easier.
15905 ;;
15906 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
15907 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
15908 ;; negdf respectively, so they can never be disabled entirely.
15909
15910 (define_insn "*btsq_imm"
15911 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
15912 (const_int 1)
15913 (match_operand 1 "const_0_to_63_operand"))
15914 (const_int 1))
15915 (clobber (reg:CC FLAGS_REG))]
15916 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
15917 "bts{q}\t{%1, %0|%0, %1}"
15918 [(set_attr "type" "alu1")
15919 (set_attr "prefix_0f" "1")
15920 (set_attr "znver1_decode" "double")
15921 (set_attr "mode" "DI")])
15922
15923 (define_insn "*btrq_imm"
15924 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
15925 (const_int 1)
15926 (match_operand 1 "const_0_to_63_operand"))
15927 (const_int 0))
15928 (clobber (reg:CC FLAGS_REG))]
15929 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
15930 "btr{q}\t{%1, %0|%0, %1}"
15931 [(set_attr "type" "alu1")
15932 (set_attr "prefix_0f" "1")
15933 (set_attr "znver1_decode" "double")
15934 (set_attr "mode" "DI")])
15935
15936 (define_insn "*btcq_imm"
15937 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
15938 (const_int 1)
15939 (match_operand 1 "const_0_to_63_operand"))
15940 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
15941 (clobber (reg:CC FLAGS_REG))]
15942 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
15943 "btc{q}\t{%1, %0|%0, %1}"
15944 [(set_attr "type" "alu1")
15945 (set_attr "prefix_0f" "1")
15946 (set_attr "znver1_decode" "double")
15947 (set_attr "mode" "DI")])
15948
15949 ;; Allow Nocona to avoid these instructions if a register is available.
15950
15951 (define_peephole2
15952 [(match_scratch:DI 2 "r")
15953 (parallel [(set (zero_extract:DI
15954 (match_operand:DI 0 "nonimmediate_operand")
15955 (const_int 1)
15956 (match_operand 1 "const_0_to_63_operand"))
15957 (const_int 1))
15958 (clobber (reg:CC FLAGS_REG))])]
15959 "TARGET_64BIT && !TARGET_USE_BT"
15960 [(parallel [(set (match_dup 0)
15961 (ior:DI (match_dup 0) (match_dup 3)))
15962 (clobber (reg:CC FLAGS_REG))])]
15963 {
15964 int i = INTVAL (operands[1]);
15965
15966 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
15967
15968 if (!x86_64_immediate_operand (operands[3], DImode))
15969 {
15970 emit_move_insn (operands[2], operands[3]);
15971 operands[3] = operands[2];
15972 }
15973 })
15974
15975 (define_peephole2
15976 [(match_scratch:DI 2 "r")
15977 (parallel [(set (zero_extract:DI
15978 (match_operand:DI 0 "nonimmediate_operand")
15979 (const_int 1)
15980 (match_operand 1 "const_0_to_63_operand"))
15981 (const_int 0))
15982 (clobber (reg:CC FLAGS_REG))])]
15983 "TARGET_64BIT && !TARGET_USE_BT"
15984 [(parallel [(set (match_dup 0)
15985 (and:DI (match_dup 0) (match_dup 3)))
15986 (clobber (reg:CC FLAGS_REG))])]
15987 {
15988 int i = INTVAL (operands[1]);
15989
15990 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
15991
15992 if (!x86_64_immediate_operand (operands[3], DImode))
15993 {
15994 emit_move_insn (operands[2], operands[3]);
15995 operands[3] = operands[2];
15996 }
15997 })
15998
15999 (define_peephole2
16000 [(match_scratch:DI 2 "r")
16001 (parallel [(set (zero_extract:DI
16002 (match_operand:DI 0 "nonimmediate_operand")
16003 (const_int 1)
16004 (match_operand 1 "const_0_to_63_operand"))
16005 (not:DI (zero_extract:DI
16006 (match_dup 0) (const_int 1) (match_dup 1))))
16007 (clobber (reg:CC FLAGS_REG))])]
16008 "TARGET_64BIT && !TARGET_USE_BT"
16009 [(parallel [(set (match_dup 0)
16010 (xor:DI (match_dup 0) (match_dup 3)))
16011 (clobber (reg:CC FLAGS_REG))])]
16012 {
16013 int i = INTVAL (operands[1]);
16014
16015 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
16016
16017 if (!x86_64_immediate_operand (operands[3], DImode))
16018 {
16019 emit_move_insn (operands[2], operands[3]);
16020 operands[3] = operands[2];
16021 }
16022 })
16023
16024 ;; %%% bt
16025
16026 (define_insn "*bt<mode>"
16027 [(set (reg:CCC FLAGS_REG)
16028 (compare:CCC
16029 (zero_extract:SWI48
16030 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
16031 (const_int 1)
16032 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
16033 (const_int 0)))]
16034 ""
16035 {
16036 switch (get_attr_mode (insn))
16037 {
16038 case MODE_SI:
16039 return "bt{l}\t{%1, %k0|%k0, %1}";
16040
16041 case MODE_DI:
16042 return "bt{q}\t{%q1, %0|%0, %q1}";
16043
16044 default:
16045 gcc_unreachable ();
16046 }
16047 }
16048 [(set_attr "type" "alu1")
16049 (set_attr "prefix_0f" "1")
16050 (set (attr "mode")
16051 (if_then_else
16052 (and (match_test "CONST_INT_P (operands[1])")
16053 (match_test "INTVAL (operands[1]) < 32"))
16054 (const_string "SI")
16055 (const_string "<MODE>")))])
16056
16057 (define_insn_and_split "*jcc_bt<mode>"
16058 [(set (pc)
16059 (if_then_else (match_operator 0 "bt_comparison_operator"
16060 [(zero_extract:SWI48
16061 (match_operand:SWI48 1 "nonimmediate_operand")
16062 (const_int 1)
16063 (match_operand:SI 2 "nonmemory_operand"))
16064 (const_int 0)])
16065 (label_ref (match_operand 3))
16066 (pc)))
16067 (clobber (reg:CC FLAGS_REG))]
16068 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16069 && (CONST_INT_P (operands[2])
16070 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
16071 && INTVAL (operands[2])
16072 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16073 : !memory_operand (operands[1], <MODE>mode))
16074 && ix86_pre_reload_split ()"
16075 "#"
16076 "&& 1"
16077 [(set (reg:CCC FLAGS_REG)
16078 (compare:CCC
16079 (zero_extract:SWI48
16080 (match_dup 1)
16081 (const_int 1)
16082 (match_dup 2))
16083 (const_int 0)))
16084 (set (pc)
16085 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16086 (label_ref (match_dup 3))
16087 (pc)))]
16088 {
16089 operands[0] = shallow_copy_rtx (operands[0]);
16090 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16091 })
16092
16093 (define_insn_and_split "*jcc_bt<mode>_1"
16094 [(set (pc)
16095 (if_then_else (match_operator 0 "bt_comparison_operator"
16096 [(zero_extract:SWI48
16097 (match_operand:SWI48 1 "register_operand")
16098 (const_int 1)
16099 (zero_extend:SI
16100 (match_operand:QI 2 "register_operand")))
16101 (const_int 0)])
16102 (label_ref (match_operand 3))
16103 (pc)))
16104 (clobber (reg:CC FLAGS_REG))]
16105 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16106 && ix86_pre_reload_split ()"
16107 "#"
16108 "&& 1"
16109 [(set (reg:CCC FLAGS_REG)
16110 (compare:CCC
16111 (zero_extract:SWI48
16112 (match_dup 1)
16113 (const_int 1)
16114 (match_dup 2))
16115 (const_int 0)))
16116 (set (pc)
16117 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16118 (label_ref (match_dup 3))
16119 (pc)))]
16120 {
16121 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16122 operands[0] = shallow_copy_rtx (operands[0]);
16123 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16124 })
16125
16126 ;; Avoid useless masking of bit offset operand.
16127 (define_insn_and_split "*jcc_bt<mode>_mask"
16128 [(set (pc)
16129 (if_then_else (match_operator 0 "bt_comparison_operator"
16130 [(zero_extract:SWI48
16131 (match_operand:SWI48 1 "register_operand")
16132 (const_int 1)
16133 (and:SI
16134 (match_operand:SI 2 "register_operand")
16135 (match_operand 3 "const_int_operand")))])
16136 (label_ref (match_operand 4))
16137 (pc)))
16138 (clobber (reg:CC FLAGS_REG))]
16139 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16140 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16141 == GET_MODE_BITSIZE (<MODE>mode)-1
16142 && ix86_pre_reload_split ()"
16143 "#"
16144 "&& 1"
16145 [(set (reg:CCC FLAGS_REG)
16146 (compare:CCC
16147 (zero_extract:SWI48
16148 (match_dup 1)
16149 (const_int 1)
16150 (match_dup 2))
16151 (const_int 0)))
16152 (set (pc)
16153 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16154 (label_ref (match_dup 4))
16155 (pc)))]
16156 {
16157 operands[0] = shallow_copy_rtx (operands[0]);
16158 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16159 })
16160
16161 (define_insn_and_split "*jcc_bt<mode>_mask_1"
16162 [(set (pc)
16163 (if_then_else (match_operator 0 "bt_comparison_operator"
16164 [(zero_extract:SWI48
16165 (match_operand:SWI48 1 "register_operand")
16166 (const_int 1)
16167 (zero_extend:SI
16168 (subreg:QI
16169 (and
16170 (match_operand 2 "int248_register_operand")
16171 (match_operand 3 "const_int_operand")) 0)))])
16172 (label_ref (match_operand 4))
16173 (pc)))
16174 (clobber (reg:CC FLAGS_REG))]
16175 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16176 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16177 == GET_MODE_BITSIZE (<MODE>mode)-1
16178 && ix86_pre_reload_split ()"
16179 "#"
16180 "&& 1"
16181 [(set (reg:CCC FLAGS_REG)
16182 (compare:CCC
16183 (zero_extract:SWI48
16184 (match_dup 1)
16185 (const_int 1)
16186 (match_dup 2))
16187 (const_int 0)))
16188 (set (pc)
16189 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16190 (label_ref (match_dup 4))
16191 (pc)))]
16192 {
16193 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16194 operands[2] = gen_lowpart (SImode, operands[2]);
16195 operands[0] = shallow_copy_rtx (operands[0]);
16196 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16197 })
16198
16199 ;; Help combine recognize bt followed by cmov
16200 (define_split
16201 [(set (match_operand:SWI248 0 "register_operand")
16202 (if_then_else:SWI248
16203 (match_operator 5 "bt_comparison_operator"
16204 [(zero_extract:SWI48
16205 (match_operand:SWI48 1 "register_operand")
16206 (const_int 1)
16207 (zero_extend:SI (match_operand:QI 2 "register_operand")))
16208 (const_int 0)])
16209 (match_operand:SWI248 3 "nonimmediate_operand")
16210 (match_operand:SWI248 4 "nonimmediate_operand")))]
16211 "TARGET_USE_BT && TARGET_CMOVE
16212 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16213 && ix86_pre_reload_split ()"
16214 [(set (reg:CCC FLAGS_REG)
16215 (compare:CCC
16216 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16217 (const_int 0)))
16218 (set (match_dup 0)
16219 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16220 (match_dup 3)
16221 (match_dup 4)))]
16222 {
16223 if (GET_CODE (operands[5]) == EQ)
16224 std::swap (operands[3], operands[4]);
16225 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16226 })
16227
16228 ;; Help combine recognize bt followed by setc
16229 (define_insn_and_split "*bt<mode>_setcqi"
16230 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16231 (zero_extract:SWI48
16232 (match_operand:SWI48 1 "register_operand")
16233 (const_int 1)
16234 (zero_extend:SI (match_operand:QI 2 "register_operand"))))
16235 (clobber (reg:CC FLAGS_REG))]
16236 "TARGET_USE_BT && ix86_pre_reload_split ()"
16237 "#"
16238 "&& 1"
16239 [(set (reg:CCC FLAGS_REG)
16240 (compare:CCC
16241 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16242 (const_int 0)))
16243 (set (match_dup 0)
16244 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16245 {
16246 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16247 })
16248
16249 ;; Help combine recognize bt followed by setnc
16250 (define_insn_and_split "*bt<mode>_setncqi"
16251 [(set (match_operand:QI 0 "register_operand")
16252 (and:QI
16253 (not:QI
16254 (subreg:QI
16255 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16256 (match_operand:QI 2 "register_operand")) 0))
16257 (const_int 1)))
16258 (clobber (reg:CC FLAGS_REG))]
16259 "TARGET_USE_BT && ix86_pre_reload_split ()"
16260 "#"
16261 "&& 1"
16262 [(set (reg:CCC FLAGS_REG)
16263 (compare:CCC
16264 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16265 (const_int 0)))
16266 (set (match_dup 0)
16267 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16268 {
16269 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16270 })
16271
16272 (define_insn_and_split "*bt<mode>_setnc<mode>"
16273 [(set (match_operand:SWI48 0 "register_operand")
16274 (and:SWI48
16275 (not:SWI48
16276 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16277 (match_operand:QI 2 "register_operand")))
16278 (const_int 1)))
16279 (clobber (reg:CC FLAGS_REG))]
16280 "TARGET_USE_BT && ix86_pre_reload_split ()"
16281 "#"
16282 "&& 1"
16283 [(set (reg:CCC FLAGS_REG)
16284 (compare:CCC
16285 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16286 (const_int 0)))
16287 (set (match_dup 3)
16288 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16289 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16290 {
16291 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16292 operands[3] = gen_reg_rtx (QImode);
16293 })
16294 \f
16295 ;; Store-flag instructions.
16296
16297 (define_split
16298 [(set (match_operand:QI 0 "nonimmediate_operand")
16299 (match_operator:QI 1 "add_comparison_operator"
16300 [(not:SWI (match_operand:SWI 2 "register_operand"))
16301 (match_operand:SWI 3 "nonimmediate_operand")]))]
16302 ""
16303 [(set (reg:CCC FLAGS_REG)
16304 (compare:CCC
16305 (plus:SWI (match_dup 2) (match_dup 3))
16306 (match_dup 2)))
16307 (set (match_dup 0)
16308 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16309
16310 (define_split
16311 [(set (match_operand:QI 0 "nonimmediate_operand")
16312 (match_operator:QI 1 "shr_comparison_operator"
16313 [(match_operand:DI 2 "register_operand")
16314 (match_operand 3 "const_int_operand")]))]
16315 "TARGET_64BIT
16316 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16317 [(set (reg:CCZ FLAGS_REG)
16318 (compare:CCZ
16319 (lshiftrt:DI (match_dup 2) (match_dup 4))
16320 (const_int 0)))
16321 (set (match_dup 0)
16322 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16323 {
16324 enum rtx_code new_code;
16325
16326 operands[1] = shallow_copy_rtx (operands[1]);
16327 switch (GET_CODE (operands[1]))
16328 {
16329 case GTU: new_code = NE; break;
16330 case LEU: new_code = EQ; break;
16331 default: gcc_unreachable ();
16332 }
16333 PUT_CODE (operands[1], new_code);
16334
16335 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16336 })
16337
16338 ;; For all sCOND expanders, also expand the compare or test insn that
16339 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16340
16341 (define_insn_and_split "*setcc_di_1"
16342 [(set (match_operand:DI 0 "register_operand" "=q")
16343 (match_operator:DI 1 "ix86_comparison_operator"
16344 [(reg FLAGS_REG) (const_int 0)]))]
16345 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16346 "#"
16347 "&& reload_completed"
16348 [(set (match_dup 2) (match_dup 1))
16349 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16350 {
16351 operands[1] = shallow_copy_rtx (operands[1]);
16352 PUT_MODE (operands[1], QImode);
16353 operands[2] = gen_lowpart (QImode, operands[0]);
16354 })
16355
16356 (define_insn_and_split "*setcc_<mode>_1_and"
16357 [(set (match_operand:SWI24 0 "register_operand" "=q")
16358 (match_operator:SWI24 1 "ix86_comparison_operator"
16359 [(reg FLAGS_REG) (const_int 0)]))
16360 (clobber (reg:CC FLAGS_REG))]
16361 "!TARGET_PARTIAL_REG_STALL
16362 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16363 "#"
16364 "&& reload_completed"
16365 [(set (match_dup 2) (match_dup 1))
16366 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16367 (clobber (reg:CC FLAGS_REG))])]
16368 {
16369 operands[1] = shallow_copy_rtx (operands[1]);
16370 PUT_MODE (operands[1], QImode);
16371 operands[2] = gen_lowpart (QImode, operands[0]);
16372 })
16373
16374 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16375 [(set (match_operand:SWI24 0 "register_operand" "=q")
16376 (match_operator:SWI24 1 "ix86_comparison_operator"
16377 [(reg FLAGS_REG) (const_int 0)]))]
16378 "!TARGET_PARTIAL_REG_STALL
16379 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16380 "#"
16381 "&& reload_completed"
16382 [(set (match_dup 2) (match_dup 1))
16383 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16384 {
16385 operands[1] = shallow_copy_rtx (operands[1]);
16386 PUT_MODE (operands[1], QImode);
16387 operands[2] = gen_lowpart (QImode, operands[0]);
16388 })
16389
16390 (define_insn "*setcc_qi"
16391 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16392 (match_operator:QI 1 "ix86_comparison_operator"
16393 [(reg FLAGS_REG) (const_int 0)]))]
16394 ""
16395 "set%C1\t%0"
16396 [(set_attr "type" "setcc")
16397 (set_attr "mode" "QI")])
16398
16399 (define_insn "*setcc_qi_slp"
16400 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16401 (match_operator:QI 1 "ix86_comparison_operator"
16402 [(reg FLAGS_REG) (const_int 0)]))]
16403 ""
16404 "set%C1\t%0"
16405 [(set_attr "type" "setcc")
16406 (set_attr "mode" "QI")])
16407
16408 ;; In general it is not safe to assume too much about CCmode registers,
16409 ;; so simplify-rtx stops when it sees a second one. Under certain
16410 ;; conditions this is safe on x86, so help combine not create
16411 ;;
16412 ;; seta %al
16413 ;; testb %al, %al
16414 ;; sete %al
16415
16416 (define_split
16417 [(set (match_operand:QI 0 "nonimmediate_operand")
16418 (ne:QI (match_operator 1 "ix86_comparison_operator"
16419 [(reg FLAGS_REG) (const_int 0)])
16420 (const_int 0)))]
16421 ""
16422 [(set (match_dup 0) (match_dup 1))]
16423 {
16424 operands[1] = shallow_copy_rtx (operands[1]);
16425 PUT_MODE (operands[1], QImode);
16426 })
16427
16428 (define_split
16429 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16430 (ne:QI (match_operator 1 "ix86_comparison_operator"
16431 [(reg FLAGS_REG) (const_int 0)])
16432 (const_int 0)))]
16433 ""
16434 [(set (match_dup 0) (match_dup 1))]
16435 {
16436 operands[1] = shallow_copy_rtx (operands[1]);
16437 PUT_MODE (operands[1], QImode);
16438 })
16439
16440 (define_split
16441 [(set (match_operand:QI 0 "nonimmediate_operand")
16442 (eq:QI (match_operator 1 "ix86_comparison_operator"
16443 [(reg FLAGS_REG) (const_int 0)])
16444 (const_int 0)))]
16445 ""
16446 [(set (match_dup 0) (match_dup 1))]
16447 {
16448 operands[1] = shallow_copy_rtx (operands[1]);
16449 PUT_MODE (operands[1], QImode);
16450 PUT_CODE (operands[1],
16451 ix86_reverse_condition (GET_CODE (operands[1]),
16452 GET_MODE (XEXP (operands[1], 0))));
16453
16454 /* Make sure that (a) the CCmode we have for the flags is strong
16455 enough for the reversed compare or (b) we have a valid FP compare. */
16456 if (! ix86_comparison_operator (operands[1], VOIDmode))
16457 FAIL;
16458 })
16459
16460 (define_split
16461 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16462 (eq:QI (match_operator 1 "ix86_comparison_operator"
16463 [(reg FLAGS_REG) (const_int 0)])
16464 (const_int 0)))]
16465 ""
16466 [(set (match_dup 0) (match_dup 1))]
16467 {
16468 operands[1] = shallow_copy_rtx (operands[1]);
16469 PUT_MODE (operands[1], QImode);
16470 PUT_CODE (operands[1],
16471 ix86_reverse_condition (GET_CODE (operands[1]),
16472 GET_MODE (XEXP (operands[1], 0))));
16473
16474 /* Make sure that (a) the CCmode we have for the flags is strong
16475 enough for the reversed compare or (b) we have a valid FP compare. */
16476 if (! ix86_comparison_operator (operands[1], VOIDmode))
16477 FAIL;
16478 })
16479
16480 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
16481 ;; subsequent logical operations are used to imitate conditional moves.
16482 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
16483 ;; it directly.
16484
16485 (define_insn "setcc_<mode>_sse"
16486 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16487 (match_operator:MODEF 3 "sse_comparison_operator"
16488 [(match_operand:MODEF 1 "register_operand" "0,x")
16489 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
16490 "SSE_FLOAT_MODE_P (<MODE>mode)"
16491 "@
16492 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
16493 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16494 [(set_attr "isa" "noavx,avx")
16495 (set_attr "type" "ssecmp")
16496 (set_attr "length_immediate" "1")
16497 (set_attr "prefix" "orig,vex")
16498 (set_attr "mode" "<MODE>")])
16499
16500 (define_insn "setcc_hf_mask"
16501 [(set (match_operand:QI 0 "register_operand" "=k")
16502 (unspec:QI
16503 [(match_operand:HF 1 "register_operand" "v")
16504 (match_operand:HF 2 "nonimmediate_operand" "vm")
16505 (match_operand:SI 3 "const_0_to_31_operand")]
16506 UNSPEC_PCMP))]
16507 "TARGET_AVX512FP16"
16508 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16509 [(set_attr "type" "ssecmp")
16510 (set_attr "prefix" "evex")
16511 (set_attr "mode" "HF")])
16512
16513 \f
16514 ;; Basic conditional jump instructions.
16515
16516 (define_split
16517 [(set (pc)
16518 (if_then_else
16519 (match_operator 1 "add_comparison_operator"
16520 [(not:SWI (match_operand:SWI 2 "register_operand"))
16521 (match_operand:SWI 3 "nonimmediate_operand")])
16522 (label_ref (match_operand 0))
16523 (pc)))]
16524 ""
16525 [(set (reg:CCC FLAGS_REG)
16526 (compare:CCC
16527 (plus:SWI (match_dup 2) (match_dup 3))
16528 (match_dup 2)))
16529 (set (pc)
16530 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
16531 (label_ref (match_operand 0))
16532 (pc)))])
16533
16534 (define_split
16535 [(set (pc)
16536 (if_then_else
16537 (match_operator 1 "shr_comparison_operator"
16538 [(match_operand:DI 2 "register_operand")
16539 (match_operand 3 "const_int_operand")])
16540 (label_ref (match_operand 0))
16541 (pc)))]
16542 "TARGET_64BIT
16543 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16544 [(set (reg:CCZ FLAGS_REG)
16545 (compare:CCZ
16546 (lshiftrt:DI (match_dup 2) (match_dup 4))
16547 (const_int 0)))
16548 (set (pc)
16549 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
16550 (label_ref (match_operand 0))
16551 (pc)))]
16552 {
16553 enum rtx_code new_code;
16554
16555 operands[1] = shallow_copy_rtx (operands[1]);
16556 switch (GET_CODE (operands[1]))
16557 {
16558 case GTU: new_code = NE; break;
16559 case LEU: new_code = EQ; break;
16560 default: gcc_unreachable ();
16561 }
16562 PUT_CODE (operands[1], new_code);
16563
16564 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16565 })
16566
16567 ;; We ignore the overflow flag for signed branch instructions.
16568
16569 (define_insn "*jcc"
16570 [(set (pc)
16571 (if_then_else (match_operator 1 "ix86_comparison_operator"
16572 [(reg FLAGS_REG) (const_int 0)])
16573 (label_ref (match_operand 0))
16574 (pc)))]
16575 ""
16576 "%!%+j%C1\t%l0"
16577 [(set_attr "type" "ibr")
16578 (set_attr "modrm" "0")
16579 (set (attr "length")
16580 (if_then_else
16581 (and (ge (minus (match_dup 0) (pc))
16582 (const_int -126))
16583 (lt (minus (match_dup 0) (pc))
16584 (const_int 128)))
16585 (const_int 2)
16586 (const_int 6)))])
16587
16588 ;; In general it is not safe to assume too much about CCmode registers,
16589 ;; so simplify-rtx stops when it sees a second one. Under certain
16590 ;; conditions this is safe on x86, so help combine not create
16591 ;;
16592 ;; seta %al
16593 ;; testb %al, %al
16594 ;; je Lfoo
16595
16596 (define_split
16597 [(set (pc)
16598 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
16599 [(reg FLAGS_REG) (const_int 0)])
16600 (const_int 0))
16601 (label_ref (match_operand 1))
16602 (pc)))]
16603 ""
16604 [(set (pc)
16605 (if_then_else (match_dup 0)
16606 (label_ref (match_dup 1))
16607 (pc)))]
16608 {
16609 operands[0] = shallow_copy_rtx (operands[0]);
16610 PUT_MODE (operands[0], VOIDmode);
16611 })
16612
16613 (define_split
16614 [(set (pc)
16615 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
16616 [(reg FLAGS_REG) (const_int 0)])
16617 (const_int 0))
16618 (label_ref (match_operand 1))
16619 (pc)))]
16620 ""
16621 [(set (pc)
16622 (if_then_else (match_dup 0)
16623 (label_ref (match_dup 1))
16624 (pc)))]
16625 {
16626 operands[0] = shallow_copy_rtx (operands[0]);
16627 PUT_MODE (operands[0], VOIDmode);
16628 PUT_CODE (operands[0],
16629 ix86_reverse_condition (GET_CODE (operands[0]),
16630 GET_MODE (XEXP (operands[0], 0))));
16631
16632 /* Make sure that (a) the CCmode we have for the flags is strong
16633 enough for the reversed compare or (b) we have a valid FP compare. */
16634 if (! ix86_comparison_operator (operands[0], VOIDmode))
16635 FAIL;
16636 })
16637 \f
16638 ;; Unconditional and other jump instructions
16639
16640 (define_insn "jump"
16641 [(set (pc)
16642 (label_ref (match_operand 0)))]
16643 ""
16644 "%!jmp\t%l0"
16645 [(set_attr "type" "ibr")
16646 (set_attr "modrm" "0")
16647 (set (attr "length")
16648 (if_then_else
16649 (and (ge (minus (match_dup 0) (pc))
16650 (const_int -126))
16651 (lt (minus (match_dup 0) (pc))
16652 (const_int 128)))
16653 (const_int 2)
16654 (const_int 5)))])
16655
16656 (define_expand "indirect_jump"
16657 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
16658 ""
16659 {
16660 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16661 operands[0] = convert_memory_address (word_mode, operands[0]);
16662 cfun->machine->has_local_indirect_jump = true;
16663 })
16664
16665 (define_insn "*indirect_jump"
16666 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
16667 ""
16668 "* return ix86_output_indirect_jmp (operands[0]);"
16669 [(set (attr "type")
16670 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16671 != indirect_branch_keep)")
16672 (const_string "multi")
16673 (const_string "ibr")))
16674 (set_attr "length_immediate" "0")])
16675
16676 (define_expand "tablejump"
16677 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
16678 (use (label_ref (match_operand 1)))])]
16679 ""
16680 {
16681 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
16682 relative. Convert the relative address to an absolute address. */
16683 if (flag_pic)
16684 {
16685 rtx op0, op1;
16686 enum rtx_code code;
16687
16688 /* We can't use @GOTOFF for text labels on VxWorks;
16689 see gotoff_operand. */
16690 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
16691 {
16692 code = PLUS;
16693 op0 = operands[0];
16694 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
16695 }
16696 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
16697 {
16698 code = PLUS;
16699 op0 = operands[0];
16700 op1 = pic_offset_table_rtx;
16701 }
16702 else
16703 {
16704 code = MINUS;
16705 op0 = pic_offset_table_rtx;
16706 op1 = operands[0];
16707 }
16708
16709 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
16710 OPTAB_DIRECT);
16711 }
16712
16713 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16714 operands[0] = convert_memory_address (word_mode, operands[0]);
16715 cfun->machine->has_local_indirect_jump = true;
16716 })
16717
16718 (define_insn "*tablejump_1"
16719 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
16720 (use (label_ref (match_operand 1)))]
16721 ""
16722 "* return ix86_output_indirect_jmp (operands[0]);"
16723 [(set (attr "type")
16724 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16725 != indirect_branch_keep)")
16726 (const_string "multi")
16727 (const_string "ibr")))
16728 (set_attr "length_immediate" "0")])
16729 \f
16730 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
16731
16732 (define_peephole2
16733 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
16734 (set (match_operand:QI 1 "register_operand")
16735 (match_operator:QI 2 "ix86_comparison_operator"
16736 [(reg FLAGS_REG) (const_int 0)]))
16737 (set (match_operand 3 "any_QIreg_operand")
16738 (zero_extend (match_dup 1)))]
16739 "(peep2_reg_dead_p (3, operands[1])
16740 || operands_match_p (operands[1], operands[3]))
16741 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16742 && peep2_regno_dead_p (0, FLAGS_REG)"
16743 [(set (match_dup 4) (match_dup 0))
16744 (set (strict_low_part (match_dup 5))
16745 (match_dup 2))]
16746 {
16747 operands[5] = gen_lowpart (QImode, operands[3]);
16748 ix86_expand_clear (operands[3]);
16749 })
16750
16751 (define_peephole2
16752 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
16753 (match_operand 4)])
16754 (set (match_operand:QI 1 "register_operand")
16755 (match_operator:QI 2 "ix86_comparison_operator"
16756 [(reg FLAGS_REG) (const_int 0)]))
16757 (set (match_operand 3 "any_QIreg_operand")
16758 (zero_extend (match_dup 1)))]
16759 "(peep2_reg_dead_p (3, operands[1])
16760 || operands_match_p (operands[1], operands[3]))
16761 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16762 && ! reg_overlap_mentioned_p (operands[3], operands[4])
16763 && ! reg_set_p (operands[3], operands[4])
16764 && peep2_regno_dead_p (0, FLAGS_REG)"
16765 [(parallel [(set (match_dup 5) (match_dup 0))
16766 (match_dup 4)])
16767 (set (strict_low_part (match_dup 6))
16768 (match_dup 2))]
16769 {
16770 operands[6] = gen_lowpart (QImode, operands[3]);
16771 ix86_expand_clear (operands[3]);
16772 })
16773
16774 (define_peephole2
16775 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
16776 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
16777 (match_operand 5)])
16778 (set (match_operand:QI 2 "register_operand")
16779 (match_operator:QI 3 "ix86_comparison_operator"
16780 [(reg FLAGS_REG) (const_int 0)]))
16781 (set (match_operand 4 "any_QIreg_operand")
16782 (zero_extend (match_dup 2)))]
16783 "(peep2_reg_dead_p (4, operands[2])
16784 || operands_match_p (operands[2], operands[4]))
16785 && ! reg_overlap_mentioned_p (operands[4], operands[0])
16786 && ! reg_overlap_mentioned_p (operands[4], operands[1])
16787 && ! reg_overlap_mentioned_p (operands[4], operands[5])
16788 && ! reg_set_p (operands[4], operands[5])
16789 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
16790 && peep2_regno_dead_p (0, FLAGS_REG)"
16791 [(set (match_dup 6) (match_dup 0))
16792 (parallel [(set (match_dup 7) (match_dup 1))
16793 (match_dup 5)])
16794 (set (strict_low_part (match_dup 8))
16795 (match_dup 3))]
16796 {
16797 operands[8] = gen_lowpart (QImode, operands[4]);
16798 ix86_expand_clear (operands[4]);
16799 })
16800
16801 ;; Similar, but match zero extend with andsi3.
16802
16803 (define_peephole2
16804 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
16805 (set (match_operand:QI 1 "register_operand")
16806 (match_operator:QI 2 "ix86_comparison_operator"
16807 [(reg FLAGS_REG) (const_int 0)]))
16808 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
16809 (and:SI (match_dup 3) (const_int 255)))
16810 (clobber (reg:CC FLAGS_REG))])]
16811 "REGNO (operands[1]) == REGNO (operands[3])
16812 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16813 && peep2_regno_dead_p (0, FLAGS_REG)"
16814 [(set (match_dup 4) (match_dup 0))
16815 (set (strict_low_part (match_dup 5))
16816 (match_dup 2))]
16817 {
16818 operands[5] = gen_lowpart (QImode, operands[3]);
16819 ix86_expand_clear (operands[3]);
16820 })
16821
16822 (define_peephole2
16823 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
16824 (match_operand 4)])
16825 (set (match_operand:QI 1 "register_operand")
16826 (match_operator:QI 2 "ix86_comparison_operator"
16827 [(reg FLAGS_REG) (const_int 0)]))
16828 (parallel [(set (match_operand 3 "any_QIreg_operand")
16829 (zero_extend (match_dup 1)))
16830 (clobber (reg:CC FLAGS_REG))])]
16831 "(peep2_reg_dead_p (3, operands[1])
16832 || operands_match_p (operands[1], operands[3]))
16833 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16834 && ! reg_overlap_mentioned_p (operands[3], operands[4])
16835 && ! reg_set_p (operands[3], operands[4])
16836 && peep2_regno_dead_p (0, FLAGS_REG)"
16837 [(parallel [(set (match_dup 5) (match_dup 0))
16838 (match_dup 4)])
16839 (set (strict_low_part (match_dup 6))
16840 (match_dup 2))]
16841 {
16842 operands[6] = gen_lowpart (QImode, operands[3]);
16843 ix86_expand_clear (operands[3]);
16844 })
16845
16846 (define_peephole2
16847 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
16848 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
16849 (match_operand 5)])
16850 (set (match_operand:QI 2 "register_operand")
16851 (match_operator:QI 3 "ix86_comparison_operator"
16852 [(reg FLAGS_REG) (const_int 0)]))
16853 (parallel [(set (match_operand 4 "any_QIreg_operand")
16854 (zero_extend (match_dup 2)))
16855 (clobber (reg:CC FLAGS_REG))])]
16856 "(peep2_reg_dead_p (4, operands[2])
16857 || operands_match_p (operands[2], operands[4]))
16858 && ! reg_overlap_mentioned_p (operands[4], operands[0])
16859 && ! reg_overlap_mentioned_p (operands[4], operands[1])
16860 && ! reg_overlap_mentioned_p (operands[4], operands[5])
16861 && ! reg_set_p (operands[4], operands[5])
16862 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
16863 && peep2_regno_dead_p (0, FLAGS_REG)"
16864 [(set (match_dup 6) (match_dup 0))
16865 (parallel [(set (match_dup 7) (match_dup 1))
16866 (match_dup 5)])
16867 (set (strict_low_part (match_dup 8))
16868 (match_dup 3))]
16869 {
16870 operands[8] = gen_lowpart (QImode, operands[4]);
16871 ix86_expand_clear (operands[4]);
16872 })
16873 \f
16874 ;; Call instructions.
16875
16876 ;; The predicates normally associated with named expanders are not properly
16877 ;; checked for calls. This is a bug in the generic code, but it isn't that
16878 ;; easy to fix. Ignore it for now and be prepared to fix things up.
16879
16880 ;; P6 processors will jump to the address after the decrement when %esp
16881 ;; is used as a call operand, so they will execute return address as a code.
16882 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
16883
16884 ;; Register constraint for call instruction.
16885 (define_mode_attr c [(SI "l") (DI "r")])
16886
16887 ;; Call subroutine returning no value.
16888
16889 (define_expand "call"
16890 [(call (match_operand:QI 0)
16891 (match_operand 1))
16892 (use (match_operand 2))]
16893 ""
16894 {
16895 ix86_expand_call (NULL, operands[0], operands[1],
16896 operands[2], NULL, false);
16897 DONE;
16898 })
16899
16900 (define_expand "sibcall"
16901 [(call (match_operand:QI 0)
16902 (match_operand 1))
16903 (use (match_operand 2))]
16904 ""
16905 {
16906 ix86_expand_call (NULL, operands[0], operands[1],
16907 operands[2], NULL, true);
16908 DONE;
16909 })
16910
16911 (define_insn "*call"
16912 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
16913 (match_operand 1))]
16914 "!SIBLING_CALL_P (insn)"
16915 "* return ix86_output_call_insn (insn, operands[0]);"
16916 [(set_attr "type" "call")])
16917
16918 ;; This covers both call and sibcall since only GOT slot is allowed.
16919 (define_insn "*call_got_x32"
16920 [(call (mem:QI (zero_extend:DI
16921 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
16922 (match_operand 1))]
16923 "TARGET_X32"
16924 {
16925 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
16926 return ix86_output_call_insn (insn, fnaddr);
16927 }
16928 [(set_attr "type" "call")])
16929
16930 ;; Since sibcall never returns, we can only use call-clobbered register
16931 ;; as GOT base.
16932 (define_insn "*sibcall_GOT_32"
16933 [(call (mem:QI
16934 (mem:SI (plus:SI
16935 (match_operand:SI 0 "register_no_elim_operand" "U")
16936 (match_operand:SI 1 "GOT32_symbol_operand"))))
16937 (match_operand 2))]
16938 "!TARGET_MACHO
16939 && !TARGET_64BIT
16940 && !TARGET_INDIRECT_BRANCH_REGISTER
16941 && SIBLING_CALL_P (insn)"
16942 {
16943 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
16944 fnaddr = gen_const_mem (SImode, fnaddr);
16945 return ix86_output_call_insn (insn, fnaddr);
16946 }
16947 [(set_attr "type" "call")])
16948
16949 (define_insn "*sibcall"
16950 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
16951 (match_operand 1))]
16952 "SIBLING_CALL_P (insn)"
16953 "* return ix86_output_call_insn (insn, operands[0]);"
16954 [(set_attr "type" "call")])
16955
16956 (define_insn "*sibcall_memory"
16957 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
16958 (match_operand 1))
16959 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
16960 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
16961 "* return ix86_output_call_insn (insn, operands[0]);"
16962 [(set_attr "type" "call")])
16963
16964 (define_peephole2
16965 [(set (match_operand:W 0 "register_operand")
16966 (match_operand:W 1 "memory_operand"))
16967 (call (mem:QI (match_dup 0))
16968 (match_operand 3))]
16969 "!TARGET_X32
16970 && !TARGET_INDIRECT_BRANCH_REGISTER
16971 && SIBLING_CALL_P (peep2_next_insn (1))
16972 && !reg_mentioned_p (operands[0],
16973 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
16974 [(parallel [(call (mem:QI (match_dup 1))
16975 (match_dup 3))
16976 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
16977
16978 (define_peephole2
16979 [(set (match_operand:W 0 "register_operand")
16980 (match_operand:W 1 "memory_operand"))
16981 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
16982 (call (mem:QI (match_dup 0))
16983 (match_operand 3))]
16984 "!TARGET_X32
16985 && !TARGET_INDIRECT_BRANCH_REGISTER
16986 && SIBLING_CALL_P (peep2_next_insn (2))
16987 && !reg_mentioned_p (operands[0],
16988 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
16989 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
16990 (parallel [(call (mem:QI (match_dup 1))
16991 (match_dup 3))
16992 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
16993
16994 (define_expand "call_pop"
16995 [(parallel [(call (match_operand:QI 0)
16996 (match_operand:SI 1))
16997 (set (reg:SI SP_REG)
16998 (plus:SI (reg:SI SP_REG)
16999 (match_operand:SI 3)))])]
17000 "!TARGET_64BIT"
17001 {
17002 ix86_expand_call (NULL, operands[0], operands[1],
17003 operands[2], operands[3], false);
17004 DONE;
17005 })
17006
17007 (define_insn "*call_pop"
17008 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
17009 (match_operand 1))
17010 (set (reg:SI SP_REG)
17011 (plus:SI (reg:SI SP_REG)
17012 (match_operand:SI 2 "immediate_operand" "i")))]
17013 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17014 "* return ix86_output_call_insn (insn, operands[0]);"
17015 [(set_attr "type" "call")])
17016
17017 (define_insn "*sibcall_pop"
17018 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
17019 (match_operand 1))
17020 (set (reg:SI SP_REG)
17021 (plus:SI (reg:SI SP_REG)
17022 (match_operand:SI 2 "immediate_operand" "i")))]
17023 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17024 "* return ix86_output_call_insn (insn, operands[0]);"
17025 [(set_attr "type" "call")])
17026
17027 (define_insn "*sibcall_pop_memory"
17028 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
17029 (match_operand 1))
17030 (set (reg:SI SP_REG)
17031 (plus:SI (reg:SI SP_REG)
17032 (match_operand:SI 2 "immediate_operand" "i")))
17033 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17034 "!TARGET_64BIT"
17035 "* return ix86_output_call_insn (insn, operands[0]);"
17036 [(set_attr "type" "call")])
17037
17038 (define_peephole2
17039 [(set (match_operand:SI 0 "register_operand")
17040 (match_operand:SI 1 "memory_operand"))
17041 (parallel [(call (mem:QI (match_dup 0))
17042 (match_operand 3))
17043 (set (reg:SI SP_REG)
17044 (plus:SI (reg:SI SP_REG)
17045 (match_operand:SI 4 "immediate_operand")))])]
17046 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17047 && !reg_mentioned_p (operands[0],
17048 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17049 [(parallel [(call (mem:QI (match_dup 1))
17050 (match_dup 3))
17051 (set (reg:SI SP_REG)
17052 (plus:SI (reg:SI SP_REG)
17053 (match_dup 4)))
17054 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17055
17056 (define_peephole2
17057 [(set (match_operand:SI 0 "register_operand")
17058 (match_operand:SI 1 "memory_operand"))
17059 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17060 (parallel [(call (mem:QI (match_dup 0))
17061 (match_operand 3))
17062 (set (reg:SI SP_REG)
17063 (plus:SI (reg:SI SP_REG)
17064 (match_operand:SI 4 "immediate_operand")))])]
17065 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17066 && !reg_mentioned_p (operands[0],
17067 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17068 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17069 (parallel [(call (mem:QI (match_dup 1))
17070 (match_dup 3))
17071 (set (reg:SI SP_REG)
17072 (plus:SI (reg:SI SP_REG)
17073 (match_dup 4)))
17074 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17075
17076 ;; Combining simple memory jump instruction
17077
17078 (define_peephole2
17079 [(set (match_operand:W 0 "register_operand")
17080 (match_operand:W 1 "memory_operand"))
17081 (set (pc) (match_dup 0))]
17082 "!TARGET_X32
17083 && !TARGET_INDIRECT_BRANCH_REGISTER
17084 && peep2_reg_dead_p (2, operands[0])"
17085 [(set (pc) (match_dup 1))])
17086
17087 ;; Call subroutine, returning value in operand 0
17088
17089 (define_expand "call_value"
17090 [(set (match_operand 0)
17091 (call (match_operand:QI 1)
17092 (match_operand 2)))
17093 (use (match_operand 3))]
17094 ""
17095 {
17096 ix86_expand_call (operands[0], operands[1], operands[2],
17097 operands[3], NULL, false);
17098 DONE;
17099 })
17100
17101 (define_expand "sibcall_value"
17102 [(set (match_operand 0)
17103 (call (match_operand:QI 1)
17104 (match_operand 2)))
17105 (use (match_operand 3))]
17106 ""
17107 {
17108 ix86_expand_call (operands[0], operands[1], operands[2],
17109 operands[3], NULL, true);
17110 DONE;
17111 })
17112
17113 (define_insn "*call_value"
17114 [(set (match_operand 0)
17115 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17116 (match_operand 2)))]
17117 "!SIBLING_CALL_P (insn)"
17118 "* return ix86_output_call_insn (insn, operands[1]);"
17119 [(set_attr "type" "callv")])
17120
17121 ;; This covers both call and sibcall since only GOT slot is allowed.
17122 (define_insn "*call_value_got_x32"
17123 [(set (match_operand 0)
17124 (call (mem:QI
17125 (zero_extend:DI
17126 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17127 (match_operand 2)))]
17128 "TARGET_X32"
17129 {
17130 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17131 return ix86_output_call_insn (insn, fnaddr);
17132 }
17133 [(set_attr "type" "callv")])
17134
17135 ;; Since sibcall never returns, we can only use call-clobbered register
17136 ;; as GOT base.
17137 (define_insn "*sibcall_value_GOT_32"
17138 [(set (match_operand 0)
17139 (call (mem:QI
17140 (mem:SI (plus:SI
17141 (match_operand:SI 1 "register_no_elim_operand" "U")
17142 (match_operand:SI 2 "GOT32_symbol_operand"))))
17143 (match_operand 3)))]
17144 "!TARGET_MACHO
17145 && !TARGET_64BIT
17146 && !TARGET_INDIRECT_BRANCH_REGISTER
17147 && SIBLING_CALL_P (insn)"
17148 {
17149 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17150 fnaddr = gen_const_mem (SImode, fnaddr);
17151 return ix86_output_call_insn (insn, fnaddr);
17152 }
17153 [(set_attr "type" "callv")])
17154
17155 (define_insn "*sibcall_value"
17156 [(set (match_operand 0)
17157 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17158 (match_operand 2)))]
17159 "SIBLING_CALL_P (insn)"
17160 "* return ix86_output_call_insn (insn, operands[1]);"
17161 [(set_attr "type" "callv")])
17162
17163 (define_insn "*sibcall_value_memory"
17164 [(set (match_operand 0)
17165 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17166 (match_operand 2)))
17167 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17168 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17169 "* return ix86_output_call_insn (insn, operands[1]);"
17170 [(set_attr "type" "callv")])
17171
17172 (define_peephole2
17173 [(set (match_operand:W 0 "register_operand")
17174 (match_operand:W 1 "memory_operand"))
17175 (set (match_operand 2)
17176 (call (mem:QI (match_dup 0))
17177 (match_operand 3)))]
17178 "!TARGET_X32
17179 && !TARGET_INDIRECT_BRANCH_REGISTER
17180 && SIBLING_CALL_P (peep2_next_insn (1))
17181 && !reg_mentioned_p (operands[0],
17182 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17183 [(parallel [(set (match_dup 2)
17184 (call (mem:QI (match_dup 1))
17185 (match_dup 3)))
17186 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17187
17188 (define_peephole2
17189 [(set (match_operand:W 0 "register_operand")
17190 (match_operand:W 1 "memory_operand"))
17191 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17192 (set (match_operand 2)
17193 (call (mem:QI (match_dup 0))
17194 (match_operand 3)))]
17195 "!TARGET_X32
17196 && !TARGET_INDIRECT_BRANCH_REGISTER
17197 && SIBLING_CALL_P (peep2_next_insn (2))
17198 && !reg_mentioned_p (operands[0],
17199 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17200 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17201 (parallel [(set (match_dup 2)
17202 (call (mem:QI (match_dup 1))
17203 (match_dup 3)))
17204 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17205
17206 (define_expand "call_value_pop"
17207 [(parallel [(set (match_operand 0)
17208 (call (match_operand:QI 1)
17209 (match_operand:SI 2)))
17210 (set (reg:SI SP_REG)
17211 (plus:SI (reg:SI SP_REG)
17212 (match_operand:SI 4)))])]
17213 "!TARGET_64BIT"
17214 {
17215 ix86_expand_call (operands[0], operands[1], operands[2],
17216 operands[3], operands[4], false);
17217 DONE;
17218 })
17219
17220 (define_insn "*call_value_pop"
17221 [(set (match_operand 0)
17222 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17223 (match_operand 2)))
17224 (set (reg:SI SP_REG)
17225 (plus:SI (reg:SI SP_REG)
17226 (match_operand:SI 3 "immediate_operand" "i")))]
17227 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17228 "* return ix86_output_call_insn (insn, operands[1]);"
17229 [(set_attr "type" "callv")])
17230
17231 (define_insn "*sibcall_value_pop"
17232 [(set (match_operand 0)
17233 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17234 (match_operand 2)))
17235 (set (reg:SI SP_REG)
17236 (plus:SI (reg:SI SP_REG)
17237 (match_operand:SI 3 "immediate_operand" "i")))]
17238 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17239 "* return ix86_output_call_insn (insn, operands[1]);"
17240 [(set_attr "type" "callv")])
17241
17242 (define_insn "*sibcall_value_pop_memory"
17243 [(set (match_operand 0)
17244 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17245 (match_operand 2)))
17246 (set (reg:SI SP_REG)
17247 (plus:SI (reg:SI SP_REG)
17248 (match_operand:SI 3 "immediate_operand" "i")))
17249 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17250 "!TARGET_64BIT"
17251 "* return ix86_output_call_insn (insn, operands[1]);"
17252 [(set_attr "type" "callv")])
17253
17254 (define_peephole2
17255 [(set (match_operand:SI 0 "register_operand")
17256 (match_operand:SI 1 "memory_operand"))
17257 (parallel [(set (match_operand 2)
17258 (call (mem:QI (match_dup 0))
17259 (match_operand 3)))
17260 (set (reg:SI SP_REG)
17261 (plus:SI (reg:SI SP_REG)
17262 (match_operand:SI 4 "immediate_operand")))])]
17263 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17264 && !reg_mentioned_p (operands[0],
17265 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17266 [(parallel [(set (match_dup 2)
17267 (call (mem:QI (match_dup 1))
17268 (match_dup 3)))
17269 (set (reg:SI SP_REG)
17270 (plus:SI (reg:SI SP_REG)
17271 (match_dup 4)))
17272 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17273
17274 (define_peephole2
17275 [(set (match_operand:SI 0 "register_operand")
17276 (match_operand:SI 1 "memory_operand"))
17277 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17278 (parallel [(set (match_operand 2)
17279 (call (mem:QI (match_dup 0))
17280 (match_operand 3)))
17281 (set (reg:SI SP_REG)
17282 (plus:SI (reg:SI SP_REG)
17283 (match_operand:SI 4 "immediate_operand")))])]
17284 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17285 && !reg_mentioned_p (operands[0],
17286 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17287 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17288 (parallel [(set (match_dup 2)
17289 (call (mem:QI (match_dup 1))
17290 (match_dup 3)))
17291 (set (reg:SI SP_REG)
17292 (plus:SI (reg:SI SP_REG)
17293 (match_dup 4)))
17294 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17295
17296 ;; Call subroutine returning any type.
17297
17298 (define_expand "untyped_call"
17299 [(parallel [(call (match_operand 0)
17300 (const_int 0))
17301 (match_operand 1)
17302 (match_operand 2)])]
17303 ""
17304 {
17305 int i;
17306
17307 /* In order to give reg-stack an easier job in validating two
17308 coprocessor registers as containing a possible return value,
17309 simply pretend the untyped call returns a complex long double
17310 value.
17311
17312 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17313 and should have the default ABI. */
17314
17315 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17316 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17317 operands[0], const0_rtx,
17318 GEN_INT ((TARGET_64BIT
17319 ? (ix86_abi == SYSV_ABI
17320 ? X86_64_SSE_REGPARM_MAX
17321 : X86_64_MS_SSE_REGPARM_MAX)
17322 : X86_32_SSE_REGPARM_MAX)
17323 - 1),
17324 NULL, false);
17325
17326 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17327 {
17328 rtx set = XVECEXP (operands[2], 0, i);
17329 emit_move_insn (SET_DEST (set), SET_SRC (set));
17330 }
17331
17332 /* The optimizer does not know that the call sets the function value
17333 registers we stored in the result block. We avoid problems by
17334 claiming that all hard registers are used and clobbered at this
17335 point. */
17336 emit_insn (gen_blockage ());
17337
17338 DONE;
17339 })
17340 \f
17341 ;; Prologue and epilogue instructions
17342
17343 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17344 ;; all of memory. This blocks insns from being moved across this point.
17345
17346 (define_insn "blockage"
17347 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17348 ""
17349 ""
17350 [(set_attr "length" "0")])
17351
17352 ;; Do not schedule instructions accessing memory across this point.
17353
17354 (define_expand "memory_blockage"
17355 [(set (match_dup 0)
17356 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17357 ""
17358 {
17359 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17360 MEM_VOLATILE_P (operands[0]) = 1;
17361 })
17362
17363 (define_insn "*memory_blockage"
17364 [(set (match_operand:BLK 0)
17365 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17366 ""
17367 ""
17368 [(set_attr "length" "0")])
17369
17370 ;; As USE insns aren't meaningful after reload, this is used instead
17371 ;; to prevent deleting instructions setting registers for PIC code
17372 (define_insn "prologue_use"
17373 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17374 ""
17375 ""
17376 [(set_attr "length" "0")])
17377
17378 ;; Insn emitted into the body of a function to return from a function.
17379 ;; This is only done if the function's epilogue is known to be simple.
17380 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17381
17382 (define_expand "return"
17383 [(simple_return)]
17384 "ix86_can_use_return_insn_p ()"
17385 {
17386 if (crtl->args.pops_args)
17387 {
17388 rtx popc = GEN_INT (crtl->args.pops_args);
17389 emit_jump_insn (gen_simple_return_pop_internal (popc));
17390 DONE;
17391 }
17392 })
17393
17394 ;; We need to disable this for TARGET_SEH, as otherwise
17395 ;; shrink-wrapped prologue gets enabled too. This might exceed
17396 ;; the maximum size of prologue in unwind information.
17397 ;; Also disallow shrink-wrapping if using stack slot to pass the
17398 ;; static chain pointer - the first instruction has to be pushl %esi
17399 ;; and it can't be moved around, as we use alternate entry points
17400 ;; in that case.
17401 ;; Also disallow for ms_hook_prologue functions which have frame
17402 ;; pointer set up in function label which is correctly handled in
17403 ;; ix86_expand_{prologue|epligoue}() only.
17404
17405 (define_expand "simple_return"
17406 [(simple_return)]
17407 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17408 {
17409 if (crtl->args.pops_args)
17410 {
17411 rtx popc = GEN_INT (crtl->args.pops_args);
17412 emit_jump_insn (gen_simple_return_pop_internal (popc));
17413 DONE;
17414 }
17415 })
17416
17417 (define_insn "simple_return_internal"
17418 [(simple_return)]
17419 "reload_completed"
17420 "* return ix86_output_function_return (false);"
17421 [(set_attr "length" "1")
17422 (set_attr "atom_unit" "jeu")
17423 (set_attr "length_immediate" "0")
17424 (set_attr "modrm" "0")])
17425
17426 (define_insn "interrupt_return"
17427 [(simple_return)
17428 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17429 "reload_completed"
17430 {
17431 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17432 })
17433
17434 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17435 ;; instruction Athlon and K8 have.
17436
17437 (define_insn "simple_return_internal_long"
17438 [(simple_return)
17439 (unspec [(const_int 0)] UNSPEC_REP)]
17440 "reload_completed"
17441 "* return ix86_output_function_return (true);"
17442 [(set_attr "length" "2")
17443 (set_attr "atom_unit" "jeu")
17444 (set_attr "length_immediate" "0")
17445 (set_attr "prefix_rep" "1")
17446 (set_attr "modrm" "0")])
17447
17448 (define_insn_and_split "simple_return_pop_internal"
17449 [(simple_return)
17450 (use (match_operand:SI 0 "const_int_operand"))]
17451 "reload_completed"
17452 "ret\t%0"
17453 "&& cfun->machine->function_return_type != indirect_branch_keep"
17454 [(const_int 0)]
17455 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17456 [(set_attr "length" "3")
17457 (set_attr "atom_unit" "jeu")
17458 (set_attr "length_immediate" "2")
17459 (set_attr "modrm" "0")])
17460
17461 (define_expand "simple_return_indirect_internal"
17462 [(parallel
17463 [(simple_return)
17464 (use (match_operand 0 "register_operand"))])])
17465
17466 (define_insn "*simple_return_indirect_internal<mode>"
17467 [(simple_return)
17468 (use (match_operand:W 0 "register_operand" "r"))]
17469 "reload_completed"
17470 "* return ix86_output_indirect_function_return (operands[0]);"
17471 [(set (attr "type")
17472 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17473 != indirect_branch_keep)")
17474 (const_string "multi")
17475 (const_string "ibr")))
17476 (set_attr "length_immediate" "0")])
17477
17478 (define_insn "nop"
17479 [(const_int 0)]
17480 ""
17481 "nop"
17482 [(set_attr "length" "1")
17483 (set_attr "length_immediate" "0")
17484 (set_attr "modrm" "0")])
17485
17486 ;; Generate nops. Operand 0 is the number of nops, up to 8.
17487 (define_insn "nops"
17488 [(unspec_volatile [(match_operand 0 "const_int_operand")]
17489 UNSPECV_NOPS)]
17490 "reload_completed"
17491 {
17492 int num = INTVAL (operands[0]);
17493
17494 gcc_assert (IN_RANGE (num, 1, 8));
17495
17496 while (num--)
17497 fputs ("\tnop\n", asm_out_file);
17498
17499 return "";
17500 }
17501 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
17502 (set_attr "length_immediate" "0")
17503 (set_attr "modrm" "0")])
17504
17505 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
17506 ;; branch prediction penalty for the third jump in a 16-byte
17507 ;; block on K8.
17508
17509 (define_insn "pad"
17510 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
17511 ""
17512 {
17513 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
17514 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
17515 #else
17516 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
17517 The align insn is used to avoid 3 jump instructions in the row to improve
17518 branch prediction and the benefits hardly outweigh the cost of extra 8
17519 nops on the average inserted by full alignment pseudo operation. */
17520 #endif
17521 return "";
17522 }
17523 [(set_attr "length" "16")])
17524
17525 (define_expand "prologue"
17526 [(const_int 0)]
17527 ""
17528 "ix86_expand_prologue (); DONE;")
17529
17530 (define_expand "set_got"
17531 [(parallel
17532 [(set (match_operand:SI 0 "register_operand")
17533 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17534 (clobber (reg:CC FLAGS_REG))])]
17535 "!TARGET_64BIT"
17536 {
17537 if (flag_pic && !TARGET_VXWORKS_RTP)
17538 ix86_pc_thunk_call_expanded = true;
17539 })
17540
17541 (define_insn "*set_got"
17542 [(set (match_operand:SI 0 "register_operand" "=r")
17543 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17544 (clobber (reg:CC FLAGS_REG))]
17545 "!TARGET_64BIT"
17546 "* return output_set_got (operands[0], NULL_RTX);"
17547 [(set_attr "type" "multi")
17548 (set_attr "length" "12")])
17549
17550 (define_expand "set_got_labelled"
17551 [(parallel
17552 [(set (match_operand:SI 0 "register_operand")
17553 (unspec:SI [(label_ref (match_operand 1))]
17554 UNSPEC_SET_GOT))
17555 (clobber (reg:CC FLAGS_REG))])]
17556 "!TARGET_64BIT"
17557 {
17558 if (flag_pic && !TARGET_VXWORKS_RTP)
17559 ix86_pc_thunk_call_expanded = true;
17560 })
17561
17562 (define_insn "*set_got_labelled"
17563 [(set (match_operand:SI 0 "register_operand" "=r")
17564 (unspec:SI [(label_ref (match_operand 1))]
17565 UNSPEC_SET_GOT))
17566 (clobber (reg:CC FLAGS_REG))]
17567 "!TARGET_64BIT"
17568 "* return output_set_got (operands[0], operands[1]);"
17569 [(set_attr "type" "multi")
17570 (set_attr "length" "12")])
17571
17572 (define_insn "set_got_rex64"
17573 [(set (match_operand:DI 0 "register_operand" "=r")
17574 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
17575 "TARGET_64BIT"
17576 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
17577 [(set_attr "type" "lea")
17578 (set_attr "length_address" "4")
17579 (set_attr "mode" "DI")])
17580
17581 (define_insn "set_rip_rex64"
17582 [(set (match_operand:DI 0 "register_operand" "=r")
17583 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
17584 "TARGET_64BIT"
17585 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
17586 [(set_attr "type" "lea")
17587 (set_attr "length_address" "4")
17588 (set_attr "mode" "DI")])
17589
17590 (define_insn "set_got_offset_rex64"
17591 [(set (match_operand:DI 0 "register_operand" "=r")
17592 (unspec:DI
17593 [(label_ref (match_operand 1))]
17594 UNSPEC_SET_GOT_OFFSET))]
17595 "TARGET_LP64"
17596 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
17597 [(set_attr "type" "imov")
17598 (set_attr "length_immediate" "0")
17599 (set_attr "length_address" "8")
17600 (set_attr "mode" "DI")])
17601
17602 (define_expand "epilogue"
17603 [(const_int 0)]
17604 ""
17605 "ix86_expand_epilogue (1); DONE;")
17606
17607 (define_expand "sibcall_epilogue"
17608 [(const_int 0)]
17609 ""
17610 "ix86_expand_epilogue (0); DONE;")
17611
17612 (define_expand "eh_return"
17613 [(use (match_operand 0 "register_operand"))]
17614 ""
17615 {
17616 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
17617
17618 /* Tricky bit: we write the address of the handler to which we will
17619 be returning into someone else's stack frame, one word below the
17620 stack address we wish to restore. */
17621 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
17622 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
17623 /* Return address is always in word_mode. */
17624 tmp = gen_rtx_MEM (word_mode, tmp);
17625 if (GET_MODE (ra) != word_mode)
17626 ra = convert_to_mode (word_mode, ra, 1);
17627 emit_move_insn (tmp, ra);
17628
17629 emit_jump_insn (gen_eh_return_internal ());
17630 emit_barrier ();
17631 DONE;
17632 })
17633
17634 (define_insn_and_split "eh_return_internal"
17635 [(eh_return)]
17636 ""
17637 "#"
17638 "epilogue_completed"
17639 [(const_int 0)]
17640 "ix86_expand_epilogue (2); DONE;")
17641
17642 (define_expand "@leave_<mode>"
17643 [(parallel
17644 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
17645 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
17646 (clobber (mem:BLK (scratch)))])]
17647 ""
17648 "operands[0] = GEN_INT (<MODE_SIZE>);")
17649
17650 (define_insn "*leave"
17651 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
17652 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
17653 (clobber (mem:BLK (scratch)))]
17654 "!TARGET_64BIT"
17655 "leave"
17656 [(set_attr "type" "leave")])
17657
17658 (define_insn "*leave_rex64"
17659 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
17660 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
17661 (clobber (mem:BLK (scratch)))]
17662 "TARGET_64BIT"
17663 "leave"
17664 [(set_attr "type" "leave")])
17665 \f
17666 ;; Handle -fsplit-stack.
17667
17668 (define_expand "split_stack_prologue"
17669 [(const_int 0)]
17670 ""
17671 {
17672 ix86_expand_split_stack_prologue ();
17673 DONE;
17674 })
17675
17676 ;; In order to support the call/return predictor, we use a return
17677 ;; instruction which the middle-end doesn't see.
17678 (define_insn "split_stack_return"
17679 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
17680 UNSPECV_SPLIT_STACK_RETURN)]
17681 ""
17682 {
17683 if (operands[0] == const0_rtx)
17684 return "ret";
17685 else
17686 return "ret\t%0";
17687 }
17688 [(set_attr "atom_unit" "jeu")
17689 (set_attr "modrm" "0")
17690 (set (attr "length")
17691 (if_then_else (match_operand:SI 0 "const0_operand")
17692 (const_int 1)
17693 (const_int 3)))
17694 (set (attr "length_immediate")
17695 (if_then_else (match_operand:SI 0 "const0_operand")
17696 (const_int 0)
17697 (const_int 2)))])
17698
17699 ;; If there are operand 0 bytes available on the stack, jump to
17700 ;; operand 1.
17701
17702 (define_expand "split_stack_space_check"
17703 [(set (pc) (if_then_else
17704 (ltu (minus (reg SP_REG)
17705 (match_operand 0 "register_operand"))
17706 (match_dup 2))
17707 (label_ref (match_operand 1))
17708 (pc)))]
17709 ""
17710 {
17711 rtx reg = gen_reg_rtx (Pmode);
17712
17713 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
17714
17715 operands[2] = ix86_split_stack_guard ();
17716 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
17717
17718 DONE;
17719 })
17720 \f
17721 ;; Bit manipulation instructions.
17722
17723 (define_expand "ffs<mode>2"
17724 [(set (match_dup 2) (const_int -1))
17725 (parallel [(set (match_dup 3) (match_dup 4))
17726 (set (match_operand:SWI48 0 "register_operand")
17727 (ctz:SWI48
17728 (match_operand:SWI48 1 "nonimmediate_operand")))])
17729 (set (match_dup 0) (if_then_else:SWI48
17730 (eq (match_dup 3) (const_int 0))
17731 (match_dup 2)
17732 (match_dup 0)))
17733 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
17734 (clobber (reg:CC FLAGS_REG))])]
17735 ""
17736 {
17737 machine_mode flags_mode;
17738
17739 if (<MODE>mode == SImode && !TARGET_CMOVE)
17740 {
17741 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
17742 DONE;
17743 }
17744
17745 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
17746
17747 operands[2] = gen_reg_rtx (<MODE>mode);
17748 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
17749 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
17750 })
17751
17752 (define_insn_and_split "ffssi2_no_cmove"
17753 [(set (match_operand:SI 0 "register_operand" "=r")
17754 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
17755 (clobber (match_scratch:SI 2 "=&q"))
17756 (clobber (reg:CC FLAGS_REG))]
17757 "!TARGET_CMOVE"
17758 "#"
17759 "&& reload_completed"
17760 [(parallel [(set (match_dup 4) (match_dup 5))
17761 (set (match_dup 0) (ctz:SI (match_dup 1)))])
17762 (set (strict_low_part (match_dup 3))
17763 (eq:QI (match_dup 4) (const_int 0)))
17764 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
17765 (clobber (reg:CC FLAGS_REG))])
17766 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
17767 (clobber (reg:CC FLAGS_REG))])
17768 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
17769 (clobber (reg:CC FLAGS_REG))])]
17770 {
17771 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
17772
17773 operands[3] = gen_lowpart (QImode, operands[2]);
17774 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
17775 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
17776
17777 ix86_expand_clear (operands[2]);
17778 })
17779
17780 (define_insn_and_split "*tzcnt<mode>_1"
17781 [(set (reg:CCC FLAGS_REG)
17782 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17783 (const_int 0)))
17784 (set (match_operand:SWI48 0 "register_operand" "=r")
17785 (ctz:SWI48 (match_dup 1)))]
17786 "TARGET_BMI"
17787 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17788 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17789 && optimize_function_for_speed_p (cfun)
17790 && !reg_mentioned_p (operands[0], operands[1])"
17791 [(parallel
17792 [(set (reg:CCC FLAGS_REG)
17793 (compare:CCC (match_dup 1) (const_int 0)))
17794 (set (match_dup 0)
17795 (ctz:SWI48 (match_dup 1)))
17796 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
17797 "ix86_expand_clear (operands[0]);"
17798 [(set_attr "type" "alu1")
17799 (set_attr "prefix_0f" "1")
17800 (set_attr "prefix_rep" "1")
17801 (set_attr "btver2_decode" "double")
17802 (set_attr "mode" "<MODE>")])
17803
17804 ; False dependency happens when destination is only updated by tzcnt,
17805 ; lzcnt or popcnt. There is no false dependency when destination is
17806 ; also used in source.
17807 (define_insn "*tzcnt<mode>_1_falsedep"
17808 [(set (reg:CCC FLAGS_REG)
17809 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17810 (const_int 0)))
17811 (set (match_operand:SWI48 0 "register_operand" "=r")
17812 (ctz:SWI48 (match_dup 1)))
17813 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
17814 UNSPEC_INSN_FALSE_DEP)]
17815 "TARGET_BMI"
17816 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17817 [(set_attr "type" "alu1")
17818 (set_attr "prefix_0f" "1")
17819 (set_attr "prefix_rep" "1")
17820 (set_attr "btver2_decode" "double")
17821 (set_attr "mode" "<MODE>")])
17822
17823 (define_insn "*bsf<mode>_1"
17824 [(set (reg:CCZ FLAGS_REG)
17825 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17826 (const_int 0)))
17827 (set (match_operand:SWI48 0 "register_operand" "=r")
17828 (ctz:SWI48 (match_dup 1)))]
17829 ""
17830 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
17831 [(set_attr "type" "alu1")
17832 (set_attr "prefix_0f" "1")
17833 (set_attr "btver2_decode" "double")
17834 (set_attr "znver1_decode" "vector")
17835 (set_attr "mode" "<MODE>")])
17836
17837 (define_insn_and_split "ctz<mode>2"
17838 [(set (match_operand:SWI48 0 "register_operand" "=r")
17839 (ctz:SWI48
17840 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
17841 (clobber (reg:CC FLAGS_REG))]
17842 ""
17843 {
17844 if (TARGET_BMI)
17845 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17846 else if (optimize_function_for_size_p (cfun))
17847 ;
17848 else if (TARGET_CPU_P (GENERIC))
17849 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17850 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17851
17852 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17853 }
17854 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
17855 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17856 && optimize_function_for_speed_p (cfun)
17857 && !reg_mentioned_p (operands[0], operands[1])"
17858 [(parallel
17859 [(set (match_dup 0)
17860 (ctz:SWI48 (match_dup 1)))
17861 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17862 (clobber (reg:CC FLAGS_REG))])]
17863 "ix86_expand_clear (operands[0]);"
17864 [(set_attr "type" "alu1")
17865 (set_attr "prefix_0f" "1")
17866 (set (attr "prefix_rep")
17867 (if_then_else
17868 (ior (match_test "TARGET_BMI")
17869 (and (not (match_test "optimize_function_for_size_p (cfun)"))
17870 (match_test "TARGET_CPU_P (GENERIC)")))
17871 (const_string "1")
17872 (const_string "0")))
17873 (set_attr "mode" "<MODE>")])
17874
17875 ; False dependency happens when destination is only updated by tzcnt,
17876 ; lzcnt or popcnt. There is no false dependency when destination is
17877 ; also used in source.
17878 (define_insn "*ctz<mode>2_falsedep"
17879 [(set (match_operand:SWI48 0 "register_operand" "=r")
17880 (ctz:SWI48
17881 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
17882 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
17883 UNSPEC_INSN_FALSE_DEP)
17884 (clobber (reg:CC FLAGS_REG))]
17885 ""
17886 {
17887 if (TARGET_BMI)
17888 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17889 else if (TARGET_CPU_P (GENERIC))
17890 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17891 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17892 else
17893 gcc_unreachable ();
17894 }
17895 [(set_attr "type" "alu1")
17896 (set_attr "prefix_0f" "1")
17897 (set_attr "prefix_rep" "1")
17898 (set_attr "mode" "<MODE>")])
17899
17900 (define_insn_and_split "*ctzsi2_zext"
17901 [(set (match_operand:DI 0 "register_operand" "=r")
17902 (and:DI
17903 (subreg:DI
17904 (ctz:SI
17905 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
17906 (const_int 63)))
17907 (clobber (reg:CC FLAGS_REG))]
17908 "TARGET_BMI && TARGET_64BIT"
17909 "tzcnt{l}\t{%1, %k0|%k0, %1}"
17910 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17911 && optimize_function_for_speed_p (cfun)
17912 && !reg_mentioned_p (operands[0], operands[1])"
17913 [(parallel
17914 [(set (match_dup 0)
17915 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
17916 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17917 (clobber (reg:CC FLAGS_REG))])]
17918 "ix86_expand_clear (operands[0]);"
17919 [(set_attr "type" "alu1")
17920 (set_attr "prefix_0f" "1")
17921 (set_attr "prefix_rep" "1")
17922 (set_attr "mode" "SI")])
17923
17924 ; False dependency happens when destination is only updated by tzcnt,
17925 ; lzcnt or popcnt. There is no false dependency when destination is
17926 ; also used in source.
17927 (define_insn "*ctzsi2_zext_falsedep"
17928 [(set (match_operand:DI 0 "register_operand" "=r")
17929 (and:DI
17930 (subreg:DI
17931 (ctz:SI
17932 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
17933 (const_int 63)))
17934 (unspec [(match_operand:DI 2 "register_operand" "0")]
17935 UNSPEC_INSN_FALSE_DEP)
17936 (clobber (reg:CC FLAGS_REG))]
17937 "TARGET_BMI && TARGET_64BIT"
17938 "tzcnt{l}\t{%1, %k0|%k0, %1}"
17939 [(set_attr "type" "alu1")
17940 (set_attr "prefix_0f" "1")
17941 (set_attr "prefix_rep" "1")
17942 (set_attr "mode" "SI")])
17943
17944 (define_insn_and_split "*ctzsidi2_<s>ext"
17945 [(set (match_operand:DI 0 "register_operand" "=r")
17946 (any_extend:DI
17947 (ctz:SI
17948 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
17949 (clobber (reg:CC FLAGS_REG))]
17950 "TARGET_64BIT"
17951 {
17952 if (TARGET_BMI)
17953 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
17954 else if (TARGET_CPU_P (GENERIC)
17955 && !optimize_function_for_size_p (cfun))
17956 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17957 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
17958 return "bsf{l}\t{%1, %k0|%k0, %1}";
17959 }
17960 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
17961 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17962 && optimize_function_for_speed_p (cfun)
17963 && !reg_mentioned_p (operands[0], operands[1])"
17964 [(parallel
17965 [(set (match_dup 0)
17966 (any_extend:DI (ctz:SI (match_dup 1))))
17967 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17968 (clobber (reg:CC FLAGS_REG))])]
17969 "ix86_expand_clear (operands[0]);"
17970 [(set_attr "type" "alu1")
17971 (set_attr "prefix_0f" "1")
17972 (set (attr "prefix_rep")
17973 (if_then_else
17974 (ior (match_test "TARGET_BMI")
17975 (and (not (match_test "optimize_function_for_size_p (cfun)"))
17976 (match_test "TARGET_CPU_P (GENERIC)")))
17977 (const_string "1")
17978 (const_string "0")))
17979 (set_attr "mode" "SI")])
17980
17981 (define_insn "*ctzsidi2_<s>ext_falsedep"
17982 [(set (match_operand:DI 0 "register_operand" "=r")
17983 (any_extend:DI
17984 (ctz:SI
17985 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
17986 (unspec [(match_operand:DI 2 "register_operand" "0")]
17987 UNSPEC_INSN_FALSE_DEP)
17988 (clobber (reg:CC FLAGS_REG))]
17989 "TARGET_64BIT"
17990 {
17991 if (TARGET_BMI)
17992 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
17993 else if (TARGET_CPU_P (GENERIC))
17994 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17995 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
17996 else
17997 gcc_unreachable ();
17998 }
17999 [(set_attr "type" "alu1")
18000 (set_attr "prefix_0f" "1")
18001 (set_attr "prefix_rep" "1")
18002 (set_attr "mode" "SI")])
18003
18004 (define_insn "bsr_rex64"
18005 [(set (reg:CCZ FLAGS_REG)
18006 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
18007 (const_int 0)))
18008 (set (match_operand:DI 0 "register_operand" "=r")
18009 (minus:DI (const_int 63)
18010 (clz:DI (match_dup 1))))]
18011 "TARGET_64BIT"
18012 "bsr{q}\t{%1, %0|%0, %1}"
18013 [(set_attr "type" "alu1")
18014 (set_attr "prefix_0f" "1")
18015 (set_attr "znver1_decode" "vector")
18016 (set_attr "mode" "DI")])
18017
18018 (define_insn "bsr_rex64_1"
18019 [(set (match_operand:DI 0 "register_operand" "=r")
18020 (minus:DI (const_int 63)
18021 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
18022 (clobber (reg:CC FLAGS_REG))]
18023 "!TARGET_LZCNT && TARGET_64BIT"
18024 "bsr{q}\t{%1, %0|%0, %1}"
18025 [(set_attr "type" "alu1")
18026 (set_attr "prefix_0f" "1")
18027 (set_attr "znver1_decode" "vector")
18028 (set_attr "mode" "DI")])
18029
18030 (define_insn "bsr_rex64_1_zext"
18031 [(set (match_operand:DI 0 "register_operand" "=r")
18032 (zero_extend:DI
18033 (minus:SI (const_int 63)
18034 (subreg:SI
18035 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
18036 0))))
18037 (clobber (reg:CC FLAGS_REG))]
18038 "!TARGET_LZCNT && TARGET_64BIT"
18039 "bsr{q}\t{%1, %0|%0, %1}"
18040 [(set_attr "type" "alu1")
18041 (set_attr "prefix_0f" "1")
18042 (set_attr "znver1_decode" "vector")
18043 (set_attr "mode" "DI")])
18044
18045 (define_insn "bsr"
18046 [(set (reg:CCZ FLAGS_REG)
18047 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
18048 (const_int 0)))
18049 (set (match_operand:SI 0 "register_operand" "=r")
18050 (minus:SI (const_int 31)
18051 (clz:SI (match_dup 1))))]
18052 ""
18053 "bsr{l}\t{%1, %0|%0, %1}"
18054 [(set_attr "type" "alu1")
18055 (set_attr "prefix_0f" "1")
18056 (set_attr "znver1_decode" "vector")
18057 (set_attr "mode" "SI")])
18058
18059 (define_insn "bsr_1"
18060 [(set (match_operand:SI 0 "register_operand" "=r")
18061 (minus:SI (const_int 31)
18062 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18063 (clobber (reg:CC FLAGS_REG))]
18064 "!TARGET_LZCNT"
18065 "bsr{l}\t{%1, %0|%0, %1}"
18066 [(set_attr "type" "alu1")
18067 (set_attr "prefix_0f" "1")
18068 (set_attr "znver1_decode" "vector")
18069 (set_attr "mode" "SI")])
18070
18071 (define_insn "bsr_zext_1"
18072 [(set (match_operand:DI 0 "register_operand" "=r")
18073 (zero_extend:DI
18074 (minus:SI
18075 (const_int 31)
18076 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18077 (clobber (reg:CC FLAGS_REG))]
18078 "!TARGET_LZCNT && TARGET_64BIT"
18079 "bsr{l}\t{%1, %k0|%k0, %1}"
18080 [(set_attr "type" "alu1")
18081 (set_attr "prefix_0f" "1")
18082 (set_attr "znver1_decode" "vector")
18083 (set_attr "mode" "SI")])
18084
18085 ; As bsr is undefined behavior on zero and for other input
18086 ; values it is in range 0 to 63, we can optimize away sign-extends.
18087 (define_insn_and_split "*bsr_rex64_2"
18088 [(set (match_operand:DI 0 "register_operand")
18089 (xor:DI
18090 (sign_extend:DI
18091 (minus:SI
18092 (const_int 63)
18093 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18094 0)))
18095 (const_int 63)))
18096 (clobber (reg:CC FLAGS_REG))]
18097 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18098 "#"
18099 "&& 1"
18100 [(parallel [(set (reg:CCZ FLAGS_REG)
18101 (compare:CCZ (match_dup 1) (const_int 0)))
18102 (set (match_dup 2)
18103 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18104 (parallel [(set (match_dup 0)
18105 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18106 (clobber (reg:CC FLAGS_REG))])]
18107 {
18108 operands[2] = gen_reg_rtx (DImode);
18109 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18110 })
18111
18112 (define_insn_and_split "*bsr_2"
18113 [(set (match_operand:DI 0 "register_operand")
18114 (sign_extend:DI
18115 (xor:SI
18116 (minus:SI
18117 (const_int 31)
18118 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18119 (const_int 31))))
18120 (clobber (reg:CC FLAGS_REG))]
18121 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18122 "#"
18123 "&& 1"
18124 [(parallel [(set (reg:CCZ FLAGS_REG)
18125 (compare:CCZ (match_dup 1) (const_int 0)))
18126 (set (match_dup 2)
18127 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18128 (parallel [(set (match_dup 0)
18129 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18130 (clobber (reg:CC FLAGS_REG))])]
18131 "operands[2] = gen_reg_rtx (SImode);")
18132
18133 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18134 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18135 ; in [0, 63] or [0, 31] range.
18136 (define_split
18137 [(set (match_operand:SI 0 "register_operand")
18138 (minus:SI
18139 (match_operand:SI 2 "const_int_operand")
18140 (xor:SI
18141 (minus:SI (const_int 63)
18142 (subreg:SI
18143 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18144 0))
18145 (const_int 63))))]
18146 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18147 [(set (match_dup 3)
18148 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18149 (set (match_dup 0)
18150 (plus:SI (match_dup 5) (match_dup 4)))]
18151 {
18152 operands[3] = gen_reg_rtx (DImode);
18153 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18154 if (INTVAL (operands[2]) == 63)
18155 {
18156 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18157 emit_move_insn (operands[0], operands[5]);
18158 DONE;
18159 }
18160 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18161 })
18162
18163 (define_split
18164 [(set (match_operand:SI 0 "register_operand")
18165 (minus:SI
18166 (match_operand:SI 2 "const_int_operand")
18167 (xor:SI
18168 (minus:SI (const_int 31)
18169 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18170 (const_int 31))))]
18171 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18172 [(set (match_dup 3)
18173 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18174 (set (match_dup 0)
18175 (plus:SI (match_dup 3) (match_dup 4)))]
18176 {
18177 if (INTVAL (operands[2]) == 31)
18178 {
18179 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18180 DONE;
18181 }
18182 operands[3] = gen_reg_rtx (SImode);
18183 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18184 })
18185
18186 (define_split
18187 [(set (match_operand:DI 0 "register_operand")
18188 (minus:DI
18189 (match_operand:DI 2 "const_int_operand")
18190 (xor:DI
18191 (sign_extend:DI
18192 (minus:SI (const_int 63)
18193 (subreg:SI
18194 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18195 0)))
18196 (const_int 63))))]
18197 "!TARGET_LZCNT
18198 && TARGET_64BIT
18199 && ix86_pre_reload_split ()
18200 && ((unsigned HOST_WIDE_INT)
18201 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18202 == UINTVAL (operands[2]) - 63)"
18203 [(set (match_dup 3)
18204 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18205 (set (match_dup 0)
18206 (plus:DI (match_dup 3) (match_dup 4)))]
18207 {
18208 if (INTVAL (operands[2]) == 63)
18209 {
18210 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18211 DONE;
18212 }
18213 operands[3] = gen_reg_rtx (DImode);
18214 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18215 })
18216
18217 (define_split
18218 [(set (match_operand:DI 0 "register_operand")
18219 (minus:DI
18220 (match_operand:DI 2 "const_int_operand")
18221 (sign_extend:DI
18222 (xor:SI
18223 (minus:SI (const_int 31)
18224 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18225 (const_int 31)))))]
18226 "!TARGET_LZCNT
18227 && TARGET_64BIT
18228 && ix86_pre_reload_split ()
18229 && ((unsigned HOST_WIDE_INT)
18230 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18231 == UINTVAL (operands[2]) - 31)"
18232 [(set (match_dup 3)
18233 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18234 (set (match_dup 0)
18235 (plus:DI (match_dup 3) (match_dup 4)))]
18236 {
18237 if (INTVAL (operands[2]) == 31)
18238 {
18239 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18240 DONE;
18241 }
18242 operands[3] = gen_reg_rtx (DImode);
18243 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18244 })
18245
18246 (define_expand "clz<mode>2"
18247 [(parallel
18248 [(set (reg:CCZ FLAGS_REG)
18249 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18250 (const_int 0)))
18251 (set (match_dup 3) (minus:SWI48
18252 (match_dup 2)
18253 (clz:SWI48 (match_dup 1))))])
18254 (parallel
18255 [(set (match_operand:SWI48 0 "register_operand")
18256 (xor:SWI48 (match_dup 3) (match_dup 2)))
18257 (clobber (reg:CC FLAGS_REG))])]
18258 ""
18259 {
18260 if (TARGET_LZCNT)
18261 {
18262 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18263 DONE;
18264 }
18265 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18266 operands[3] = gen_reg_rtx (<MODE>mode);
18267 })
18268
18269 (define_insn_and_split "clz<mode>2_lzcnt"
18270 [(set (match_operand:SWI48 0 "register_operand" "=r")
18271 (clz:SWI48
18272 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18273 (clobber (reg:CC FLAGS_REG))]
18274 "TARGET_LZCNT"
18275 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18276 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18277 && optimize_function_for_speed_p (cfun)
18278 && !reg_mentioned_p (operands[0], operands[1])"
18279 [(parallel
18280 [(set (match_dup 0)
18281 (clz:SWI48 (match_dup 1)))
18282 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18283 (clobber (reg:CC FLAGS_REG))])]
18284 "ix86_expand_clear (operands[0]);"
18285 [(set_attr "prefix_rep" "1")
18286 (set_attr "type" "bitmanip")
18287 (set_attr "mode" "<MODE>")])
18288
18289 ; False dependency happens when destination is only updated by tzcnt,
18290 ; lzcnt or popcnt. There is no false dependency when destination is
18291 ; also used in source.
18292 (define_insn "*clz<mode>2_lzcnt_falsedep"
18293 [(set (match_operand:SWI48 0 "register_operand" "=r")
18294 (clz:SWI48
18295 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18296 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18297 UNSPEC_INSN_FALSE_DEP)
18298 (clobber (reg:CC FLAGS_REG))]
18299 "TARGET_LZCNT"
18300 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18301 [(set_attr "prefix_rep" "1")
18302 (set_attr "type" "bitmanip")
18303 (set_attr "mode" "<MODE>")])
18304
18305 (define_insn_and_split "*clzsi2_lzcnt_zext"
18306 [(set (match_operand:DI 0 "register_operand" "=r")
18307 (and:DI
18308 (subreg:DI
18309 (clz:SI
18310 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18311 (const_int 63)))
18312 (clobber (reg:CC FLAGS_REG))]
18313 "TARGET_LZCNT && TARGET_64BIT"
18314 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18315 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18316 && optimize_function_for_speed_p (cfun)
18317 && !reg_mentioned_p (operands[0], operands[1])"
18318 [(parallel
18319 [(set (match_dup 0)
18320 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18321 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18322 (clobber (reg:CC FLAGS_REG))])]
18323 "ix86_expand_clear (operands[0]);"
18324 [(set_attr "prefix_rep" "1")
18325 (set_attr "type" "bitmanip")
18326 (set_attr "mode" "SI")])
18327
18328 ; False dependency happens when destination is only updated by tzcnt,
18329 ; lzcnt or popcnt. There is no false dependency when destination is
18330 ; also used in source.
18331 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18332 [(set (match_operand:DI 0 "register_operand" "=r")
18333 (and:DI
18334 (subreg:DI
18335 (clz:SI
18336 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18337 (const_int 63)))
18338 (unspec [(match_operand:DI 2 "register_operand" "0")]
18339 UNSPEC_INSN_FALSE_DEP)
18340 (clobber (reg:CC FLAGS_REG))]
18341 "TARGET_LZCNT"
18342 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18343 [(set_attr "prefix_rep" "1")
18344 (set_attr "type" "bitmanip")
18345 (set_attr "mode" "SI")])
18346
18347 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18348 [(set (match_operand:DI 0 "register_operand" "=r")
18349 (zero_extend:DI
18350 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18351 (clobber (reg:CC FLAGS_REG))]
18352 "TARGET_LZCNT && TARGET_64BIT"
18353 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18354 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18355 && optimize_function_for_speed_p (cfun)
18356 && !reg_mentioned_p (operands[0], operands[1])"
18357 [(parallel
18358 [(set (match_dup 0)
18359 (zero_extend:DI (clz:SI (match_dup 1))))
18360 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18361 (clobber (reg:CC FLAGS_REG))])]
18362 "ix86_expand_clear (operands[0]);"
18363 [(set_attr "prefix_rep" "1")
18364 (set_attr "type" "bitmanip")
18365 (set_attr "mode" "SI")])
18366
18367 ; False dependency happens when destination is only updated by tzcnt,
18368 ; lzcnt or popcnt. There is no false dependency when destination is
18369 ; also used in source.
18370 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18371 [(set (match_operand:DI 0 "register_operand" "=r")
18372 (zero_extend:DI
18373 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18374 (unspec [(match_operand:DI 2 "register_operand" "0")]
18375 UNSPEC_INSN_FALSE_DEP)
18376 (clobber (reg:CC FLAGS_REG))]
18377 "TARGET_LZCNT"
18378 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18379 [(set_attr "prefix_rep" "1")
18380 (set_attr "type" "bitmanip")
18381 (set_attr "mode" "SI")])
18382
18383 (define_int_iterator LT_ZCNT
18384 [(UNSPEC_TZCNT "TARGET_BMI")
18385 (UNSPEC_LZCNT "TARGET_LZCNT")])
18386
18387 (define_int_attr lt_zcnt
18388 [(UNSPEC_TZCNT "tzcnt")
18389 (UNSPEC_LZCNT "lzcnt")])
18390
18391 (define_int_attr lt_zcnt_type
18392 [(UNSPEC_TZCNT "alu1")
18393 (UNSPEC_LZCNT "bitmanip")])
18394
18395 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
18396 ;; provides operand size as output when source operand is zero.
18397
18398 (define_insn_and_split "<lt_zcnt>_<mode>"
18399 [(set (match_operand:SWI48 0 "register_operand" "=r")
18400 (unspec:SWI48
18401 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18402 (clobber (reg:CC FLAGS_REG))]
18403 ""
18404 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18405 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18406 && optimize_function_for_speed_p (cfun)
18407 && !reg_mentioned_p (operands[0], operands[1])"
18408 [(parallel
18409 [(set (match_dup 0)
18410 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18411 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18412 (clobber (reg:CC FLAGS_REG))])]
18413 "ix86_expand_clear (operands[0]);"
18414 [(set_attr "type" "<lt_zcnt_type>")
18415 (set_attr "prefix_0f" "1")
18416 (set_attr "prefix_rep" "1")
18417 (set_attr "mode" "<MODE>")])
18418
18419 ; False dependency happens when destination is only updated by tzcnt,
18420 ; lzcnt or popcnt. There is no false dependency when destination is
18421 ; also used in source.
18422 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18423 [(set (match_operand:SWI48 0 "register_operand" "=r")
18424 (unspec:SWI48
18425 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18426 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18427 UNSPEC_INSN_FALSE_DEP)
18428 (clobber (reg:CC FLAGS_REG))]
18429 ""
18430 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18431 [(set_attr "type" "<lt_zcnt_type>")
18432 (set_attr "prefix_0f" "1")
18433 (set_attr "prefix_rep" "1")
18434 (set_attr "mode" "<MODE>")])
18435
18436 (define_insn "<lt_zcnt>_hi"
18437 [(set (match_operand:HI 0 "register_operand" "=r")
18438 (unspec:HI
18439 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18440 (clobber (reg:CC FLAGS_REG))]
18441 ""
18442 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18443 [(set_attr "type" "<lt_zcnt_type>")
18444 (set_attr "prefix_0f" "1")
18445 (set_attr "prefix_rep" "1")
18446 (set_attr "mode" "HI")])
18447
18448 ;; BMI instructions.
18449
18450 (define_insn "bmi_bextr_<mode>"
18451 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18452 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18453 (match_operand:SWI48 2 "register_operand" "r,r")]
18454 UNSPEC_BEXTR))
18455 (clobber (reg:CC FLAGS_REG))]
18456 "TARGET_BMI"
18457 "bextr\t{%2, %1, %0|%0, %1, %2}"
18458 [(set_attr "type" "bitmanip")
18459 (set_attr "btver2_decode" "direct, double")
18460 (set_attr "mode" "<MODE>")])
18461
18462 (define_insn "*bmi_bextr_<mode>_ccz"
18463 [(set (reg:CCZ FLAGS_REG)
18464 (compare:CCZ
18465 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18466 (match_operand:SWI48 2 "register_operand" "r,r")]
18467 UNSPEC_BEXTR)
18468 (const_int 0)))
18469 (clobber (match_scratch:SWI48 0 "=r,r"))]
18470 "TARGET_BMI"
18471 "bextr\t{%2, %1, %0|%0, %1, %2}"
18472 [(set_attr "type" "bitmanip")
18473 (set_attr "btver2_decode" "direct, double")
18474 (set_attr "mode" "<MODE>")])
18475
18476 (define_insn "*bmi_blsi_<mode>"
18477 [(set (match_operand:SWI48 0 "register_operand" "=r")
18478 (and:SWI48
18479 (neg:SWI48
18480 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18481 (match_dup 1)))
18482 (clobber (reg:CC FLAGS_REG))]
18483 "TARGET_BMI"
18484 "blsi\t{%1, %0|%0, %1}"
18485 [(set_attr "type" "bitmanip")
18486 (set_attr "btver2_decode" "double")
18487 (set_attr "mode" "<MODE>")])
18488
18489 (define_insn "*bmi_blsi_<mode>_cmp"
18490 [(set (reg FLAGS_REG)
18491 (compare
18492 (and:SWI48
18493 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18494 (match_dup 1))
18495 (const_int 0)))
18496 (set (match_operand:SWI48 0 "register_operand" "=r")
18497 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
18498 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18499 "blsi\t{%1, %0|%0, %1}"
18500 [(set_attr "type" "bitmanip")
18501 (set_attr "btver2_decode" "double")
18502 (set_attr "mode" "<MODE>")])
18503
18504 (define_insn "*bmi_blsi_<mode>_ccno"
18505 [(set (reg FLAGS_REG)
18506 (compare
18507 (and:SWI48
18508 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18509 (match_dup 1))
18510 (const_int 0)))
18511 (clobber (match_scratch:SWI48 0 "=r"))]
18512 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18513 "blsi\t{%1, %0|%0, %1}"
18514 [(set_attr "type" "bitmanip")
18515 (set_attr "btver2_decode" "double")
18516 (set_attr "mode" "<MODE>")])
18517
18518 (define_insn "*bmi_blsmsk_<mode>"
18519 [(set (match_operand:SWI48 0 "register_operand" "=r")
18520 (xor:SWI48
18521 (plus:SWI48
18522 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18523 (const_int -1))
18524 (match_dup 1)))
18525 (clobber (reg:CC FLAGS_REG))]
18526 "TARGET_BMI"
18527 "blsmsk\t{%1, %0|%0, %1}"
18528 [(set_attr "type" "bitmanip")
18529 (set_attr "btver2_decode" "double")
18530 (set_attr "mode" "<MODE>")])
18531
18532 (define_insn "*bmi_blsr_<mode>"
18533 [(set (match_operand:SWI48 0 "register_operand" "=r")
18534 (and:SWI48
18535 (plus:SWI48
18536 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18537 (const_int -1))
18538 (match_dup 1)))
18539 (clobber (reg:CC FLAGS_REG))]
18540 "TARGET_BMI"
18541 "blsr\t{%1, %0|%0, %1}"
18542 [(set_attr "type" "bitmanip")
18543 (set_attr "btver2_decode" "double")
18544 (set_attr "mode" "<MODE>")])
18545
18546 (define_insn "*bmi_blsr_<mode>_cmp"
18547 [(set (reg:CCZ FLAGS_REG)
18548 (compare:CCZ
18549 (and:SWI48
18550 (plus:SWI48
18551 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18552 (const_int -1))
18553 (match_dup 1))
18554 (const_int 0)))
18555 (set (match_operand:SWI48 0 "register_operand" "=r")
18556 (and:SWI48
18557 (plus:SWI48
18558 (match_dup 1)
18559 (const_int -1))
18560 (match_dup 1)))]
18561 "TARGET_BMI"
18562 "blsr\t{%1, %0|%0, %1}"
18563 [(set_attr "type" "bitmanip")
18564 (set_attr "btver2_decode" "double")
18565 (set_attr "mode" "<MODE>")])
18566
18567 (define_insn "*bmi_blsr_<mode>_ccz"
18568 [(set (reg:CCZ FLAGS_REG)
18569 (compare:CCZ
18570 (and:SWI48
18571 (plus:SWI48
18572 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18573 (const_int -1))
18574 (match_dup 1))
18575 (const_int 0)))
18576 (clobber (match_scratch:SWI48 0 "=r"))]
18577 "TARGET_BMI"
18578 "blsr\t{%1, %0|%0, %1}"
18579 [(set_attr "type" "bitmanip")
18580 (set_attr "btver2_decode" "double")
18581 (set_attr "mode" "<MODE>")])
18582
18583 ;; BMI2 instructions.
18584 (define_expand "bmi2_bzhi_<mode>3"
18585 [(parallel
18586 [(set (match_operand:SWI48 0 "register_operand")
18587 (if_then_else:SWI48
18588 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
18589 (const_int 255))
18590 (const_int 0))
18591 (zero_extract:SWI48
18592 (match_operand:SWI48 1 "nonimmediate_operand")
18593 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
18594 (match_dup 3))
18595 (const_int 0))
18596 (const_int 0)))
18597 (clobber (reg:CC FLAGS_REG))])]
18598 "TARGET_BMI2"
18599 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
18600
18601 (define_insn "*bmi2_bzhi_<mode>3"
18602 [(set (match_operand:SWI48 0 "register_operand" "=r")
18603 (if_then_else:SWI48
18604 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
18605 (const_int 255))
18606 (const_int 0))
18607 (zero_extract:SWI48
18608 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18609 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
18610 (match_operand:SWI48 3 "const_int_operand"))
18611 (const_int 0))
18612 (const_int 0)))
18613 (clobber (reg:CC FLAGS_REG))]
18614 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18615 "bzhi\t{%2, %1, %0|%0, %1, %2}"
18616 [(set_attr "type" "bitmanip")
18617 (set_attr "prefix" "vex")
18618 (set_attr "mode" "<MODE>")])
18619
18620 (define_insn "*bmi2_bzhi_<mode>3_1"
18621 [(set (match_operand:SWI48 0 "register_operand" "=r")
18622 (if_then_else:SWI48
18623 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18624 (zero_extract:SWI48
18625 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18626 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
18627 (match_operand:SWI48 3 "const_int_operand"))
18628 (const_int 0))
18629 (const_int 0)))
18630 (clobber (reg:CC FLAGS_REG))]
18631 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18632 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18633 [(set_attr "type" "bitmanip")
18634 (set_attr "prefix" "vex")
18635 (set_attr "mode" "<MODE>")])
18636
18637 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
18638 [(set (reg:CCZ FLAGS_REG)
18639 (compare:CCZ
18640 (if_then_else:SWI48
18641 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18642 (zero_extract:SWI48
18643 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18644 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
18645 (match_operand:SWI48 3 "const_int_operand"))
18646 (const_int 0))
18647 (const_int 0))
18648 (const_int 0)))
18649 (clobber (match_scratch:SWI48 0 "=r"))]
18650 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18651 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18652 [(set_attr "type" "bitmanip")
18653 (set_attr "prefix" "vex")
18654 (set_attr "mode" "<MODE>")])
18655
18656 (define_insn "*bmi2_bzhi_<mode>3_2"
18657 [(set (match_operand:SWI48 0 "register_operand" "=r")
18658 (and:SWI48
18659 (plus:SWI48
18660 (ashift:SWI48 (const_int 1)
18661 (match_operand:QI 2 "register_operand" "r"))
18662 (const_int -1))
18663 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18664 (clobber (reg:CC FLAGS_REG))]
18665 "TARGET_BMI2"
18666 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18667 [(set_attr "type" "bitmanip")
18668 (set_attr "prefix" "vex")
18669 (set_attr "mode" "<MODE>")])
18670
18671 (define_insn "*bmi2_bzhi_<mode>3_3"
18672 [(set (match_operand:SWI48 0 "register_operand" "=r")
18673 (and:SWI48
18674 (not:SWI48
18675 (ashift:SWI48 (const_int -1)
18676 (match_operand:QI 2 "register_operand" "r")))
18677 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18678 (clobber (reg:CC FLAGS_REG))]
18679 "TARGET_BMI2"
18680 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18681 [(set_attr "type" "bitmanip")
18682 (set_attr "prefix" "vex")
18683 (set_attr "mode" "<MODE>")])
18684
18685 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
18686 [(set (match_operand:DI 0 "register_operand" "=r")
18687 (zero_extend:DI
18688 (and:SI
18689 (plus:SI
18690 (ashift:SI (const_int 1)
18691 (match_operand:QI 2 "register_operand" "r"))
18692 (const_int -1))
18693 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18694 (clobber (reg:CC FLAGS_REG))]
18695 "TARGET_64BIT && TARGET_BMI2"
18696 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18697 [(set_attr "type" "bitmanip")
18698 (set_attr "prefix" "vex")
18699 (set_attr "mode" "DI")])
18700
18701 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
18702 [(set (match_operand:DI 0 "register_operand" "=r")
18703 (and:DI
18704 (zero_extend:DI
18705 (plus:SI
18706 (ashift:SI (const_int 1)
18707 (match_operand:QI 2 "register_operand" "r"))
18708 (const_int -1)))
18709 (match_operand:DI 1 "nonimmediate_operand" "rm")))
18710 (clobber (reg:CC FLAGS_REG))]
18711 "TARGET_64BIT && TARGET_BMI2"
18712 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18713 [(set_attr "type" "bitmanip")
18714 (set_attr "prefix" "vex")
18715 (set_attr "mode" "DI")])
18716
18717 (define_insn "bmi2_pdep_<mode>3"
18718 [(set (match_operand:SWI48 0 "register_operand" "=r")
18719 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18720 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18721 UNSPEC_PDEP))]
18722 "TARGET_BMI2"
18723 "pdep\t{%2, %1, %0|%0, %1, %2}"
18724 [(set_attr "type" "bitmanip")
18725 (set_attr "prefix" "vex")
18726 (set_attr "mode" "<MODE>")])
18727
18728 (define_insn "bmi2_pext_<mode>3"
18729 [(set (match_operand:SWI48 0 "register_operand" "=r")
18730 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18731 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18732 UNSPEC_PEXT))]
18733 "TARGET_BMI2"
18734 "pext\t{%2, %1, %0|%0, %1, %2}"
18735 [(set_attr "type" "bitmanip")
18736 (set_attr "prefix" "vex")
18737 (set_attr "mode" "<MODE>")])
18738
18739 ;; TBM instructions.
18740 (define_insn "@tbm_bextri_<mode>"
18741 [(set (match_operand:SWI48 0 "register_operand" "=r")
18742 (zero_extract:SWI48
18743 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18744 (match_operand 2 "const_0_to_255_operand")
18745 (match_operand 3 "const_0_to_255_operand")))
18746 (clobber (reg:CC FLAGS_REG))]
18747 "TARGET_TBM"
18748 {
18749 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
18750 return "bextr\t{%2, %1, %0|%0, %1, %2}";
18751 }
18752 [(set_attr "type" "bitmanip")
18753 (set_attr "mode" "<MODE>")])
18754
18755 (define_insn "*tbm_blcfill_<mode>"
18756 [(set (match_operand:SWI48 0 "register_operand" "=r")
18757 (and:SWI48
18758 (plus:SWI48
18759 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18760 (const_int 1))
18761 (match_dup 1)))
18762 (clobber (reg:CC FLAGS_REG))]
18763 "TARGET_TBM"
18764 "blcfill\t{%1, %0|%0, %1}"
18765 [(set_attr "type" "bitmanip")
18766 (set_attr "mode" "<MODE>")])
18767
18768 (define_insn "*tbm_blci_<mode>"
18769 [(set (match_operand:SWI48 0 "register_operand" "=r")
18770 (ior:SWI48
18771 (not:SWI48
18772 (plus:SWI48
18773 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18774 (const_int 1)))
18775 (match_dup 1)))
18776 (clobber (reg:CC FLAGS_REG))]
18777 "TARGET_TBM"
18778 "blci\t{%1, %0|%0, %1}"
18779 [(set_attr "type" "bitmanip")
18780 (set_attr "mode" "<MODE>")])
18781
18782 (define_insn "*tbm_blcic_<mode>"
18783 [(set (match_operand:SWI48 0 "register_operand" "=r")
18784 (and:SWI48
18785 (plus:SWI48
18786 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18787 (const_int 1))
18788 (not:SWI48
18789 (match_dup 1))))
18790 (clobber (reg:CC FLAGS_REG))]
18791 "TARGET_TBM"
18792 "blcic\t{%1, %0|%0, %1}"
18793 [(set_attr "type" "bitmanip")
18794 (set_attr "mode" "<MODE>")])
18795
18796 (define_insn "*tbm_blcmsk_<mode>"
18797 [(set (match_operand:SWI48 0 "register_operand" "=r")
18798 (xor:SWI48
18799 (plus:SWI48
18800 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18801 (const_int 1))
18802 (match_dup 1)))
18803 (clobber (reg:CC FLAGS_REG))]
18804 "TARGET_TBM"
18805 "blcmsk\t{%1, %0|%0, %1}"
18806 [(set_attr "type" "bitmanip")
18807 (set_attr "mode" "<MODE>")])
18808
18809 (define_insn "*tbm_blcs_<mode>"
18810 [(set (match_operand:SWI48 0 "register_operand" "=r")
18811 (ior:SWI48
18812 (plus:SWI48
18813 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18814 (const_int 1))
18815 (match_dup 1)))
18816 (clobber (reg:CC FLAGS_REG))]
18817 "TARGET_TBM"
18818 "blcs\t{%1, %0|%0, %1}"
18819 [(set_attr "type" "bitmanip")
18820 (set_attr "mode" "<MODE>")])
18821
18822 (define_insn "*tbm_blsfill_<mode>"
18823 [(set (match_operand:SWI48 0 "register_operand" "=r")
18824 (ior:SWI48
18825 (plus:SWI48
18826 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18827 (const_int -1))
18828 (match_dup 1)))
18829 (clobber (reg:CC FLAGS_REG))]
18830 "TARGET_TBM"
18831 "blsfill\t{%1, %0|%0, %1}"
18832 [(set_attr "type" "bitmanip")
18833 (set_attr "mode" "<MODE>")])
18834
18835 (define_insn "*tbm_blsic_<mode>"
18836 [(set (match_operand:SWI48 0 "register_operand" "=r")
18837 (ior:SWI48
18838 (plus:SWI48
18839 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18840 (const_int -1))
18841 (not:SWI48
18842 (match_dup 1))))
18843 (clobber (reg:CC FLAGS_REG))]
18844 "TARGET_TBM"
18845 "blsic\t{%1, %0|%0, %1}"
18846 [(set_attr "type" "bitmanip")
18847 (set_attr "mode" "<MODE>")])
18848
18849 (define_insn "*tbm_t1mskc_<mode>"
18850 [(set (match_operand:SWI48 0 "register_operand" "=r")
18851 (ior:SWI48
18852 (plus:SWI48
18853 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18854 (const_int 1))
18855 (not:SWI48
18856 (match_dup 1))))
18857 (clobber (reg:CC FLAGS_REG))]
18858 "TARGET_TBM"
18859 "t1mskc\t{%1, %0|%0, %1}"
18860 [(set_attr "type" "bitmanip")
18861 (set_attr "mode" "<MODE>")])
18862
18863 (define_insn "*tbm_tzmsk_<mode>"
18864 [(set (match_operand:SWI48 0 "register_operand" "=r")
18865 (and:SWI48
18866 (plus:SWI48
18867 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18868 (const_int -1))
18869 (not:SWI48
18870 (match_dup 1))))
18871 (clobber (reg:CC FLAGS_REG))]
18872 "TARGET_TBM"
18873 "tzmsk\t{%1, %0|%0, %1}"
18874 [(set_attr "type" "bitmanip")
18875 (set_attr "mode" "<MODE>")])
18876
18877 (define_insn_and_split "popcount<mode>2"
18878 [(set (match_operand:SWI48 0 "register_operand" "=r")
18879 (popcount:SWI48
18880 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18881 (clobber (reg:CC FLAGS_REG))]
18882 "TARGET_POPCNT"
18883 {
18884 #if TARGET_MACHO
18885 return "popcnt\t{%1, %0|%0, %1}";
18886 #else
18887 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18888 #endif
18889 }
18890 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18891 && optimize_function_for_speed_p (cfun)
18892 && !reg_mentioned_p (operands[0], operands[1])"
18893 [(parallel
18894 [(set (match_dup 0)
18895 (popcount:SWI48 (match_dup 1)))
18896 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18897 (clobber (reg:CC FLAGS_REG))])]
18898 "ix86_expand_clear (operands[0]);"
18899 [(set_attr "prefix_rep" "1")
18900 (set_attr "type" "bitmanip")
18901 (set_attr "mode" "<MODE>")])
18902
18903 ; False dependency happens when destination is only updated by tzcnt,
18904 ; lzcnt or popcnt. There is no false dependency when destination is
18905 ; also used in source.
18906 (define_insn "*popcount<mode>2_falsedep"
18907 [(set (match_operand:SWI48 0 "register_operand" "=r")
18908 (popcount:SWI48
18909 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18910 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18911 UNSPEC_INSN_FALSE_DEP)
18912 (clobber (reg:CC FLAGS_REG))]
18913 "TARGET_POPCNT"
18914 {
18915 #if TARGET_MACHO
18916 return "popcnt\t{%1, %0|%0, %1}";
18917 #else
18918 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18919 #endif
18920 }
18921 [(set_attr "prefix_rep" "1")
18922 (set_attr "type" "bitmanip")
18923 (set_attr "mode" "<MODE>")])
18924
18925 (define_insn_and_split "*popcountsi2_zext"
18926 [(set (match_operand:DI 0 "register_operand" "=r")
18927 (and:DI
18928 (subreg:DI
18929 (popcount:SI
18930 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18931 (const_int 63)))
18932 (clobber (reg:CC FLAGS_REG))]
18933 "TARGET_POPCNT && TARGET_64BIT"
18934 {
18935 #if TARGET_MACHO
18936 return "popcnt\t{%1, %k0|%k0, %1}";
18937 #else
18938 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18939 #endif
18940 }
18941 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18942 && optimize_function_for_speed_p (cfun)
18943 && !reg_mentioned_p (operands[0], operands[1])"
18944 [(parallel
18945 [(set (match_dup 0)
18946 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
18947 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18948 (clobber (reg:CC FLAGS_REG))])]
18949 "ix86_expand_clear (operands[0]);"
18950 [(set_attr "prefix_rep" "1")
18951 (set_attr "type" "bitmanip")
18952 (set_attr "mode" "SI")])
18953
18954 ; False dependency happens when destination is only updated by tzcnt,
18955 ; lzcnt or popcnt. There is no false dependency when destination is
18956 ; also used in source.
18957 (define_insn "*popcountsi2_zext_falsedep"
18958 [(set (match_operand:DI 0 "register_operand" "=r")
18959 (and:DI
18960 (subreg:DI
18961 (popcount:SI
18962 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18963 (const_int 63)))
18964 (unspec [(match_operand:DI 2 "register_operand" "0")]
18965 UNSPEC_INSN_FALSE_DEP)
18966 (clobber (reg:CC FLAGS_REG))]
18967 "TARGET_POPCNT && TARGET_64BIT"
18968 {
18969 #if TARGET_MACHO
18970 return "popcnt\t{%1, %k0|%k0, %1}";
18971 #else
18972 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18973 #endif
18974 }
18975 [(set_attr "prefix_rep" "1")
18976 (set_attr "type" "bitmanip")
18977 (set_attr "mode" "SI")])
18978
18979 (define_insn_and_split "*popcountsi2_zext_2"
18980 [(set (match_operand:DI 0 "register_operand" "=r")
18981 (zero_extend:DI
18982 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18983 (clobber (reg:CC FLAGS_REG))]
18984 "TARGET_POPCNT && TARGET_64BIT"
18985 {
18986 #if TARGET_MACHO
18987 return "popcnt\t{%1, %k0|%k0, %1}";
18988 #else
18989 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18990 #endif
18991 }
18992 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18993 && optimize_function_for_speed_p (cfun)
18994 && !reg_mentioned_p (operands[0], operands[1])"
18995 [(parallel
18996 [(set (match_dup 0)
18997 (zero_extend:DI (popcount:SI (match_dup 1))))
18998 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18999 (clobber (reg:CC FLAGS_REG))])]
19000 "ix86_expand_clear (operands[0]);"
19001 [(set_attr "prefix_rep" "1")
19002 (set_attr "type" "bitmanip")
19003 (set_attr "mode" "SI")])
19004
19005 ; False dependency happens when destination is only updated by tzcnt,
19006 ; lzcnt or popcnt. There is no false dependency when destination is
19007 ; also used in source.
19008 (define_insn "*popcountsi2_zext_2_falsedep"
19009 [(set (match_operand:DI 0 "register_operand" "=r")
19010 (zero_extend:DI
19011 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
19012 (unspec [(match_operand:DI 2 "register_operand" "0")]
19013 UNSPEC_INSN_FALSE_DEP)
19014 (clobber (reg:CC FLAGS_REG))]
19015 "TARGET_POPCNT && TARGET_64BIT"
19016 {
19017 #if TARGET_MACHO
19018 return "popcnt\t{%1, %k0|%k0, %1}";
19019 #else
19020 return "popcnt{l}\t{%1, %k0|%k0, %1}";
19021 #endif
19022 }
19023 [(set_attr "prefix_rep" "1")
19024 (set_attr "type" "bitmanip")
19025 (set_attr "mode" "SI")])
19026
19027 (define_insn_and_split "*popcounthi2_1"
19028 [(set (match_operand:SI 0 "register_operand")
19029 (popcount:SI
19030 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
19031 (clobber (reg:CC FLAGS_REG))]
19032 "TARGET_POPCNT
19033 && ix86_pre_reload_split ()"
19034 "#"
19035 "&& 1"
19036 [(const_int 0)]
19037 {
19038 rtx tmp = gen_reg_rtx (HImode);
19039
19040 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19041 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19042 DONE;
19043 })
19044
19045 (define_insn_and_split "*popcounthi2_2"
19046 [(set (match_operand:SI 0 "register_operand")
19047 (zero_extend:SI
19048 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
19049 (clobber (reg:CC FLAGS_REG))]
19050 "TARGET_POPCNT
19051 && ix86_pre_reload_split ()"
19052 "#"
19053 "&& 1"
19054 [(const_int 0)]
19055 {
19056 rtx tmp = gen_reg_rtx (HImode);
19057
19058 emit_insn (gen_popcounthi2 (tmp, operands[1]));
19059 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
19060 DONE;
19061 })
19062
19063 (define_insn "popcounthi2"
19064 [(set (match_operand:HI 0 "register_operand" "=r")
19065 (popcount:HI
19066 (match_operand:HI 1 "nonimmediate_operand" "rm")))
19067 (clobber (reg:CC FLAGS_REG))]
19068 "TARGET_POPCNT"
19069 {
19070 #if TARGET_MACHO
19071 return "popcnt\t{%1, %0|%0, %1}";
19072 #else
19073 return "popcnt{w}\t{%1, %0|%0, %1}";
19074 #endif
19075 }
19076 [(set_attr "prefix_rep" "1")
19077 (set_attr "type" "bitmanip")
19078 (set_attr "mode" "HI")])
19079
19080 (define_expand "bswapdi2"
19081 [(set (match_operand:DI 0 "register_operand")
19082 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19083 "TARGET_64BIT"
19084 {
19085 if (!TARGET_MOVBE)
19086 operands[1] = force_reg (DImode, operands[1]);
19087 })
19088
19089 (define_expand "bswapsi2"
19090 [(set (match_operand:SI 0 "register_operand")
19091 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19092 ""
19093 {
19094 if (TARGET_MOVBE)
19095 ;
19096 else if (TARGET_BSWAP)
19097 operands[1] = force_reg (SImode, operands[1]);
19098 else
19099 {
19100 rtx x = operands[0];
19101
19102 emit_move_insn (x, operands[1]);
19103 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19104 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19105 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19106 DONE;
19107 }
19108 })
19109
19110 (define_insn "*bswap<mode>2_movbe"
19111 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19112 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19113 "TARGET_MOVBE
19114 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19115 "@
19116 bswap\t%0
19117 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19118 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19119 [(set_attr "type" "bitmanip,imov,imov")
19120 (set_attr "modrm" "0,1,1")
19121 (set_attr "prefix_0f" "*,1,1")
19122 (set_attr "prefix_extra" "*,1,1")
19123 (set_attr "mode" "<MODE>")])
19124
19125 (define_insn "*bswap<mode>2"
19126 [(set (match_operand:SWI48 0 "register_operand" "=r")
19127 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19128 "TARGET_BSWAP"
19129 "bswap\t%0"
19130 [(set_attr "type" "bitmanip")
19131 (set_attr "modrm" "0")
19132 (set_attr "mode" "<MODE>")])
19133
19134 (define_expand "bswaphi2"
19135 [(set (match_operand:HI 0 "register_operand")
19136 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19137 "TARGET_MOVBE")
19138
19139 (define_insn "*bswaphi2_movbe"
19140 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19141 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19142 "TARGET_MOVBE
19143 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19144 "@
19145 xchg{b}\t{%h0, %b0|%b0, %h0}
19146 movbe{w}\t{%1, %0|%0, %1}
19147 movbe{w}\t{%1, %0|%0, %1}"
19148 [(set_attr "type" "imov")
19149 (set_attr "modrm" "*,1,1")
19150 (set_attr "prefix_0f" "*,1,1")
19151 (set_attr "prefix_extra" "*,1,1")
19152 (set_attr "pent_pair" "np,*,*")
19153 (set_attr "athlon_decode" "vector,*,*")
19154 (set_attr "amdfam10_decode" "double,*,*")
19155 (set_attr "bdver1_decode" "double,*,*")
19156 (set_attr "mode" "QI,HI,HI")])
19157
19158 (define_peephole2
19159 [(set (match_operand:HI 0 "general_reg_operand")
19160 (bswap:HI (match_dup 0)))]
19161 "TARGET_MOVBE
19162 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19163 && peep2_regno_dead_p (0, FLAGS_REG)"
19164 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19165 (clobber (reg:CC FLAGS_REG))])])
19166
19167 (define_insn "bswaphi_lowpart"
19168 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19169 (bswap:HI (match_dup 0)))
19170 (clobber (reg:CC FLAGS_REG))]
19171 ""
19172 "@
19173 xchg{b}\t{%h0, %b0|%b0, %h0}
19174 rol{w}\t{$8, %0|%0, 8}"
19175 [(set (attr "preferred_for_size")
19176 (cond [(eq_attr "alternative" "0")
19177 (symbol_ref "true")]
19178 (symbol_ref "false")))
19179 (set (attr "preferred_for_speed")
19180 (cond [(eq_attr "alternative" "0")
19181 (symbol_ref "TARGET_USE_XCHGB")]
19182 (symbol_ref "!TARGET_USE_XCHGB")))
19183 (set_attr "length" "2,4")
19184 (set_attr "mode" "QI,HI")])
19185
19186 (define_expand "paritydi2"
19187 [(set (match_operand:DI 0 "register_operand")
19188 (parity:DI (match_operand:DI 1 "register_operand")))]
19189 "! TARGET_POPCNT"
19190 {
19191 rtx scratch = gen_reg_rtx (QImode);
19192 rtx hipart1 = gen_reg_rtx (SImode);
19193 rtx lopart1 = gen_reg_rtx (SImode);
19194 rtx xor1 = gen_reg_rtx (SImode);
19195 rtx shift2 = gen_reg_rtx (SImode);
19196 rtx hipart2 = gen_reg_rtx (HImode);
19197 rtx lopart2 = gen_reg_rtx (HImode);
19198 rtx xor2 = gen_reg_rtx (HImode);
19199
19200 if (TARGET_64BIT)
19201 {
19202 rtx shift1 = gen_reg_rtx (DImode);
19203 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19204 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19205 }
19206 else
19207 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19208
19209 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19210 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19211
19212 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19213 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19214 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19215 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19216
19217 emit_insn (gen_parityhi2_cmp (xor2));
19218
19219 ix86_expand_setcc (scratch, ORDERED,
19220 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19221
19222 if (TARGET_64BIT)
19223 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19224 else
19225 {
19226 rtx tmp = gen_reg_rtx (SImode);
19227
19228 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19229 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19230 }
19231 DONE;
19232 })
19233
19234 (define_expand "paritysi2"
19235 [(set (match_operand:SI 0 "register_operand")
19236 (parity:SI (match_operand:SI 1 "register_operand")))]
19237 "! TARGET_POPCNT"
19238 {
19239 rtx scratch = gen_reg_rtx (QImode);
19240 rtx shift = gen_reg_rtx (SImode);
19241 rtx hipart = gen_reg_rtx (HImode);
19242 rtx lopart = gen_reg_rtx (HImode);
19243 rtx tmp = gen_reg_rtx (HImode);
19244
19245 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19246 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19247 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19248 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19249
19250 emit_insn (gen_parityhi2_cmp (tmp));
19251
19252 ix86_expand_setcc (scratch, ORDERED,
19253 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19254
19255 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19256 DONE;
19257 })
19258
19259 (define_expand "parityhi2"
19260 [(set (match_operand:HI 0 "register_operand")
19261 (parity:HI (match_operand:HI 1 "register_operand")))]
19262 "! TARGET_POPCNT"
19263 {
19264 rtx scratch = gen_reg_rtx (QImode);
19265
19266 emit_insn (gen_parityhi2_cmp (operands[1]));
19267
19268 ix86_expand_setcc (scratch, ORDERED,
19269 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19270
19271 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19272 DONE;
19273 })
19274
19275 (define_expand "parityqi2"
19276 [(set (match_operand:QI 0 "register_operand")
19277 (parity:QI (match_operand:QI 1 "register_operand")))]
19278 "! TARGET_POPCNT"
19279 {
19280 emit_insn (gen_parityqi2_cmp (operands[1]));
19281
19282 ix86_expand_setcc (operands[0], ORDERED,
19283 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19284 DONE;
19285 })
19286
19287 (define_insn "parityhi2_cmp"
19288 [(set (reg:CC FLAGS_REG)
19289 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19290 UNSPEC_PARITY))
19291 (clobber (match_dup 0))]
19292 ""
19293 "xor{b}\t{%h0, %b0|%b0, %h0}"
19294 [(set_attr "length" "2")
19295 (set_attr "mode" "QI")])
19296
19297 (define_insn "parityqi2_cmp"
19298 [(set (reg:CC FLAGS_REG)
19299 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19300 UNSPEC_PARITY))]
19301 ""
19302 "test{b}\t%0, %0"
19303 [(set_attr "mode" "QI")])
19304
19305 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19306 (define_peephole2
19307 [(set (match_operand:HI 0 "register_operand")
19308 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19309 (parallel [(set (reg:CC FLAGS_REG)
19310 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19311 (clobber (match_dup 0))])]
19312 ""
19313 [(set (reg:CC FLAGS_REG)
19314 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19315
19316 ;; Eliminate QImode popcount&1 using parity flag
19317 (define_peephole2
19318 [(set (match_operand:SI 0 "register_operand")
19319 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19320 (parallel [(set (match_operand:SI 2 "register_operand")
19321 (popcount:SI (match_dup 0)))
19322 (clobber (reg:CC FLAGS_REG))])
19323 (set (reg:CCZ FLAGS_REG)
19324 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19325 (const_int 1))
19326 (const_int 0)))
19327 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19328 [(reg:CCZ FLAGS_REG)
19329 (const_int 0)])
19330 (label_ref (match_operand 5))
19331 (pc)))]
19332 "REGNO (operands[2]) == REGNO (operands[3])
19333 && peep2_reg_dead_p (3, operands[0])
19334 && peep2_reg_dead_p (3, operands[2])
19335 && peep2_regno_dead_p (4, FLAGS_REG)"
19336 [(set (reg:CC FLAGS_REG)
19337 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19338 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19339 (const_int 0)])
19340 (label_ref (match_dup 5))
19341 (pc)))]
19342 {
19343 operands[4] = shallow_copy_rtx (operands[4]);
19344 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19345 })
19346
19347 ;; Eliminate HImode popcount&1 using parity flag
19348 (define_peephole2
19349 [(match_scratch:HI 0 "Q")
19350 (parallel [(set (match_operand:HI 1 "register_operand")
19351 (popcount:HI
19352 (match_operand:HI 2 "nonimmediate_operand")))
19353 (clobber (reg:CC FLAGS_REG))])
19354 (set (match_operand 3 "register_operand")
19355 (zero_extend (match_dup 1)))
19356 (set (reg:CCZ FLAGS_REG)
19357 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19358 (const_int 1))
19359 (const_int 0)))
19360 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19361 [(reg:CCZ FLAGS_REG)
19362 (const_int 0)])
19363 (label_ref (match_operand 6))
19364 (pc)))]
19365 "REGNO (operands[3]) == REGNO (operands[4])
19366 && peep2_reg_dead_p (3, operands[1])
19367 && peep2_reg_dead_p (3, operands[3])
19368 && peep2_regno_dead_p (4, FLAGS_REG)"
19369 [(set (match_dup 0) (match_dup 2))
19370 (parallel [(set (reg:CC FLAGS_REG)
19371 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19372 (clobber (match_dup 0))])
19373 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19374 (const_int 0)])
19375 (label_ref (match_dup 6))
19376 (pc)))]
19377 {
19378 operands[5] = shallow_copy_rtx (operands[5]);
19379 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19380 })
19381
19382 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19383 (define_peephole2
19384 [(match_scratch:HI 0 "Q")
19385 (parallel [(set (match_operand:HI 1 "register_operand")
19386 (popcount:HI
19387 (match_operand:HI 2 "nonimmediate_operand")))
19388 (clobber (reg:CC FLAGS_REG))])
19389 (set (reg:CCZ FLAGS_REG)
19390 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19391 (const_int 1))
19392 (const_int 0)))
19393 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19394 [(reg:CCZ FLAGS_REG)
19395 (const_int 0)])
19396 (label_ref (match_operand 5))
19397 (pc)))]
19398 "REGNO (operands[1]) == REGNO (operands[3])
19399 && peep2_reg_dead_p (2, operands[1])
19400 && peep2_reg_dead_p (2, operands[3])
19401 && peep2_regno_dead_p (3, FLAGS_REG)"
19402 [(set (match_dup 0) (match_dup 2))
19403 (parallel [(set (reg:CC FLAGS_REG)
19404 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19405 (clobber (match_dup 0))])
19406 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19407 (const_int 0)])
19408 (label_ref (match_dup 5))
19409 (pc)))]
19410 {
19411 operands[4] = shallow_copy_rtx (operands[4]);
19412 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19413 })
19414
19415 \f
19416 ;; Thread-local storage patterns for ELF.
19417 ;;
19418 ;; Note that these code sequences must appear exactly as shown
19419 ;; in order to allow linker relaxation.
19420
19421 (define_insn "*tls_global_dynamic_32_gnu"
19422 [(set (match_operand:SI 0 "register_operand" "=a")
19423 (unspec:SI
19424 [(match_operand:SI 1 "register_operand" "Yb")
19425 (match_operand 2 "tls_symbolic_operand")
19426 (match_operand 3 "constant_call_address_operand" "Bz")
19427 (reg:SI SP_REG)]
19428 UNSPEC_TLS_GD))
19429 (clobber (match_scratch:SI 4 "=d"))
19430 (clobber (match_scratch:SI 5 "=c"))
19431 (clobber (reg:CC FLAGS_REG))]
19432 "!TARGET_64BIT && TARGET_GNU_TLS"
19433 {
19434 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19435 output_asm_insn
19436 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19437 else
19438 output_asm_insn
19439 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19440 if (TARGET_SUN_TLS)
19441 #ifdef HAVE_AS_IX86_TLSGDPLT
19442 return "call\t%a2@tlsgdplt";
19443 #else
19444 return "call\t%p3@plt";
19445 #endif
19446 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19447 return "call\t%P3";
19448 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19449 }
19450 [(set_attr "type" "multi")
19451 (set_attr "length" "12")])
19452
19453 (define_expand "tls_global_dynamic_32"
19454 [(parallel
19455 [(set (match_operand:SI 0 "register_operand")
19456 (unspec:SI [(match_operand:SI 2 "register_operand")
19457 (match_operand 1 "tls_symbolic_operand")
19458 (match_operand 3 "constant_call_address_operand")
19459 (reg:SI SP_REG)]
19460 UNSPEC_TLS_GD))
19461 (clobber (scratch:SI))
19462 (clobber (scratch:SI))
19463 (clobber (reg:CC FLAGS_REG))])]
19464 ""
19465 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19466
19467 (define_insn "*tls_global_dynamic_64_<mode>"
19468 [(set (match_operand:P 0 "register_operand" "=a")
19469 (call:P
19470 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19471 (match_operand 3)))
19472 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19473 (reg:P SP_REG)]
19474 UNSPEC_TLS_GD)]
19475 "TARGET_64BIT"
19476 {
19477 if (!TARGET_X32)
19478 /* The .loc directive has effect for 'the immediately following assembly
19479 instruction'. So for a sequence:
19480 .loc f l
19481 .byte x
19482 insn1
19483 the 'immediately following assembly instruction' is insn1.
19484 We want to emit an insn prefix here, but if we use .byte (as shown in
19485 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19486 inside the insn sequence, rather than to the start. After relaxation
19487 of the sequence by the linker, the .loc might point inside an insn.
19488 Use data16 prefix instead, which doesn't have this problem. */
19489 fputs ("\tdata16", asm_out_file);
19490 output_asm_insn
19491 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19492 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19493 fputs (ASM_SHORT "0x6666\n", asm_out_file);
19494 else
19495 fputs (ASM_BYTE "0x66\n", asm_out_file);
19496 fputs ("\trex64\n", asm_out_file);
19497 if (TARGET_SUN_TLS)
19498 return "call\t%p2@plt";
19499 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19500 return "call\t%P2";
19501 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
19502 }
19503 [(set_attr "type" "multi")
19504 (set (attr "length")
19505 (symbol_ref "TARGET_X32 ? 15 : 16"))])
19506
19507 (define_insn "*tls_global_dynamic_64_largepic"
19508 [(set (match_operand:DI 0 "register_operand" "=a")
19509 (call:DI
19510 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
19511 (match_operand:DI 3 "immediate_operand" "i")))
19512 (match_operand 4)))
19513 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
19514 (reg:DI SP_REG)]
19515 UNSPEC_TLS_GD)]
19516 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19517 && GET_CODE (operands[3]) == CONST
19518 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
19519 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
19520 {
19521 output_asm_insn
19522 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19523 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
19524 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
19525 return "call\t{*%%rax|rax}";
19526 }
19527 [(set_attr "type" "multi")
19528 (set_attr "length" "22")])
19529
19530 (define_expand "@tls_global_dynamic_64_<mode>"
19531 [(parallel
19532 [(set (match_operand:P 0 "register_operand")
19533 (call:P
19534 (mem:QI (match_operand 2))
19535 (const_int 0)))
19536 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19537 (reg:P SP_REG)]
19538 UNSPEC_TLS_GD)])]
19539 "TARGET_64BIT"
19540 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19541
19542 (define_insn "*tls_local_dynamic_base_32_gnu"
19543 [(set (match_operand:SI 0 "register_operand" "=a")
19544 (unspec:SI
19545 [(match_operand:SI 1 "register_operand" "Yb")
19546 (match_operand 2 "constant_call_address_operand" "Bz")
19547 (reg:SI SP_REG)]
19548 UNSPEC_TLS_LD_BASE))
19549 (clobber (match_scratch:SI 3 "=d"))
19550 (clobber (match_scratch:SI 4 "=c"))
19551 (clobber (reg:CC FLAGS_REG))]
19552 "!TARGET_64BIT && TARGET_GNU_TLS"
19553 {
19554 output_asm_insn
19555 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
19556 if (TARGET_SUN_TLS)
19557 {
19558 if (HAVE_AS_IX86_TLSLDMPLT)
19559 return "call\t%&@tlsldmplt";
19560 else
19561 return "call\t%p2@plt";
19562 }
19563 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19564 return "call\t%P2";
19565 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
19566 }
19567 [(set_attr "type" "multi")
19568 (set_attr "length" "11")])
19569
19570 (define_expand "tls_local_dynamic_base_32"
19571 [(parallel
19572 [(set (match_operand:SI 0 "register_operand")
19573 (unspec:SI
19574 [(match_operand:SI 1 "register_operand")
19575 (match_operand 2 "constant_call_address_operand")
19576 (reg:SI SP_REG)]
19577 UNSPEC_TLS_LD_BASE))
19578 (clobber (scratch:SI))
19579 (clobber (scratch:SI))
19580 (clobber (reg:CC FLAGS_REG))])]
19581 ""
19582 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19583
19584 (define_insn "*tls_local_dynamic_base_64_<mode>"
19585 [(set (match_operand:P 0 "register_operand" "=a")
19586 (call:P
19587 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
19588 (match_operand 2)))
19589 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
19590 "TARGET_64BIT"
19591 {
19592 output_asm_insn
19593 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19594 if (TARGET_SUN_TLS)
19595 return "call\t%p1@plt";
19596 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19597 return "call\t%P1";
19598 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
19599 }
19600 [(set_attr "type" "multi")
19601 (set_attr "length" "12")])
19602
19603 (define_insn "*tls_local_dynamic_base_64_largepic"
19604 [(set (match_operand:DI 0 "register_operand" "=a")
19605 (call:DI
19606 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
19607 (match_operand:DI 2 "immediate_operand" "i")))
19608 (match_operand 3)))
19609 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
19610 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19611 && GET_CODE (operands[2]) == CONST
19612 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
19613 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
19614 {
19615 output_asm_insn
19616 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19617 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
19618 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
19619 return "call\t{*%%rax|rax}";
19620 }
19621 [(set_attr "type" "multi")
19622 (set_attr "length" "22")])
19623
19624 (define_expand "@tls_local_dynamic_base_64_<mode>"
19625 [(parallel
19626 [(set (match_operand:P 0 "register_operand")
19627 (call:P
19628 (mem:QI (match_operand 1))
19629 (const_int 0)))
19630 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
19631 "TARGET_64BIT"
19632 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19633
19634 ;; Local dynamic of a single variable is a lose. Show combine how
19635 ;; to convert that back to global dynamic.
19636
19637 (define_insn_and_split "*tls_local_dynamic_32_once"
19638 [(set (match_operand:SI 0 "register_operand" "=a")
19639 (plus:SI
19640 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
19641 (match_operand 2 "constant_call_address_operand" "Bz")
19642 (reg:SI SP_REG)]
19643 UNSPEC_TLS_LD_BASE)
19644 (const:SI (unspec:SI
19645 [(match_operand 3 "tls_symbolic_operand")]
19646 UNSPEC_DTPOFF))))
19647 (clobber (match_scratch:SI 4 "=d"))
19648 (clobber (match_scratch:SI 5 "=c"))
19649 (clobber (reg:CC FLAGS_REG))]
19650 ""
19651 "#"
19652 ""
19653 [(parallel
19654 [(set (match_dup 0)
19655 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
19656 (reg:SI SP_REG)]
19657 UNSPEC_TLS_GD))
19658 (clobber (match_dup 4))
19659 (clobber (match_dup 5))
19660 (clobber (reg:CC FLAGS_REG))])])
19661
19662 ;; Load and add the thread base pointer from %<tp_seg>:0.
19663 (define_expand "get_thread_pointer<mode>"
19664 [(set (match_operand:PTR 0 "register_operand")
19665 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19666 ""
19667 {
19668 /* targetm is not visible in the scope of the condition. */
19669 if (!targetm.have_tls)
19670 error ("%<__builtin_thread_pointer%> is not supported on this target");
19671 })
19672
19673 (define_insn_and_split "*load_tp_<mode>"
19674 [(set (match_operand:PTR 0 "register_operand" "=r")
19675 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19676 ""
19677 "#"
19678 ""
19679 [(set (match_dup 0)
19680 (match_dup 1))]
19681 {
19682 addr_space_t as = DEFAULT_TLS_SEG_REG;
19683
19684 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
19685 set_mem_addr_space (operands[1], as);
19686 })
19687
19688 (define_insn_and_split "*load_tp_x32_zext"
19689 [(set (match_operand:DI 0 "register_operand" "=r")
19690 (zero_extend:DI
19691 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
19692 "TARGET_X32"
19693 "#"
19694 "&& 1"
19695 [(set (match_dup 0)
19696 (zero_extend:DI (match_dup 1)))]
19697 {
19698 addr_space_t as = DEFAULT_TLS_SEG_REG;
19699
19700 operands[1] = gen_const_mem (SImode, const0_rtx);
19701 set_mem_addr_space (operands[1], as);
19702 })
19703
19704 (define_insn_and_split "*add_tp_<mode>"
19705 [(set (match_operand:PTR 0 "register_operand" "=r")
19706 (plus:PTR
19707 (unspec:PTR [(const_int 0)] UNSPEC_TP)
19708 (match_operand:PTR 1 "register_operand" "0")))
19709 (clobber (reg:CC FLAGS_REG))]
19710 ""
19711 "#"
19712 ""
19713 [(parallel
19714 [(set (match_dup 0)
19715 (plus:PTR (match_dup 1) (match_dup 2)))
19716 (clobber (reg:CC FLAGS_REG))])]
19717 {
19718 addr_space_t as = DEFAULT_TLS_SEG_REG;
19719
19720 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
19721 set_mem_addr_space (operands[2], as);
19722 })
19723
19724 (define_insn_and_split "*add_tp_x32_zext"
19725 [(set (match_operand:DI 0 "register_operand" "=r")
19726 (zero_extend:DI
19727 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
19728 (match_operand:SI 1 "register_operand" "0"))))
19729 (clobber (reg:CC FLAGS_REG))]
19730 "TARGET_X32"
19731 "#"
19732 "&& 1"
19733 [(parallel
19734 [(set (match_dup 0)
19735 (zero_extend:DI
19736 (plus:SI (match_dup 1) (match_dup 2))))
19737 (clobber (reg:CC FLAGS_REG))])]
19738 {
19739 addr_space_t as = DEFAULT_TLS_SEG_REG;
19740
19741 operands[2] = gen_const_mem (SImode, const0_rtx);
19742 set_mem_addr_space (operands[2], as);
19743 })
19744
19745 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
19746 ;; %rax as destination of the initial executable code sequence.
19747 (define_insn "tls_initial_exec_64_sun"
19748 [(set (match_operand:DI 0 "register_operand" "=a")
19749 (unspec:DI
19750 [(match_operand 1 "tls_symbolic_operand")]
19751 UNSPEC_TLS_IE_SUN))
19752 (clobber (reg:CC FLAGS_REG))]
19753 "TARGET_64BIT && TARGET_SUN_TLS"
19754 {
19755 output_asm_insn
19756 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
19757 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
19758 }
19759 [(set_attr "type" "multi")])
19760
19761 ;; GNU2 TLS patterns can be split.
19762
19763 (define_expand "tls_dynamic_gnu2_32"
19764 [(set (match_dup 3)
19765 (plus:SI (match_operand:SI 2 "register_operand")
19766 (const:SI
19767 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
19768 UNSPEC_TLSDESC))))
19769 (parallel
19770 [(set (match_operand:SI 0 "register_operand")
19771 (unspec:SI [(match_dup 1) (match_dup 3)
19772 (match_dup 2) (reg:SI SP_REG)]
19773 UNSPEC_TLSDESC))
19774 (clobber (reg:CC FLAGS_REG))])]
19775 "!TARGET_64BIT && TARGET_GNU2_TLS"
19776 {
19777 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
19778 ix86_tls_descriptor_calls_expanded_in_cfun = true;
19779 })
19780
19781 (define_insn "*tls_dynamic_gnu2_lea_32"
19782 [(set (match_operand:SI 0 "register_operand" "=r")
19783 (plus:SI (match_operand:SI 1 "register_operand" "b")
19784 (const:SI
19785 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
19786 UNSPEC_TLSDESC))))]
19787 "!TARGET_64BIT && TARGET_GNU2_TLS"
19788 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
19789 [(set_attr "type" "lea")
19790 (set_attr "mode" "SI")
19791 (set_attr "length" "6")
19792 (set_attr "length_address" "4")])
19793
19794 (define_insn "*tls_dynamic_gnu2_call_32"
19795 [(set (match_operand:SI 0 "register_operand" "=a")
19796 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
19797 (match_operand:SI 2 "register_operand" "0")
19798 ;; we have to make sure %ebx still points to the GOT
19799 (match_operand:SI 3 "register_operand" "b")
19800 (reg:SI SP_REG)]
19801 UNSPEC_TLSDESC))
19802 (clobber (reg:CC FLAGS_REG))]
19803 "!TARGET_64BIT && TARGET_GNU2_TLS"
19804 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
19805 [(set_attr "type" "call")
19806 (set_attr "length" "2")
19807 (set_attr "length_address" "0")])
19808
19809 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
19810 [(set (match_operand:SI 0 "register_operand" "=&a")
19811 (plus:SI
19812 (unspec:SI [(match_operand 3 "tls_modbase_operand")
19813 (match_operand:SI 4)
19814 (match_operand:SI 2 "register_operand" "b")
19815 (reg:SI SP_REG)]
19816 UNSPEC_TLSDESC)
19817 (const:SI (unspec:SI
19818 [(match_operand 1 "tls_symbolic_operand")]
19819 UNSPEC_DTPOFF))))
19820 (clobber (reg:CC FLAGS_REG))]
19821 "!TARGET_64BIT && TARGET_GNU2_TLS"
19822 "#"
19823 "&& 1"
19824 [(set (match_dup 0) (match_dup 5))]
19825 {
19826 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
19827 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
19828 })
19829
19830 (define_expand "@tls_dynamic_gnu2_64_<mode>"
19831 [(set (match_dup 2)
19832 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
19833 UNSPEC_TLSDESC))
19834 (parallel
19835 [(set (match_operand:PTR 0 "register_operand")
19836 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
19837 UNSPEC_TLSDESC))
19838 (clobber (reg:CC FLAGS_REG))])]
19839 "TARGET_64BIT && TARGET_GNU2_TLS"
19840 {
19841 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
19842 ix86_tls_descriptor_calls_expanded_in_cfun = true;
19843 })
19844
19845 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
19846 [(set (match_operand:PTR 0 "register_operand" "=r")
19847 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
19848 UNSPEC_TLSDESC))]
19849 "TARGET_64BIT && TARGET_GNU2_TLS"
19850 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
19851 [(set_attr "type" "lea")
19852 (set_attr "mode" "<MODE>")
19853 (set_attr "length" "7")
19854 (set_attr "length_address" "4")])
19855
19856 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
19857 [(set (match_operand:PTR 0 "register_operand" "=a")
19858 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
19859 (match_operand:PTR 2 "register_operand" "0")
19860 (reg:PTR SP_REG)]
19861 UNSPEC_TLSDESC))
19862 (clobber (reg:CC FLAGS_REG))]
19863 "TARGET_64BIT && TARGET_GNU2_TLS"
19864 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
19865 [(set_attr "type" "call")
19866 (set_attr "length" "2")
19867 (set_attr "length_address" "0")])
19868
19869 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
19870 [(set (match_operand:PTR 0 "register_operand" "=&a")
19871 (plus:PTR
19872 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
19873 (match_operand:PTR 3)
19874 (reg:PTR SP_REG)]
19875 UNSPEC_TLSDESC)
19876 (const:PTR (unspec:PTR
19877 [(match_operand 1 "tls_symbolic_operand")]
19878 UNSPEC_DTPOFF))))
19879 (clobber (reg:CC FLAGS_REG))]
19880 "TARGET_64BIT && TARGET_GNU2_TLS"
19881 "#"
19882 "&& 1"
19883 [(set (match_dup 0) (match_dup 4))]
19884 {
19885 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
19886 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
19887 })
19888
19889 (define_split
19890 [(match_operand 0 "tls_address_pattern")]
19891 "TARGET_TLS_DIRECT_SEG_REFS"
19892 [(match_dup 0)]
19893 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
19894
19895 \f
19896 ;; These patterns match the binary 387 instructions for addM3, subM3,
19897 ;; mulM3 and divM3. There are three patterns for each of DFmode and
19898 ;; SFmode. The first is the normal insn, the second the same insn but
19899 ;; with one operand a conversion, and the third the same insn but with
19900 ;; the other operand a conversion. The conversion may be SFmode or
19901 ;; SImode if the target mode DFmode, but only SImode if the target mode
19902 ;; is SFmode.
19903
19904 ;; Gcc is slightly more smart about handling normal two address instructions
19905 ;; so use special patterns for add and mull.
19906
19907 (define_insn "*fop_xf_comm_i387"
19908 [(set (match_operand:XF 0 "register_operand" "=f")
19909 (match_operator:XF 3 "binary_fp_operator"
19910 [(match_operand:XF 1 "register_operand" "%0")
19911 (match_operand:XF 2 "register_operand" "f")]))]
19912 "TARGET_80387
19913 && COMMUTATIVE_ARITH_P (operands[3])"
19914 "* return output_387_binary_op (insn, operands);"
19915 [(set (attr "type")
19916 (if_then_else (match_operand:XF 3 "mult_operator")
19917 (const_string "fmul")
19918 (const_string "fop")))
19919 (set_attr "mode" "XF")])
19920
19921 (define_insn "*fop_<mode>_comm"
19922 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
19923 (match_operator:MODEF 3 "binary_fp_operator"
19924 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
19925 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
19926 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19927 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
19928 && COMMUTATIVE_ARITH_P (operands[3])
19929 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
19930 "* return output_387_binary_op (insn, operands);"
19931 [(set (attr "type")
19932 (if_then_else (eq_attr "alternative" "1,2")
19933 (if_then_else (match_operand:MODEF 3 "mult_operator")
19934 (const_string "ssemul")
19935 (const_string "sseadd"))
19936 (if_then_else (match_operand:MODEF 3 "mult_operator")
19937 (const_string "fmul")
19938 (const_string "fop"))))
19939 (set_attr "isa" "*,noavx,avx")
19940 (set_attr "prefix" "orig,orig,vex")
19941 (set_attr "mode" "<MODE>")
19942 (set (attr "enabled")
19943 (if_then_else
19944 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
19945 (if_then_else
19946 (eq_attr "alternative" "0")
19947 (symbol_ref "TARGET_MIX_SSE_I387
19948 && X87_ENABLE_ARITH (<MODE>mode)")
19949 (const_string "*"))
19950 (if_then_else
19951 (eq_attr "alternative" "0")
19952 (symbol_ref "true")
19953 (symbol_ref "false"))))])
19954
19955 (define_insn "*<insn>hf"
19956 [(set (match_operand:HF 0 "register_operand" "=v")
19957 (plusminusmultdiv:HF
19958 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
19959 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
19960 "TARGET_AVX512FP16
19961 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
19962 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
19963 [(set_attr "prefix" "evex")
19964 (set_attr "mode" "HF")])
19965
19966 (define_insn "*rcpsf2_sse"
19967 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
19968 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
19969 UNSPEC_RCP))]
19970 "TARGET_SSE && TARGET_SSE_MATH"
19971 "@
19972 %vrcpss\t{%d1, %0|%0, %d1}
19973 %vrcpss\t{%d1, %0|%0, %d1}
19974 %vrcpss\t{%1, %d0|%d0, %1}"
19975 [(set_attr "type" "sse")
19976 (set_attr "atom_sse_attr" "rcp")
19977 (set_attr "btver2_sse_attr" "rcp")
19978 (set_attr "prefix" "maybe_vex")
19979 (set_attr "mode" "SF")
19980 (set_attr "avx_partial_xmm_update" "false,false,true")
19981 (set (attr "preferred_for_speed")
19982 (cond [(match_test "TARGET_AVX")
19983 (symbol_ref "true")
19984 (eq_attr "alternative" "1,2")
19985 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
19986 ]
19987 (symbol_ref "true")))])
19988
19989 (define_insn "rcphf2"
19990 [(set (match_operand:HF 0 "register_operand" "=v,v")
19991 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
19992 UNSPEC_RCP))]
19993 "TARGET_AVX512FP16"
19994 "@
19995 vrcpsh\t{%d1, %0|%0, %d1}
19996 vrcpsh\t{%1, %d0|%d0, %1}"
19997 [(set_attr "type" "sse")
19998 (set_attr "prefix" "evex")
19999 (set_attr "mode" "HF")
20000 (set_attr "avx_partial_xmm_update" "false,true")])
20001
20002 (define_insn "*fop_xf_1_i387"
20003 [(set (match_operand:XF 0 "register_operand" "=f,f")
20004 (match_operator:XF 3 "binary_fp_operator"
20005 [(match_operand:XF 1 "register_operand" "0,f")
20006 (match_operand:XF 2 "register_operand" "f,0")]))]
20007 "TARGET_80387
20008 && !COMMUTATIVE_ARITH_P (operands[3])"
20009 "* return output_387_binary_op (insn, operands);"
20010 [(set (attr "type")
20011 (if_then_else (match_operand:XF 3 "div_operator")
20012 (const_string "fdiv")
20013 (const_string "fop")))
20014 (set_attr "mode" "XF")])
20015
20016 (define_insn "*fop_<mode>_1"
20017 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
20018 (match_operator:MODEF 3 "binary_fp_operator"
20019 [(match_operand:MODEF 1
20020 "x87nonimm_ssenomem_operand" "0,fm,0,v")
20021 (match_operand:MODEF 2
20022 "nonimmediate_operand" "fm,0,xm,vm")]))]
20023 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20024 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
20025 && !COMMUTATIVE_ARITH_P (operands[3])
20026 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
20027 "* return output_387_binary_op (insn, operands);"
20028 [(set (attr "type")
20029 (if_then_else (eq_attr "alternative" "2,3")
20030 (if_then_else (match_operand:MODEF 3 "div_operator")
20031 (const_string "ssediv")
20032 (const_string "sseadd"))
20033 (if_then_else (match_operand:MODEF 3 "div_operator")
20034 (const_string "fdiv")
20035 (const_string "fop"))))
20036 (set_attr "isa" "*,*,noavx,avx")
20037 (set_attr "prefix" "orig,orig,orig,vex")
20038 (set_attr "mode" "<MODE>")
20039 (set (attr "enabled")
20040 (if_then_else
20041 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
20042 (if_then_else
20043 (eq_attr "alternative" "0,1")
20044 (symbol_ref "TARGET_MIX_SSE_I387
20045 && X87_ENABLE_ARITH (<MODE>mode)")
20046 (const_string "*"))
20047 (if_then_else
20048 (eq_attr "alternative" "0,1")
20049 (symbol_ref "true")
20050 (symbol_ref "false"))))])
20051
20052 (define_insn "*fop_<X87MODEF:mode>_2_i387"
20053 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20054 (match_operator:X87MODEF 3 "binary_fp_operator"
20055 [(float:X87MODEF
20056 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
20057 (match_operand:X87MODEF 2 "register_operand" "0")]))]
20058 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20059 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20060 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20061 || optimize_function_for_size_p (cfun))"
20062 "* return output_387_binary_op (insn, operands);"
20063 [(set (attr "type")
20064 (cond [(match_operand:X87MODEF 3 "mult_operator")
20065 (const_string "fmul")
20066 (match_operand:X87MODEF 3 "div_operator")
20067 (const_string "fdiv")
20068 ]
20069 (const_string "fop")))
20070 (set_attr "fp_int_src" "true")
20071 (set_attr "mode" "<SWI24:MODE>")])
20072
20073 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20074 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20075 (match_operator:X87MODEF 3 "binary_fp_operator"
20076 [(match_operand:X87MODEF 1 "register_operand" "0")
20077 (float:X87MODEF
20078 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20079 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20080 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20081 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20082 || optimize_function_for_size_p (cfun))"
20083 "* return output_387_binary_op (insn, operands);"
20084 [(set (attr "type")
20085 (cond [(match_operand:X87MODEF 3 "mult_operator")
20086 (const_string "fmul")
20087 (match_operand:X87MODEF 3 "div_operator")
20088 (const_string "fdiv")
20089 ]
20090 (const_string "fop")))
20091 (set_attr "fp_int_src" "true")
20092 (set_attr "mode" "<SWI24:MODE>")])
20093
20094 (define_insn "*fop_xf_4_i387"
20095 [(set (match_operand:XF 0 "register_operand" "=f,f")
20096 (match_operator:XF 3 "binary_fp_operator"
20097 [(float_extend:XF
20098 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20099 (match_operand:XF 2 "register_operand" "0,f")]))]
20100 "TARGET_80387"
20101 "* return output_387_binary_op (insn, operands);"
20102 [(set (attr "type")
20103 (cond [(match_operand:XF 3 "mult_operator")
20104 (const_string "fmul")
20105 (match_operand:XF 3 "div_operator")
20106 (const_string "fdiv")
20107 ]
20108 (const_string "fop")))
20109 (set_attr "mode" "<MODE>")])
20110
20111 (define_insn "*fop_df_4_i387"
20112 [(set (match_operand:DF 0 "register_operand" "=f,f")
20113 (match_operator:DF 3 "binary_fp_operator"
20114 [(float_extend:DF
20115 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20116 (match_operand:DF 2 "register_operand" "0,f")]))]
20117 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20118 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20119 "* return output_387_binary_op (insn, operands);"
20120 [(set (attr "type")
20121 (cond [(match_operand:DF 3 "mult_operator")
20122 (const_string "fmul")
20123 (match_operand:DF 3 "div_operator")
20124 (const_string "fdiv")
20125 ]
20126 (const_string "fop")))
20127 (set_attr "mode" "SF")])
20128
20129 (define_insn "*fop_xf_5_i387"
20130 [(set (match_operand:XF 0 "register_operand" "=f,f")
20131 (match_operator:XF 3 "binary_fp_operator"
20132 [(match_operand:XF 1 "register_operand" "0,f")
20133 (float_extend:XF
20134 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20135 "TARGET_80387"
20136 "* return output_387_binary_op (insn, operands);"
20137 [(set (attr "type")
20138 (cond [(match_operand:XF 3 "mult_operator")
20139 (const_string "fmul")
20140 (match_operand:XF 3 "div_operator")
20141 (const_string "fdiv")
20142 ]
20143 (const_string "fop")))
20144 (set_attr "mode" "<MODE>")])
20145
20146 (define_insn "*fop_df_5_i387"
20147 [(set (match_operand:DF 0 "register_operand" "=f,f")
20148 (match_operator:DF 3 "binary_fp_operator"
20149 [(match_operand:DF 1 "register_operand" "0,f")
20150 (float_extend:DF
20151 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20152 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20153 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20154 "* return output_387_binary_op (insn, operands);"
20155 [(set (attr "type")
20156 (cond [(match_operand:DF 3 "mult_operator")
20157 (const_string "fmul")
20158 (match_operand:DF 3 "div_operator")
20159 (const_string "fdiv")
20160 ]
20161 (const_string "fop")))
20162 (set_attr "mode" "SF")])
20163
20164 (define_insn "*fop_xf_6_i387"
20165 [(set (match_operand:XF 0 "register_operand" "=f,f")
20166 (match_operator:XF 3 "binary_fp_operator"
20167 [(float_extend:XF
20168 (match_operand:MODEF 1 "register_operand" "0,f"))
20169 (float_extend:XF
20170 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20171 "TARGET_80387"
20172 "* return output_387_binary_op (insn, operands);"
20173 [(set (attr "type")
20174 (cond [(match_operand:XF 3 "mult_operator")
20175 (const_string "fmul")
20176 (match_operand:XF 3 "div_operator")
20177 (const_string "fdiv")
20178 ]
20179 (const_string "fop")))
20180 (set_attr "mode" "<MODE>")])
20181
20182 (define_insn "*fop_df_6_i387"
20183 [(set (match_operand:DF 0 "register_operand" "=f,f")
20184 (match_operator:DF 3 "binary_fp_operator"
20185 [(float_extend:DF
20186 (match_operand:SF 1 "register_operand" "0,f"))
20187 (float_extend:DF
20188 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20189 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20190 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20191 "* return output_387_binary_op (insn, operands);"
20192 [(set (attr "type")
20193 (cond [(match_operand:DF 3 "mult_operator")
20194 (const_string "fmul")
20195 (match_operand:DF 3 "div_operator")
20196 (const_string "fdiv")
20197 ]
20198 (const_string "fop")))
20199 (set_attr "mode" "SF")])
20200 \f
20201 ;; FPU special functions.
20202
20203 ;; This pattern implements a no-op XFmode truncation for
20204 ;; all fancy i386 XFmode math functions.
20205
20206 (define_insn "truncxf<mode>2_i387_noop_unspec"
20207 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20208 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20209 UNSPEC_TRUNC_NOOP))]
20210 "TARGET_USE_FANCY_MATH_387"
20211 "* return output_387_reg_move (insn, operands);"
20212 [(set_attr "type" "fmov")
20213 (set_attr "mode" "<MODE>")])
20214
20215 (define_insn "sqrtxf2"
20216 [(set (match_operand:XF 0 "register_operand" "=f")
20217 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20218 "TARGET_USE_FANCY_MATH_387"
20219 "fsqrt"
20220 [(set_attr "type" "fpspc")
20221 (set_attr "mode" "XF")
20222 (set_attr "athlon_decode" "direct")
20223 (set_attr "amdfam10_decode" "direct")
20224 (set_attr "bdver1_decode" "direct")])
20225
20226 (define_insn "*rsqrtsf2_sse"
20227 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
20228 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
20229 UNSPEC_RSQRT))]
20230 "TARGET_SSE && TARGET_SSE_MATH"
20231 "@
20232 %vrsqrtss\t{%d1, %0|%0, %d1}
20233 %vrsqrtss\t{%d1, %0|%0, %d1}
20234 %vrsqrtss\t{%1, %d0|%d0, %1}"
20235 [(set_attr "type" "sse")
20236 (set_attr "atom_sse_attr" "rcp")
20237 (set_attr "btver2_sse_attr" "rcp")
20238 (set_attr "prefix" "maybe_vex")
20239 (set_attr "mode" "SF")
20240 (set_attr "avx_partial_xmm_update" "false,false,true")
20241 (set (attr "preferred_for_speed")
20242 (cond [(match_test "TARGET_AVX")
20243 (symbol_ref "true")
20244 (eq_attr "alternative" "1,2")
20245 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20246 ]
20247 (symbol_ref "true")))])
20248
20249 (define_expand "rsqrtsf2"
20250 [(set (match_operand:SF 0 "register_operand")
20251 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20252 UNSPEC_RSQRT))]
20253 "TARGET_SSE && TARGET_SSE_MATH"
20254 {
20255 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20256 DONE;
20257 })
20258
20259 (define_insn "rsqrthf2"
20260 [(set (match_operand:HF 0 "register_operand" "=v,v")
20261 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20262 UNSPEC_RSQRT))]
20263 "TARGET_AVX512FP16"
20264 "@
20265 vrsqrtsh\t{%d1, %0|%0, %d1}
20266 vrsqrtsh\t{%1, %d0|%d0, %1}"
20267 [(set_attr "type" "sse")
20268 (set_attr "prefix" "evex")
20269 (set_attr "avx_partial_xmm_update" "false,true")
20270 (set_attr "mode" "HF")])
20271
20272 (define_insn "sqrthf2"
20273 [(set (match_operand:HF 0 "register_operand" "=v,v")
20274 (sqrt:HF
20275 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20276 "TARGET_AVX512FP16"
20277 "@
20278 vsqrtsh\t{%d1, %0|%0, %d1}
20279 vsqrtsh\t{%1, %d0|%d0, %1}"
20280 [(set_attr "type" "sse")
20281 (set_attr "prefix" "evex")
20282 (set_attr "avx_partial_xmm_update" "false,true")
20283 (set_attr "mode" "HF")])
20284
20285 (define_insn "*sqrt<mode>2_sse"
20286 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20287 (sqrt:MODEF
20288 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20289 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20290 "@
20291 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20292 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20293 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20294 [(set_attr "type" "sse")
20295 (set_attr "atom_sse_attr" "sqrt")
20296 (set_attr "btver2_sse_attr" "sqrt")
20297 (set_attr "prefix" "maybe_vex")
20298 (set_attr "avx_partial_xmm_update" "false,false,true")
20299 (set_attr "mode" "<MODE>")
20300 (set (attr "preferred_for_speed")
20301 (cond [(match_test "TARGET_AVX")
20302 (symbol_ref "true")
20303 (eq_attr "alternative" "1,2")
20304 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20305 ]
20306 (symbol_ref "true")))])
20307
20308 (define_expand "sqrt<mode>2"
20309 [(set (match_operand:MODEF 0 "register_operand")
20310 (sqrt:MODEF
20311 (match_operand:MODEF 1 "nonimmediate_operand")))]
20312 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20313 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20314 {
20315 if (<MODE>mode == SFmode
20316 && TARGET_SSE && TARGET_SSE_MATH
20317 && TARGET_RECIP_SQRT
20318 && !optimize_function_for_size_p (cfun)
20319 && flag_finite_math_only && !flag_trapping_math
20320 && flag_unsafe_math_optimizations)
20321 {
20322 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20323 DONE;
20324 }
20325
20326 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20327 {
20328 rtx op0 = gen_reg_rtx (XFmode);
20329 rtx op1 = gen_reg_rtx (XFmode);
20330
20331 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20332 emit_insn (gen_sqrtxf2 (op0, op1));
20333 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20334 DONE;
20335 }
20336 })
20337
20338 (define_expand "hypot<mode>3"
20339 [(use (match_operand:MODEF 0 "register_operand"))
20340 (use (match_operand:MODEF 1 "general_operand"))
20341 (use (match_operand:MODEF 2 "general_operand"))]
20342 "TARGET_USE_FANCY_MATH_387
20343 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20344 || TARGET_MIX_SSE_I387)
20345 && flag_finite_math_only
20346 && flag_unsafe_math_optimizations"
20347 {
20348 rtx op0 = gen_reg_rtx (XFmode);
20349 rtx op1 = gen_reg_rtx (XFmode);
20350 rtx op2 = gen_reg_rtx (XFmode);
20351
20352 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20353 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20354
20355 emit_insn (gen_mulxf3 (op1, op1, op1));
20356 emit_insn (gen_mulxf3 (op2, op2, op2));
20357 emit_insn (gen_addxf3 (op0, op2, op1));
20358 emit_insn (gen_sqrtxf2 (op0, op0));
20359
20360 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20361 DONE;
20362 })
20363
20364 (define_insn "x86_fnstsw_1"
20365 [(set (match_operand:HI 0 "register_operand" "=a")
20366 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20367 "TARGET_80387"
20368 "fnstsw\t%0"
20369 [(set_attr "length" "2")
20370 (set_attr "mode" "SI")
20371 (set_attr "unit" "i387")])
20372
20373 (define_insn "fpremxf4_i387"
20374 [(set (match_operand:XF 0 "register_operand" "=f")
20375 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20376 (match_operand:XF 3 "register_operand" "1")]
20377 UNSPEC_FPREM_F))
20378 (set (match_operand:XF 1 "register_operand" "=f")
20379 (unspec:XF [(match_dup 2) (match_dup 3)]
20380 UNSPEC_FPREM_U))
20381 (set (reg:CCFP FPSR_REG)
20382 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20383 UNSPEC_C2_FLAG))]
20384 "TARGET_USE_FANCY_MATH_387"
20385 "fprem"
20386 [(set_attr "type" "fpspc")
20387 (set_attr "znver1_decode" "vector")
20388 (set_attr "mode" "XF")])
20389
20390 (define_expand "fmodxf3"
20391 [(use (match_operand:XF 0 "register_operand"))
20392 (use (match_operand:XF 1 "general_operand"))
20393 (use (match_operand:XF 2 "general_operand"))]
20394 "TARGET_USE_FANCY_MATH_387"
20395 {
20396 rtx_code_label *label = gen_label_rtx ();
20397
20398 rtx op1 = gen_reg_rtx (XFmode);
20399 rtx op2 = gen_reg_rtx (XFmode);
20400
20401 emit_move_insn (op2, operands[2]);
20402 emit_move_insn (op1, operands[1]);
20403
20404 emit_label (label);
20405 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20406 ix86_emit_fp_unordered_jump (label);
20407 LABEL_NUSES (label) = 1;
20408
20409 emit_move_insn (operands[0], op1);
20410 DONE;
20411 })
20412
20413 (define_expand "fmod<mode>3"
20414 [(use (match_operand:MODEF 0 "register_operand"))
20415 (use (match_operand:MODEF 1 "general_operand"))
20416 (use (match_operand:MODEF 2 "general_operand"))]
20417 "TARGET_USE_FANCY_MATH_387"
20418 {
20419 rtx (*gen_truncxf) (rtx, rtx);
20420
20421 rtx_code_label *label = gen_label_rtx ();
20422
20423 rtx op1 = gen_reg_rtx (XFmode);
20424 rtx op2 = gen_reg_rtx (XFmode);
20425
20426 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20427 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20428
20429 emit_label (label);
20430 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20431 ix86_emit_fp_unordered_jump (label);
20432 LABEL_NUSES (label) = 1;
20433
20434 /* Truncate the result properly for strict SSE math. */
20435 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20436 && !TARGET_MIX_SSE_I387)
20437 gen_truncxf = gen_truncxf<mode>2;
20438 else
20439 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20440
20441 emit_insn (gen_truncxf (operands[0], op1));
20442 DONE;
20443 })
20444
20445 (define_insn "fprem1xf4_i387"
20446 [(set (match_operand:XF 0 "register_operand" "=f")
20447 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20448 (match_operand:XF 3 "register_operand" "1")]
20449 UNSPEC_FPREM1_F))
20450 (set (match_operand:XF 1 "register_operand" "=f")
20451 (unspec:XF [(match_dup 2) (match_dup 3)]
20452 UNSPEC_FPREM1_U))
20453 (set (reg:CCFP FPSR_REG)
20454 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20455 UNSPEC_C2_FLAG))]
20456 "TARGET_USE_FANCY_MATH_387"
20457 "fprem1"
20458 [(set_attr "type" "fpspc")
20459 (set_attr "znver1_decode" "vector")
20460 (set_attr "mode" "XF")])
20461
20462 (define_expand "remainderxf3"
20463 [(use (match_operand:XF 0 "register_operand"))
20464 (use (match_operand:XF 1 "general_operand"))
20465 (use (match_operand:XF 2 "general_operand"))]
20466 "TARGET_USE_FANCY_MATH_387"
20467 {
20468 rtx_code_label *label = gen_label_rtx ();
20469
20470 rtx op1 = gen_reg_rtx (XFmode);
20471 rtx op2 = gen_reg_rtx (XFmode);
20472
20473 emit_move_insn (op2, operands[2]);
20474 emit_move_insn (op1, operands[1]);
20475
20476 emit_label (label);
20477 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20478 ix86_emit_fp_unordered_jump (label);
20479 LABEL_NUSES (label) = 1;
20480
20481 emit_move_insn (operands[0], op1);
20482 DONE;
20483 })
20484
20485 (define_expand "remainder<mode>3"
20486 [(use (match_operand:MODEF 0 "register_operand"))
20487 (use (match_operand:MODEF 1 "general_operand"))
20488 (use (match_operand:MODEF 2 "general_operand"))]
20489 "TARGET_USE_FANCY_MATH_387"
20490 {
20491 rtx (*gen_truncxf) (rtx, rtx);
20492
20493 rtx_code_label *label = gen_label_rtx ();
20494
20495 rtx op1 = gen_reg_rtx (XFmode);
20496 rtx op2 = gen_reg_rtx (XFmode);
20497
20498 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20499 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20500
20501 emit_label (label);
20502
20503 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20504 ix86_emit_fp_unordered_jump (label);
20505 LABEL_NUSES (label) = 1;
20506
20507 /* Truncate the result properly for strict SSE math. */
20508 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20509 && !TARGET_MIX_SSE_I387)
20510 gen_truncxf = gen_truncxf<mode>2;
20511 else
20512 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20513
20514 emit_insn (gen_truncxf (operands[0], op1));
20515 DONE;
20516 })
20517
20518 (define_int_iterator SINCOS
20519 [UNSPEC_SIN
20520 UNSPEC_COS])
20521
20522 (define_int_attr sincos
20523 [(UNSPEC_SIN "sin")
20524 (UNSPEC_COS "cos")])
20525
20526 (define_insn "<sincos>xf2"
20527 [(set (match_operand:XF 0 "register_operand" "=f")
20528 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
20529 SINCOS))]
20530 "TARGET_USE_FANCY_MATH_387
20531 && flag_unsafe_math_optimizations"
20532 "f<sincos>"
20533 [(set_attr "type" "fpspc")
20534 (set_attr "znver1_decode" "vector")
20535 (set_attr "mode" "XF")])
20536
20537 (define_expand "<sincos><mode>2"
20538 [(set (match_operand:MODEF 0 "register_operand")
20539 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
20540 SINCOS))]
20541 "TARGET_USE_FANCY_MATH_387
20542 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20543 || TARGET_MIX_SSE_I387)
20544 && flag_unsafe_math_optimizations"
20545 {
20546 rtx op0 = gen_reg_rtx (XFmode);
20547 rtx op1 = gen_reg_rtx (XFmode);
20548
20549 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20550 emit_insn (gen_<sincos>xf2 (op0, op1));
20551 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20552 DONE;
20553 })
20554
20555 (define_insn "sincosxf3"
20556 [(set (match_operand:XF 0 "register_operand" "=f")
20557 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20558 UNSPEC_SINCOS_COS))
20559 (set (match_operand:XF 1 "register_operand" "=f")
20560 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
20561 "TARGET_USE_FANCY_MATH_387
20562 && flag_unsafe_math_optimizations"
20563 "fsincos"
20564 [(set_attr "type" "fpspc")
20565 (set_attr "znver1_decode" "vector")
20566 (set_attr "mode" "XF")])
20567
20568 (define_expand "sincos<mode>3"
20569 [(use (match_operand:MODEF 0 "register_operand"))
20570 (use (match_operand:MODEF 1 "register_operand"))
20571 (use (match_operand:MODEF 2 "general_operand"))]
20572 "TARGET_USE_FANCY_MATH_387
20573 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20574 || TARGET_MIX_SSE_I387)
20575 && flag_unsafe_math_optimizations"
20576 {
20577 rtx op0 = gen_reg_rtx (XFmode);
20578 rtx op1 = gen_reg_rtx (XFmode);
20579 rtx op2 = gen_reg_rtx (XFmode);
20580
20581 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20582 emit_insn (gen_sincosxf3 (op0, op1, op2));
20583 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20584 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
20585 DONE;
20586 })
20587
20588 (define_insn "fptanxf4_i387"
20589 [(set (match_operand:SF 0 "register_operand" "=f")
20590 (match_operand:SF 3 "const1_operand"))
20591 (set (match_operand:XF 1 "register_operand" "=f")
20592 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20593 UNSPEC_TAN))]
20594 "TARGET_USE_FANCY_MATH_387
20595 && flag_unsafe_math_optimizations"
20596 "fptan"
20597 [(set_attr "type" "fpspc")
20598 (set_attr "znver1_decode" "vector")
20599 (set_attr "mode" "XF")])
20600
20601 (define_expand "tanxf2"
20602 [(use (match_operand:XF 0 "register_operand"))
20603 (use (match_operand:XF 1 "register_operand"))]
20604 "TARGET_USE_FANCY_MATH_387
20605 && flag_unsafe_math_optimizations"
20606 {
20607 rtx one = gen_reg_rtx (SFmode);
20608 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
20609 CONST1_RTX (SFmode)));
20610 DONE;
20611 })
20612
20613 (define_expand "tan<mode>2"
20614 [(use (match_operand:MODEF 0 "register_operand"))
20615 (use (match_operand:MODEF 1 "general_operand"))]
20616 "TARGET_USE_FANCY_MATH_387
20617 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20618 || TARGET_MIX_SSE_I387)
20619 && flag_unsafe_math_optimizations"
20620 {
20621 rtx op0 = gen_reg_rtx (XFmode);
20622 rtx op1 = gen_reg_rtx (XFmode);
20623
20624 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20625 emit_insn (gen_tanxf2 (op0, op1));
20626 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20627 DONE;
20628 })
20629
20630 (define_insn "atan2xf3"
20631 [(set (match_operand:XF 0 "register_operand" "=f")
20632 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20633 (match_operand:XF 1 "register_operand" "f")]
20634 UNSPEC_FPATAN))
20635 (clobber (match_scratch:XF 3 "=1"))]
20636 "TARGET_USE_FANCY_MATH_387
20637 && flag_unsafe_math_optimizations"
20638 "fpatan"
20639 [(set_attr "type" "fpspc")
20640 (set_attr "znver1_decode" "vector")
20641 (set_attr "mode" "XF")])
20642
20643 (define_expand "atan2<mode>3"
20644 [(use (match_operand:MODEF 0 "register_operand"))
20645 (use (match_operand:MODEF 1 "general_operand"))
20646 (use (match_operand:MODEF 2 "general_operand"))]
20647 "TARGET_USE_FANCY_MATH_387
20648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20649 || TARGET_MIX_SSE_I387)
20650 && flag_unsafe_math_optimizations"
20651 {
20652 rtx op0 = gen_reg_rtx (XFmode);
20653 rtx op1 = gen_reg_rtx (XFmode);
20654 rtx op2 = gen_reg_rtx (XFmode);
20655
20656 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20657 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20658
20659 emit_insn (gen_atan2xf3 (op0, op1, op2));
20660 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20661 DONE;
20662 })
20663
20664 (define_expand "atanxf2"
20665 [(parallel [(set (match_operand:XF 0 "register_operand")
20666 (unspec:XF [(match_dup 2)
20667 (match_operand:XF 1 "register_operand")]
20668 UNSPEC_FPATAN))
20669 (clobber (scratch:XF))])]
20670 "TARGET_USE_FANCY_MATH_387
20671 && flag_unsafe_math_optimizations"
20672 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
20673
20674 (define_expand "atan<mode>2"
20675 [(use (match_operand:MODEF 0 "register_operand"))
20676 (use (match_operand:MODEF 1 "general_operand"))]
20677 "TARGET_USE_FANCY_MATH_387
20678 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20679 || TARGET_MIX_SSE_I387)
20680 && flag_unsafe_math_optimizations"
20681 {
20682 rtx op0 = gen_reg_rtx (XFmode);
20683 rtx op1 = gen_reg_rtx (XFmode);
20684
20685 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20686 emit_insn (gen_atanxf2 (op0, op1));
20687 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20688 DONE;
20689 })
20690
20691 (define_expand "asinxf2"
20692 [(set (match_dup 2)
20693 (mult:XF (match_operand:XF 1 "register_operand")
20694 (match_dup 1)))
20695 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20696 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20697 (parallel [(set (match_operand:XF 0 "register_operand")
20698 (unspec:XF [(match_dup 5) (match_dup 1)]
20699 UNSPEC_FPATAN))
20700 (clobber (scratch:XF))])]
20701 "TARGET_USE_FANCY_MATH_387
20702 && flag_unsafe_math_optimizations"
20703 {
20704 int i;
20705
20706 for (i = 2; i < 6; i++)
20707 operands[i] = gen_reg_rtx (XFmode);
20708
20709 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20710 })
20711
20712 (define_expand "asin<mode>2"
20713 [(use (match_operand:MODEF 0 "register_operand"))
20714 (use (match_operand:MODEF 1 "general_operand"))]
20715 "TARGET_USE_FANCY_MATH_387
20716 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20717 || TARGET_MIX_SSE_I387)
20718 && flag_unsafe_math_optimizations"
20719 {
20720 rtx op0 = gen_reg_rtx (XFmode);
20721 rtx op1 = gen_reg_rtx (XFmode);
20722
20723 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20724 emit_insn (gen_asinxf2 (op0, op1));
20725 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20726 DONE;
20727 })
20728
20729 (define_expand "acosxf2"
20730 [(set (match_dup 2)
20731 (mult:XF (match_operand:XF 1 "register_operand")
20732 (match_dup 1)))
20733 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20734 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20735 (parallel [(set (match_operand:XF 0 "register_operand")
20736 (unspec:XF [(match_dup 1) (match_dup 5)]
20737 UNSPEC_FPATAN))
20738 (clobber (scratch:XF))])]
20739 "TARGET_USE_FANCY_MATH_387
20740 && flag_unsafe_math_optimizations"
20741 {
20742 int i;
20743
20744 for (i = 2; i < 6; i++)
20745 operands[i] = gen_reg_rtx (XFmode);
20746
20747 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20748 })
20749
20750 (define_expand "acos<mode>2"
20751 [(use (match_operand:MODEF 0 "register_operand"))
20752 (use (match_operand:MODEF 1 "general_operand"))]
20753 "TARGET_USE_FANCY_MATH_387
20754 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20755 || TARGET_MIX_SSE_I387)
20756 && flag_unsafe_math_optimizations"
20757 {
20758 rtx op0 = gen_reg_rtx (XFmode);
20759 rtx op1 = gen_reg_rtx (XFmode);
20760
20761 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20762 emit_insn (gen_acosxf2 (op0, op1));
20763 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20764 DONE;
20765 })
20766
20767 (define_expand "sinhxf2"
20768 [(use (match_operand:XF 0 "register_operand"))
20769 (use (match_operand:XF 1 "register_operand"))]
20770 "TARGET_USE_FANCY_MATH_387
20771 && flag_finite_math_only
20772 && flag_unsafe_math_optimizations"
20773 {
20774 ix86_emit_i387_sinh (operands[0], operands[1]);
20775 DONE;
20776 })
20777
20778 (define_expand "sinh<mode>2"
20779 [(use (match_operand:MODEF 0 "register_operand"))
20780 (use (match_operand:MODEF 1 "general_operand"))]
20781 "TARGET_USE_FANCY_MATH_387
20782 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20783 || TARGET_MIX_SSE_I387)
20784 && flag_finite_math_only
20785 && flag_unsafe_math_optimizations"
20786 {
20787 rtx op0 = gen_reg_rtx (XFmode);
20788 rtx op1 = gen_reg_rtx (XFmode);
20789
20790 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20791 emit_insn (gen_sinhxf2 (op0, op1));
20792 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20793 DONE;
20794 })
20795
20796 (define_expand "coshxf2"
20797 [(use (match_operand:XF 0 "register_operand"))
20798 (use (match_operand:XF 1 "register_operand"))]
20799 "TARGET_USE_FANCY_MATH_387
20800 && flag_unsafe_math_optimizations"
20801 {
20802 ix86_emit_i387_cosh (operands[0], operands[1]);
20803 DONE;
20804 })
20805
20806 (define_expand "cosh<mode>2"
20807 [(use (match_operand:MODEF 0 "register_operand"))
20808 (use (match_operand:MODEF 1 "general_operand"))]
20809 "TARGET_USE_FANCY_MATH_387
20810 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20811 || TARGET_MIX_SSE_I387)
20812 && flag_unsafe_math_optimizations"
20813 {
20814 rtx op0 = gen_reg_rtx (XFmode);
20815 rtx op1 = gen_reg_rtx (XFmode);
20816
20817 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20818 emit_insn (gen_coshxf2 (op0, op1));
20819 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20820 DONE;
20821 })
20822
20823 (define_expand "tanhxf2"
20824 [(use (match_operand:XF 0 "register_operand"))
20825 (use (match_operand:XF 1 "register_operand"))]
20826 "TARGET_USE_FANCY_MATH_387
20827 && flag_unsafe_math_optimizations"
20828 {
20829 ix86_emit_i387_tanh (operands[0], operands[1]);
20830 DONE;
20831 })
20832
20833 (define_expand "tanh<mode>2"
20834 [(use (match_operand:MODEF 0 "register_operand"))
20835 (use (match_operand:MODEF 1 "general_operand"))]
20836 "TARGET_USE_FANCY_MATH_387
20837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20838 || TARGET_MIX_SSE_I387)
20839 && flag_unsafe_math_optimizations"
20840 {
20841 rtx op0 = gen_reg_rtx (XFmode);
20842 rtx op1 = gen_reg_rtx (XFmode);
20843
20844 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20845 emit_insn (gen_tanhxf2 (op0, op1));
20846 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20847 DONE;
20848 })
20849
20850 (define_expand "asinhxf2"
20851 [(use (match_operand:XF 0 "register_operand"))
20852 (use (match_operand:XF 1 "register_operand"))]
20853 "TARGET_USE_FANCY_MATH_387
20854 && flag_finite_math_only
20855 && flag_unsafe_math_optimizations"
20856 {
20857 ix86_emit_i387_asinh (operands[0], operands[1]);
20858 DONE;
20859 })
20860
20861 (define_expand "asinh<mode>2"
20862 [(use (match_operand:MODEF 0 "register_operand"))
20863 (use (match_operand:MODEF 1 "general_operand"))]
20864 "TARGET_USE_FANCY_MATH_387
20865 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20866 || TARGET_MIX_SSE_I387)
20867 && flag_finite_math_only
20868 && flag_unsafe_math_optimizations"
20869 {
20870 rtx op0 = gen_reg_rtx (XFmode);
20871 rtx op1 = gen_reg_rtx (XFmode);
20872
20873 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20874 emit_insn (gen_asinhxf2 (op0, op1));
20875 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20876 DONE;
20877 })
20878
20879 (define_expand "acoshxf2"
20880 [(use (match_operand:XF 0 "register_operand"))
20881 (use (match_operand:XF 1 "register_operand"))]
20882 "TARGET_USE_FANCY_MATH_387
20883 && flag_unsafe_math_optimizations"
20884 {
20885 ix86_emit_i387_acosh (operands[0], operands[1]);
20886 DONE;
20887 })
20888
20889 (define_expand "acosh<mode>2"
20890 [(use (match_operand:MODEF 0 "register_operand"))
20891 (use (match_operand:MODEF 1 "general_operand"))]
20892 "TARGET_USE_FANCY_MATH_387
20893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20894 || TARGET_MIX_SSE_I387)
20895 && flag_unsafe_math_optimizations"
20896 {
20897 rtx op0 = gen_reg_rtx (XFmode);
20898 rtx op1 = gen_reg_rtx (XFmode);
20899
20900 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20901 emit_insn (gen_acoshxf2 (op0, op1));
20902 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20903 DONE;
20904 })
20905
20906 (define_expand "atanhxf2"
20907 [(use (match_operand:XF 0 "register_operand"))
20908 (use (match_operand:XF 1 "register_operand"))]
20909 "TARGET_USE_FANCY_MATH_387
20910 && flag_unsafe_math_optimizations"
20911 {
20912 ix86_emit_i387_atanh (operands[0], operands[1]);
20913 DONE;
20914 })
20915
20916 (define_expand "atanh<mode>2"
20917 [(use (match_operand:MODEF 0 "register_operand"))
20918 (use (match_operand:MODEF 1 "general_operand"))]
20919 "TARGET_USE_FANCY_MATH_387
20920 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20921 || TARGET_MIX_SSE_I387)
20922 && flag_unsafe_math_optimizations"
20923 {
20924 rtx op0 = gen_reg_rtx (XFmode);
20925 rtx op1 = gen_reg_rtx (XFmode);
20926
20927 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20928 emit_insn (gen_atanhxf2 (op0, op1));
20929 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20930 DONE;
20931 })
20932
20933 (define_insn "fyl2xxf3_i387"
20934 [(set (match_operand:XF 0 "register_operand" "=f")
20935 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
20936 (match_operand:XF 2 "register_operand" "f")]
20937 UNSPEC_FYL2X))
20938 (clobber (match_scratch:XF 3 "=2"))]
20939 "TARGET_USE_FANCY_MATH_387
20940 && flag_unsafe_math_optimizations"
20941 "fyl2x"
20942 [(set_attr "type" "fpspc")
20943 (set_attr "znver1_decode" "vector")
20944 (set_attr "mode" "XF")])
20945
20946 (define_expand "logxf2"
20947 [(parallel [(set (match_operand:XF 0 "register_operand")
20948 (unspec:XF [(match_operand:XF 1 "register_operand")
20949 (match_dup 2)] UNSPEC_FYL2X))
20950 (clobber (scratch:XF))])]
20951 "TARGET_USE_FANCY_MATH_387
20952 && flag_unsafe_math_optimizations"
20953 {
20954 operands[2]
20955 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
20956 })
20957
20958 (define_expand "log<mode>2"
20959 [(use (match_operand:MODEF 0 "register_operand"))
20960 (use (match_operand:MODEF 1 "general_operand"))]
20961 "TARGET_USE_FANCY_MATH_387
20962 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20963 || TARGET_MIX_SSE_I387)
20964 && flag_unsafe_math_optimizations"
20965 {
20966 rtx op0 = gen_reg_rtx (XFmode);
20967 rtx op1 = gen_reg_rtx (XFmode);
20968
20969 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20970 emit_insn (gen_logxf2 (op0, op1));
20971 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20972 DONE;
20973 })
20974
20975 (define_expand "log10xf2"
20976 [(parallel [(set (match_operand:XF 0 "register_operand")
20977 (unspec:XF [(match_operand:XF 1 "register_operand")
20978 (match_dup 2)] UNSPEC_FYL2X))
20979 (clobber (scratch:XF))])]
20980 "TARGET_USE_FANCY_MATH_387
20981 && flag_unsafe_math_optimizations"
20982 {
20983 operands[2]
20984 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
20985 })
20986
20987 (define_expand "log10<mode>2"
20988 [(use (match_operand:MODEF 0 "register_operand"))
20989 (use (match_operand:MODEF 1 "general_operand"))]
20990 "TARGET_USE_FANCY_MATH_387
20991 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20992 || TARGET_MIX_SSE_I387)
20993 && flag_unsafe_math_optimizations"
20994 {
20995 rtx op0 = gen_reg_rtx (XFmode);
20996 rtx op1 = gen_reg_rtx (XFmode);
20997
20998 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20999 emit_insn (gen_log10xf2 (op0, op1));
21000 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21001 DONE;
21002 })
21003
21004 (define_expand "log2xf2"
21005 [(parallel [(set (match_operand:XF 0 "register_operand")
21006 (unspec:XF [(match_operand:XF 1 "register_operand")
21007 (match_dup 2)] UNSPEC_FYL2X))
21008 (clobber (scratch:XF))])]
21009 "TARGET_USE_FANCY_MATH_387
21010 && flag_unsafe_math_optimizations"
21011 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
21012
21013 (define_expand "log2<mode>2"
21014 [(use (match_operand:MODEF 0 "register_operand"))
21015 (use (match_operand:MODEF 1 "general_operand"))]
21016 "TARGET_USE_FANCY_MATH_387
21017 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21018 || TARGET_MIX_SSE_I387)
21019 && flag_unsafe_math_optimizations"
21020 {
21021 rtx op0 = gen_reg_rtx (XFmode);
21022 rtx op1 = gen_reg_rtx (XFmode);
21023
21024 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21025 emit_insn (gen_log2xf2 (op0, op1));
21026 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21027 DONE;
21028 })
21029
21030 (define_insn "fyl2xp1xf3_i387"
21031 [(set (match_operand:XF 0 "register_operand" "=f")
21032 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
21033 (match_operand:XF 2 "register_operand" "f")]
21034 UNSPEC_FYL2XP1))
21035 (clobber (match_scratch:XF 3 "=2"))]
21036 "TARGET_USE_FANCY_MATH_387
21037 && flag_unsafe_math_optimizations"
21038 "fyl2xp1"
21039 [(set_attr "type" "fpspc")
21040 (set_attr "znver1_decode" "vector")
21041 (set_attr "mode" "XF")])
21042
21043 (define_expand "log1pxf2"
21044 [(use (match_operand:XF 0 "register_operand"))
21045 (use (match_operand:XF 1 "register_operand"))]
21046 "TARGET_USE_FANCY_MATH_387
21047 && flag_unsafe_math_optimizations"
21048 {
21049 ix86_emit_i387_log1p (operands[0], operands[1]);
21050 DONE;
21051 })
21052
21053 (define_expand "log1p<mode>2"
21054 [(use (match_operand:MODEF 0 "register_operand"))
21055 (use (match_operand:MODEF 1 "general_operand"))]
21056 "TARGET_USE_FANCY_MATH_387
21057 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21058 || TARGET_MIX_SSE_I387)
21059 && flag_unsafe_math_optimizations"
21060 {
21061 rtx op0 = gen_reg_rtx (XFmode);
21062 rtx op1 = gen_reg_rtx (XFmode);
21063
21064 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21065 emit_insn (gen_log1pxf2 (op0, op1));
21066 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21067 DONE;
21068 })
21069
21070 (define_insn "fxtractxf3_i387"
21071 [(set (match_operand:XF 0 "register_operand" "=f")
21072 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21073 UNSPEC_XTRACT_FRACT))
21074 (set (match_operand:XF 1 "register_operand" "=f")
21075 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21076 "TARGET_USE_FANCY_MATH_387
21077 && flag_unsafe_math_optimizations"
21078 "fxtract"
21079 [(set_attr "type" "fpspc")
21080 (set_attr "znver1_decode" "vector")
21081 (set_attr "mode" "XF")])
21082
21083 (define_expand "logbxf2"
21084 [(parallel [(set (match_dup 2)
21085 (unspec:XF [(match_operand:XF 1 "register_operand")]
21086 UNSPEC_XTRACT_FRACT))
21087 (set (match_operand:XF 0 "register_operand")
21088 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21089 "TARGET_USE_FANCY_MATH_387
21090 && flag_unsafe_math_optimizations"
21091 "operands[2] = gen_reg_rtx (XFmode);")
21092
21093 (define_expand "logb<mode>2"
21094 [(use (match_operand:MODEF 0 "register_operand"))
21095 (use (match_operand:MODEF 1 "general_operand"))]
21096 "TARGET_USE_FANCY_MATH_387
21097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21098 || TARGET_MIX_SSE_I387)
21099 && flag_unsafe_math_optimizations"
21100 {
21101 rtx op0 = gen_reg_rtx (XFmode);
21102 rtx op1 = gen_reg_rtx (XFmode);
21103
21104 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21105 emit_insn (gen_logbxf2 (op0, op1));
21106 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21107 DONE;
21108 })
21109
21110 (define_expand "ilogbxf2"
21111 [(use (match_operand:SI 0 "register_operand"))
21112 (use (match_operand:XF 1 "register_operand"))]
21113 "TARGET_USE_FANCY_MATH_387
21114 && flag_unsafe_math_optimizations"
21115 {
21116 rtx op0, op1;
21117
21118 if (optimize_insn_for_size_p ())
21119 FAIL;
21120
21121 op0 = gen_reg_rtx (XFmode);
21122 op1 = gen_reg_rtx (XFmode);
21123
21124 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21125 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21126 DONE;
21127 })
21128
21129 (define_expand "ilogb<mode>2"
21130 [(use (match_operand:SI 0 "register_operand"))
21131 (use (match_operand:MODEF 1 "general_operand"))]
21132 "TARGET_USE_FANCY_MATH_387
21133 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21134 || TARGET_MIX_SSE_I387)
21135 && flag_unsafe_math_optimizations"
21136 {
21137 rtx op0, op1, op2;
21138
21139 if (optimize_insn_for_size_p ())
21140 FAIL;
21141
21142 op0 = gen_reg_rtx (XFmode);
21143 op1 = gen_reg_rtx (XFmode);
21144 op2 = gen_reg_rtx (XFmode);
21145
21146 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21147 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21148 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21149 DONE;
21150 })
21151
21152 (define_insn "*f2xm1xf2_i387"
21153 [(set (match_operand:XF 0 "register_operand" "=f")
21154 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21155 UNSPEC_F2XM1))]
21156 "TARGET_USE_FANCY_MATH_387
21157 && flag_unsafe_math_optimizations"
21158 "f2xm1"
21159 [(set_attr "type" "fpspc")
21160 (set_attr "znver1_decode" "vector")
21161 (set_attr "mode" "XF")])
21162
21163 (define_insn "fscalexf4_i387"
21164 [(set (match_operand:XF 0 "register_operand" "=f")
21165 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21166 (match_operand:XF 3 "register_operand" "1")]
21167 UNSPEC_FSCALE_FRACT))
21168 (set (match_operand:XF 1 "register_operand" "=f")
21169 (unspec:XF [(match_dup 2) (match_dup 3)]
21170 UNSPEC_FSCALE_EXP))]
21171 "TARGET_USE_FANCY_MATH_387
21172 && flag_unsafe_math_optimizations"
21173 "fscale"
21174 [(set_attr "type" "fpspc")
21175 (set_attr "znver1_decode" "vector")
21176 (set_attr "mode" "XF")])
21177
21178 (define_expand "expNcorexf3"
21179 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21180 (match_operand:XF 2 "register_operand")))
21181 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21182 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21183 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21184 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21185 (parallel [(set (match_operand:XF 0 "register_operand")
21186 (unspec:XF [(match_dup 8) (match_dup 4)]
21187 UNSPEC_FSCALE_FRACT))
21188 (set (match_dup 9)
21189 (unspec:XF [(match_dup 8) (match_dup 4)]
21190 UNSPEC_FSCALE_EXP))])]
21191 "TARGET_USE_FANCY_MATH_387
21192 && flag_unsafe_math_optimizations"
21193 {
21194 int i;
21195
21196 for (i = 3; i < 10; i++)
21197 operands[i] = gen_reg_rtx (XFmode);
21198
21199 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21200 })
21201
21202 (define_expand "expxf2"
21203 [(use (match_operand:XF 0 "register_operand"))
21204 (use (match_operand:XF 1 "register_operand"))]
21205 "TARGET_USE_FANCY_MATH_387
21206 && flag_unsafe_math_optimizations"
21207 {
21208 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21209
21210 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21211 DONE;
21212 })
21213
21214 (define_expand "exp<mode>2"
21215 [(use (match_operand:MODEF 0 "register_operand"))
21216 (use (match_operand:MODEF 1 "general_operand"))]
21217 "TARGET_USE_FANCY_MATH_387
21218 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21219 || TARGET_MIX_SSE_I387)
21220 && flag_unsafe_math_optimizations"
21221 {
21222 rtx op0 = gen_reg_rtx (XFmode);
21223 rtx op1 = gen_reg_rtx (XFmode);
21224
21225 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21226 emit_insn (gen_expxf2 (op0, op1));
21227 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21228 DONE;
21229 })
21230
21231 (define_expand "exp10xf2"
21232 [(use (match_operand:XF 0 "register_operand"))
21233 (use (match_operand:XF 1 "register_operand"))]
21234 "TARGET_USE_FANCY_MATH_387
21235 && flag_unsafe_math_optimizations"
21236 {
21237 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21238
21239 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21240 DONE;
21241 })
21242
21243 (define_expand "exp10<mode>2"
21244 [(use (match_operand:MODEF 0 "register_operand"))
21245 (use (match_operand:MODEF 1 "general_operand"))]
21246 "TARGET_USE_FANCY_MATH_387
21247 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21248 || TARGET_MIX_SSE_I387)
21249 && flag_unsafe_math_optimizations"
21250 {
21251 rtx op0 = gen_reg_rtx (XFmode);
21252 rtx op1 = gen_reg_rtx (XFmode);
21253
21254 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21255 emit_insn (gen_exp10xf2 (op0, op1));
21256 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21257 DONE;
21258 })
21259
21260 (define_expand "exp2xf2"
21261 [(use (match_operand:XF 0 "register_operand"))
21262 (use (match_operand:XF 1 "register_operand"))]
21263 "TARGET_USE_FANCY_MATH_387
21264 && flag_unsafe_math_optimizations"
21265 {
21266 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21267
21268 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21269 DONE;
21270 })
21271
21272 (define_expand "exp2<mode>2"
21273 [(use (match_operand:MODEF 0 "register_operand"))
21274 (use (match_operand:MODEF 1 "general_operand"))]
21275 "TARGET_USE_FANCY_MATH_387
21276 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21277 || TARGET_MIX_SSE_I387)
21278 && flag_unsafe_math_optimizations"
21279 {
21280 rtx op0 = gen_reg_rtx (XFmode);
21281 rtx op1 = gen_reg_rtx (XFmode);
21282
21283 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21284 emit_insn (gen_exp2xf2 (op0, op1));
21285 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21286 DONE;
21287 })
21288
21289 (define_expand "expm1xf2"
21290 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21291 (match_dup 2)))
21292 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21293 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21294 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21295 (parallel [(set (match_dup 7)
21296 (unspec:XF [(match_dup 6) (match_dup 4)]
21297 UNSPEC_FSCALE_FRACT))
21298 (set (match_dup 8)
21299 (unspec:XF [(match_dup 6) (match_dup 4)]
21300 UNSPEC_FSCALE_EXP))])
21301 (parallel [(set (match_dup 10)
21302 (unspec:XF [(match_dup 9) (match_dup 8)]
21303 UNSPEC_FSCALE_FRACT))
21304 (set (match_dup 11)
21305 (unspec:XF [(match_dup 9) (match_dup 8)]
21306 UNSPEC_FSCALE_EXP))])
21307 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21308 (set (match_operand:XF 0 "register_operand")
21309 (plus:XF (match_dup 12) (match_dup 7)))]
21310 "TARGET_USE_FANCY_MATH_387
21311 && flag_unsafe_math_optimizations"
21312 {
21313 int i;
21314
21315 for (i = 2; i < 13; i++)
21316 operands[i] = gen_reg_rtx (XFmode);
21317
21318 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21319 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21320 })
21321
21322 (define_expand "expm1<mode>2"
21323 [(use (match_operand:MODEF 0 "register_operand"))
21324 (use (match_operand:MODEF 1 "general_operand"))]
21325 "TARGET_USE_FANCY_MATH_387
21326 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21327 || TARGET_MIX_SSE_I387)
21328 && flag_unsafe_math_optimizations"
21329 {
21330 rtx op0 = gen_reg_rtx (XFmode);
21331 rtx op1 = gen_reg_rtx (XFmode);
21332
21333 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21334 emit_insn (gen_expm1xf2 (op0, op1));
21335 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21336 DONE;
21337 })
21338
21339 (define_insn "avx512f_scalef<mode>2"
21340 [(set (match_operand:MODEF 0 "register_operand" "=v")
21341 (unspec:MODEF
21342 [(match_operand:MODEF 1 "register_operand" "v")
21343 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21344 UNSPEC_SCALEF))]
21345 "TARGET_AVX512F"
21346 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21347 [(set_attr "prefix" "evex")
21348 (set_attr "mode" "<MODE>")])
21349
21350 (define_expand "ldexpxf3"
21351 [(match_operand:XF 0 "register_operand")
21352 (match_operand:XF 1 "register_operand")
21353 (match_operand:SI 2 "register_operand")]
21354 "TARGET_USE_FANCY_MATH_387
21355 && flag_unsafe_math_optimizations"
21356 {
21357 rtx tmp1 = gen_reg_rtx (XFmode);
21358 rtx tmp2 = gen_reg_rtx (XFmode);
21359
21360 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21361 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21362 operands[1], tmp1));
21363 DONE;
21364 })
21365
21366 (define_expand "ldexp<mode>3"
21367 [(use (match_operand:MODEF 0 "register_operand"))
21368 (use (match_operand:MODEF 1 "general_operand"))
21369 (use (match_operand:SI 2 "register_operand"))]
21370 "((TARGET_USE_FANCY_MATH_387
21371 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21372 || TARGET_MIX_SSE_I387))
21373 || (TARGET_AVX512F && TARGET_SSE_MATH))
21374 && flag_unsafe_math_optimizations"
21375 {
21376 /* Prefer avx512f version. */
21377 if (TARGET_AVX512F && TARGET_SSE_MATH)
21378 {
21379 rtx op2 = gen_reg_rtx (<MODE>mode);
21380 operands[1] = force_reg (<MODE>mode, operands[1]);
21381
21382 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21383 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21384 }
21385 else
21386 {
21387 rtx op0 = gen_reg_rtx (XFmode);
21388 rtx op1 = gen_reg_rtx (XFmode);
21389
21390 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21391 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21392 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21393 }
21394 DONE;
21395 })
21396
21397 (define_expand "scalbxf3"
21398 [(parallel [(set (match_operand:XF 0 " register_operand")
21399 (unspec:XF [(match_operand:XF 1 "register_operand")
21400 (match_operand:XF 2 "register_operand")]
21401 UNSPEC_FSCALE_FRACT))
21402 (set (match_dup 3)
21403 (unspec:XF [(match_dup 1) (match_dup 2)]
21404 UNSPEC_FSCALE_EXP))])]
21405 "TARGET_USE_FANCY_MATH_387
21406 && flag_unsafe_math_optimizations"
21407 "operands[3] = gen_reg_rtx (XFmode);")
21408
21409 (define_expand "scalb<mode>3"
21410 [(use (match_operand:MODEF 0 "register_operand"))
21411 (use (match_operand:MODEF 1 "general_operand"))
21412 (use (match_operand:MODEF 2 "general_operand"))]
21413 "TARGET_USE_FANCY_MATH_387
21414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21415 || TARGET_MIX_SSE_I387)
21416 && flag_unsafe_math_optimizations"
21417 {
21418 rtx op0 = gen_reg_rtx (XFmode);
21419 rtx op1 = gen_reg_rtx (XFmode);
21420 rtx op2 = gen_reg_rtx (XFmode);
21421
21422 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21423 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21424 emit_insn (gen_scalbxf3 (op0, op1, op2));
21425 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21426 DONE;
21427 })
21428
21429 (define_expand "significandxf2"
21430 [(parallel [(set (match_operand:XF 0 "register_operand")
21431 (unspec:XF [(match_operand:XF 1 "register_operand")]
21432 UNSPEC_XTRACT_FRACT))
21433 (set (match_dup 2)
21434 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21435 "TARGET_USE_FANCY_MATH_387
21436 && flag_unsafe_math_optimizations"
21437 "operands[2] = gen_reg_rtx (XFmode);")
21438
21439 (define_expand "significand<mode>2"
21440 [(use (match_operand:MODEF 0 "register_operand"))
21441 (use (match_operand:MODEF 1 "general_operand"))]
21442 "TARGET_USE_FANCY_MATH_387
21443 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21444 || TARGET_MIX_SSE_I387)
21445 && flag_unsafe_math_optimizations"
21446 {
21447 rtx op0 = gen_reg_rtx (XFmode);
21448 rtx op1 = gen_reg_rtx (XFmode);
21449
21450 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21451 emit_insn (gen_significandxf2 (op0, op1));
21452 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21453 DONE;
21454 })
21455 \f
21456
21457 (define_insn "sse4_1_round<mode>2"
21458 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21459 (unspec:MODEFH
21460 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,m,v,m")
21461 (match_operand:SI 2 "const_0_to_15_operand")]
21462 UNSPEC_ROUND))]
21463 "TARGET_SSE4_1"
21464 "@
21465 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21466 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21467 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21468 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21469 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21470 [(set_attr "type" "ssecvt")
21471 (set_attr "prefix_extra" "1,1,1,*,*")
21472 (set_attr "length_immediate" "*,*,*,1,1")
21473 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21474 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21475 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21476 (set_attr "mode" "<MODE>")
21477 (set (attr "preferred_for_speed")
21478 (cond [(match_test "TARGET_AVX")
21479 (symbol_ref "true")
21480 (eq_attr "alternative" "1,2")
21481 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21482 ]
21483 (symbol_ref "true")))])
21484
21485 (define_insn "rintxf2"
21486 [(set (match_operand:XF 0 "register_operand" "=f")
21487 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21488 UNSPEC_FRNDINT))]
21489 "TARGET_USE_FANCY_MATH_387"
21490 "frndint"
21491 [(set_attr "type" "fpspc")
21492 (set_attr "znver1_decode" "vector")
21493 (set_attr "mode" "XF")])
21494
21495 (define_expand "rinthf2"
21496 [(match_operand:HF 0 "register_operand")
21497 (match_operand:HF 1 "nonimmediate_operand")]
21498 "TARGET_AVX512FP16"
21499 {
21500 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21501 operands[1],
21502 GEN_INT (ROUND_MXCSR)));
21503 DONE;
21504 })
21505
21506 (define_expand "rint<mode>2"
21507 [(use (match_operand:MODEF 0 "register_operand"))
21508 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21509 "TARGET_USE_FANCY_MATH_387
21510 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21511 {
21512 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21513 {
21514 if (TARGET_SSE4_1)
21515 emit_insn (gen_sse4_1_round<mode>2
21516 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
21517 else
21518 ix86_expand_rint (operands[0], operands[1]);
21519 }
21520 else
21521 {
21522 rtx op0 = gen_reg_rtx (XFmode);
21523 rtx op1 = gen_reg_rtx (XFmode);
21524
21525 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21526 emit_insn (gen_rintxf2 (op0, op1));
21527 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21528 }
21529 DONE;
21530 })
21531
21532 (define_expand "nearbyintxf2"
21533 [(set (match_operand:XF 0 "register_operand")
21534 (unspec:XF [(match_operand:XF 1 "register_operand")]
21535 UNSPEC_FRNDINT))]
21536 "TARGET_USE_FANCY_MATH_387
21537 && !flag_trapping_math")
21538
21539 (define_expand "nearbyinthf2"
21540 [(match_operand:HF 0 "register_operand")
21541 (match_operand:HF 1 "nonimmediate_operand")]
21542 "TARGET_AVX512FP16"
21543 {
21544 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21545 operands[1],
21546 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
21547 DONE;
21548 })
21549
21550 (define_expand "nearbyint<mode>2"
21551 [(use (match_operand:MODEF 0 "register_operand"))
21552 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21553 "(TARGET_USE_FANCY_MATH_387
21554 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21555 || TARGET_MIX_SSE_I387)
21556 && !flag_trapping_math)
21557 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
21558 {
21559 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
21560 emit_insn (gen_sse4_1_round<mode>2
21561 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
21562 | ROUND_NO_EXC)));
21563 else
21564 {
21565 rtx op0 = gen_reg_rtx (XFmode);
21566 rtx op1 = gen_reg_rtx (XFmode);
21567
21568 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21569 emit_insn (gen_nearbyintxf2 (op0, op1));
21570 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21571 }
21572 DONE;
21573 })
21574
21575 (define_expand "round<mode>2"
21576 [(match_operand:X87MODEF 0 "register_operand")
21577 (match_operand:X87MODEF 1 "nonimmediate_operand")]
21578 "(TARGET_USE_FANCY_MATH_387
21579 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21580 || TARGET_MIX_SSE_I387)
21581 && flag_unsafe_math_optimizations
21582 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21583 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21584 && !flag_trapping_math && !flag_rounding_math)"
21585 {
21586 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21587 && !flag_trapping_math && !flag_rounding_math)
21588 {
21589 if (TARGET_SSE4_1)
21590 {
21591 operands[1] = force_reg (<MODE>mode, operands[1]);
21592 ix86_expand_round_sse4 (operands[0], operands[1]);
21593 }
21594 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21595 ix86_expand_round (operands[0], operands[1]);
21596 else
21597 ix86_expand_rounddf_32 (operands[0], operands[1]);
21598 }
21599 else
21600 {
21601 operands[1] = force_reg (<MODE>mode, operands[1]);
21602 ix86_emit_i387_round (operands[0], operands[1]);
21603 }
21604 DONE;
21605 })
21606
21607 (define_insn "lrintxfdi2"
21608 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21609 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21610 UNSPEC_FIST))
21611 (clobber (match_scratch:XF 2 "=&f"))]
21612 "TARGET_USE_FANCY_MATH_387"
21613 "* return output_fix_trunc (insn, operands, false);"
21614 [(set_attr "type" "fpspc")
21615 (set_attr "mode" "DI")])
21616
21617 (define_insn "lrintxf<mode>2"
21618 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21619 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21620 UNSPEC_FIST))]
21621 "TARGET_USE_FANCY_MATH_387"
21622 "* return output_fix_trunc (insn, operands, false);"
21623 [(set_attr "type" "fpspc")
21624 (set_attr "mode" "<MODE>")])
21625
21626 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
21627 [(set (match_operand:SWI48 0 "register_operand")
21628 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
21629 UNSPEC_FIX_NOTRUNC))]
21630 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
21631
21632 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
21633 [(match_operand:SWI248x 0 "nonimmediate_operand")
21634 (match_operand:X87MODEF 1 "register_operand")]
21635 "(TARGET_USE_FANCY_MATH_387
21636 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
21637 || TARGET_MIX_SSE_I387)
21638 && flag_unsafe_math_optimizations)
21639 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21640 && <SWI248x:MODE>mode != HImode
21641 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21642 && !flag_trapping_math && !flag_rounding_math)"
21643 {
21644 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21645 && <SWI248x:MODE>mode != HImode
21646 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21647 && !flag_trapping_math && !flag_rounding_math)
21648 ix86_expand_lround (operands[0], operands[1]);
21649 else
21650 ix86_emit_i387_round (operands[0], operands[1]);
21651 DONE;
21652 })
21653
21654 (define_int_iterator FRNDINT_ROUNDING
21655 [UNSPEC_FRNDINT_ROUNDEVEN
21656 UNSPEC_FRNDINT_FLOOR
21657 UNSPEC_FRNDINT_CEIL
21658 UNSPEC_FRNDINT_TRUNC])
21659
21660 (define_int_iterator FIST_ROUNDING
21661 [UNSPEC_FIST_FLOOR
21662 UNSPEC_FIST_CEIL])
21663
21664 ;; Base name for define_insn
21665 (define_int_attr rounding_insn
21666 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21667 (UNSPEC_FRNDINT_FLOOR "floor")
21668 (UNSPEC_FRNDINT_CEIL "ceil")
21669 (UNSPEC_FRNDINT_TRUNC "btrunc")
21670 (UNSPEC_FIST_FLOOR "floor")
21671 (UNSPEC_FIST_CEIL "ceil")])
21672
21673 (define_int_attr rounding
21674 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21675 (UNSPEC_FRNDINT_FLOOR "floor")
21676 (UNSPEC_FRNDINT_CEIL "ceil")
21677 (UNSPEC_FRNDINT_TRUNC "trunc")
21678 (UNSPEC_FIST_FLOOR "floor")
21679 (UNSPEC_FIST_CEIL "ceil")])
21680
21681 (define_int_attr ROUNDING
21682 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
21683 (UNSPEC_FRNDINT_FLOOR "FLOOR")
21684 (UNSPEC_FRNDINT_CEIL "CEIL")
21685 (UNSPEC_FRNDINT_TRUNC "TRUNC")
21686 (UNSPEC_FIST_FLOOR "FLOOR")
21687 (UNSPEC_FIST_CEIL "CEIL")])
21688
21689 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21690 (define_insn_and_split "frndintxf2_<rounding>"
21691 [(set (match_operand:XF 0 "register_operand")
21692 (unspec:XF [(match_operand:XF 1 "register_operand")]
21693 FRNDINT_ROUNDING))
21694 (clobber (reg:CC FLAGS_REG))]
21695 "TARGET_USE_FANCY_MATH_387
21696 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
21697 && ix86_pre_reload_split ()"
21698 "#"
21699 "&& 1"
21700 [(const_int 0)]
21701 {
21702 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
21703
21704 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
21705 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
21706
21707 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
21708 operands[2], operands[3]));
21709 DONE;
21710 }
21711 [(set_attr "type" "frndint")
21712 (set_attr "i387_cw" "<rounding>")
21713 (set_attr "mode" "XF")])
21714
21715 (define_insn "frndintxf2_<rounding>_i387"
21716 [(set (match_operand:XF 0 "register_operand" "=f")
21717 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21718 FRNDINT_ROUNDING))
21719 (use (match_operand:HI 2 "memory_operand" "m"))
21720 (use (match_operand:HI 3 "memory_operand" "m"))]
21721 "TARGET_USE_FANCY_MATH_387
21722 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
21723 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
21724 [(set_attr "type" "frndint")
21725 (set_attr "i387_cw" "<rounding>")
21726 (set_attr "mode" "XF")])
21727
21728 (define_expand "<rounding_insn>xf2"
21729 [(parallel [(set (match_operand:XF 0 "register_operand")
21730 (unspec:XF [(match_operand:XF 1 "register_operand")]
21731 FRNDINT_ROUNDING))
21732 (clobber (reg:CC FLAGS_REG))])]
21733 "TARGET_USE_FANCY_MATH_387
21734 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
21735
21736 (define_expand "<rounding_insn>hf2"
21737 [(parallel [(set (match_operand:HF 0 "register_operand")
21738 (unspec:HF [(match_operand:HF 1 "register_operand")]
21739 FRNDINT_ROUNDING))
21740 (clobber (reg:CC FLAGS_REG))])]
21741 "TARGET_AVX512FP16"
21742 {
21743 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
21744 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
21745 DONE;
21746 })
21747
21748 (define_expand "<rounding_insn><mode>2"
21749 [(parallel [(set (match_operand:MODEF 0 "register_operand")
21750 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
21751 FRNDINT_ROUNDING))
21752 (clobber (reg:CC FLAGS_REG))])]
21753 "(TARGET_USE_FANCY_MATH_387
21754 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21755 || TARGET_MIX_SSE_I387)
21756 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21757 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21758 && (TARGET_SSE4_1
21759 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
21760 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
21761 {
21762 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21763 && (TARGET_SSE4_1
21764 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
21765 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
21766 {
21767 if (TARGET_SSE4_1)
21768 emit_insn (gen_sse4_1_round<mode>2
21769 (operands[0], operands[1],
21770 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
21771 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21772 {
21773 if (ROUND_<ROUNDING> == ROUND_FLOOR)
21774 ix86_expand_floorceil (operands[0], operands[1], true);
21775 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21776 ix86_expand_floorceil (operands[0], operands[1], false);
21777 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
21778 ix86_expand_trunc (operands[0], operands[1]);
21779 else
21780 gcc_unreachable ();
21781 }
21782 else
21783 {
21784 if (ROUND_<ROUNDING> == ROUND_FLOOR)
21785 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
21786 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21787 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
21788 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
21789 ix86_expand_truncdf_32 (operands[0], operands[1]);
21790 else
21791 gcc_unreachable ();
21792 }
21793 }
21794 else
21795 {
21796 rtx op0 = gen_reg_rtx (XFmode);
21797 rtx op1 = gen_reg_rtx (XFmode);
21798
21799 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21800 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
21801 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21802 }
21803 DONE;
21804 })
21805
21806 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21807 (define_insn_and_split "*fist<mode>2_<rounding>_1"
21808 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
21809 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
21810 FIST_ROUNDING))
21811 (clobber (reg:CC FLAGS_REG))]
21812 "TARGET_USE_FANCY_MATH_387
21813 && flag_unsafe_math_optimizations
21814 && ix86_pre_reload_split ()"
21815 "#"
21816 "&& 1"
21817 [(const_int 0)]
21818 {
21819 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
21820
21821 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
21822 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
21823
21824 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
21825 operands[2], operands[3]));
21826 DONE;
21827 }
21828 [(set_attr "type" "fistp")
21829 (set_attr "i387_cw" "<rounding>")
21830 (set_attr "mode" "<MODE>")])
21831
21832 (define_insn "fistdi2_<rounding>"
21833 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21834 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21835 FIST_ROUNDING))
21836 (use (match_operand:HI 2 "memory_operand" "m"))
21837 (use (match_operand:HI 3 "memory_operand" "m"))
21838 (clobber (match_scratch:XF 4 "=&f"))]
21839 "TARGET_USE_FANCY_MATH_387
21840 && flag_unsafe_math_optimizations"
21841 "* return output_fix_trunc (insn, operands, false);"
21842 [(set_attr "type" "fistp")
21843 (set_attr "i387_cw" "<rounding>")
21844 (set_attr "mode" "DI")])
21845
21846 (define_insn "fist<mode>2_<rounding>"
21847 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21848 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21849 FIST_ROUNDING))
21850 (use (match_operand:HI 2 "memory_operand" "m"))
21851 (use (match_operand:HI 3 "memory_operand" "m"))]
21852 "TARGET_USE_FANCY_MATH_387
21853 && flag_unsafe_math_optimizations"
21854 "* return output_fix_trunc (insn, operands, false);"
21855 [(set_attr "type" "fistp")
21856 (set_attr "i387_cw" "<rounding>")
21857 (set_attr "mode" "<MODE>")])
21858
21859 (define_expand "l<rounding_insn>xf<mode>2"
21860 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
21861 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
21862 FIST_ROUNDING))
21863 (clobber (reg:CC FLAGS_REG))])]
21864 "TARGET_USE_FANCY_MATH_387
21865 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
21866 && flag_unsafe_math_optimizations")
21867
21868 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
21869 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
21870 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
21871 FIST_ROUNDING))
21872 (clobber (reg:CC FLAGS_REG))])]
21873 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
21874 && (TARGET_SSE4_1 || !flag_trapping_math)"
21875 {
21876 if (TARGET_SSE4_1)
21877 {
21878 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
21879
21880 emit_insn (gen_sse4_1_round<MODEF:mode>2
21881 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
21882 | ROUND_NO_EXC)));
21883 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
21884 (operands[0], tmp));
21885 }
21886 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
21887 ix86_expand_lfloorceil (operands[0], operands[1], true);
21888 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21889 ix86_expand_lfloorceil (operands[0], operands[1], false);
21890 else
21891 gcc_unreachable ();
21892
21893 DONE;
21894 })
21895
21896 (define_insn "fxam<mode>2_i387"
21897 [(set (match_operand:HI 0 "register_operand" "=a")
21898 (unspec:HI
21899 [(match_operand:X87MODEF 1 "register_operand" "f")]
21900 UNSPEC_FXAM))]
21901 "TARGET_USE_FANCY_MATH_387"
21902 "fxam\n\tfnstsw\t%0"
21903 [(set_attr "type" "multi")
21904 (set_attr "length" "4")
21905 (set_attr "unit" "i387")
21906 (set_attr "mode" "<MODE>")])
21907
21908 (define_expand "signbittf2"
21909 [(use (match_operand:SI 0 "register_operand"))
21910 (use (match_operand:TF 1 "register_operand"))]
21911 "TARGET_SSE"
21912 {
21913 if (TARGET_SSE4_1)
21914 {
21915 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
21916 rtx scratch = gen_reg_rtx (QImode);
21917
21918 emit_insn (gen_ptesttf2 (operands[1], mask));
21919 ix86_expand_setcc (scratch, NE,
21920 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
21921
21922 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
21923 }
21924 else
21925 {
21926 emit_insn (gen_sse_movmskps (operands[0],
21927 gen_lowpart (V4SFmode, operands[1])));
21928 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
21929 }
21930 DONE;
21931 })
21932
21933 (define_expand "signbitxf2"
21934 [(use (match_operand:SI 0 "register_operand"))
21935 (use (match_operand:XF 1 "register_operand"))]
21936 "TARGET_USE_FANCY_MATH_387"
21937 {
21938 rtx scratch = gen_reg_rtx (HImode);
21939
21940 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
21941 emit_insn (gen_andsi3 (operands[0],
21942 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
21943 DONE;
21944 })
21945
21946 (define_insn "movmsk_df"
21947 [(set (match_operand:SI 0 "register_operand" "=r")
21948 (unspec:SI
21949 [(match_operand:DF 1 "register_operand" "x")]
21950 UNSPEC_MOVMSK))]
21951 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
21952 "%vmovmskpd\t{%1, %0|%0, %1}"
21953 [(set_attr "type" "ssemov")
21954 (set_attr "prefix" "maybe_vex")
21955 (set_attr "mode" "DF")])
21956
21957 ;; Use movmskpd in SSE mode to avoid store forwarding stall
21958 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
21959 (define_expand "signbitdf2"
21960 [(use (match_operand:SI 0 "register_operand"))
21961 (use (match_operand:DF 1 "register_operand"))]
21962 "TARGET_USE_FANCY_MATH_387
21963 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
21964 {
21965 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
21966 {
21967 emit_insn (gen_movmsk_df (operands[0], operands[1]));
21968 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
21969 }
21970 else
21971 {
21972 rtx scratch = gen_reg_rtx (HImode);
21973
21974 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
21975 emit_insn (gen_andsi3 (operands[0],
21976 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
21977 }
21978 DONE;
21979 })
21980
21981 (define_expand "signbitsf2"
21982 [(use (match_operand:SI 0 "register_operand"))
21983 (use (match_operand:SF 1 "register_operand"))]
21984 "TARGET_USE_FANCY_MATH_387
21985 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
21986 {
21987 rtx scratch = gen_reg_rtx (HImode);
21988
21989 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
21990 emit_insn (gen_andsi3 (operands[0],
21991 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
21992 DONE;
21993 })
21994 \f
21995 ;; Block operation instructions
21996
21997 (define_insn "cld"
21998 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
21999 ""
22000 "cld"
22001 [(set_attr "length" "1")
22002 (set_attr "length_immediate" "0")
22003 (set_attr "modrm" "0")])
22004
22005 (define_expand "cpymem<mode>"
22006 [(use (match_operand:BLK 0 "memory_operand"))
22007 (use (match_operand:BLK 1 "memory_operand"))
22008 (use (match_operand:SWI48 2 "nonmemory_operand"))
22009 (use (match_operand:SWI48 3 "const_int_operand"))
22010 (use (match_operand:SI 4 "const_int_operand"))
22011 (use (match_operand:SI 5 "const_int_operand"))
22012 (use (match_operand:SI 6 ""))
22013 (use (match_operand:SI 7 ""))
22014 (use (match_operand:SI 8 ""))]
22015 ""
22016 {
22017 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
22018 operands[2], NULL, operands[3],
22019 operands[4], operands[5],
22020 operands[6], operands[7],
22021 operands[8], false))
22022 DONE;
22023 else
22024 FAIL;
22025 })
22026
22027 ;; Most CPUs don't like single string operations
22028 ;; Handle this case here to simplify previous expander.
22029
22030 (define_expand "strmov"
22031 [(set (match_dup 4) (match_operand 3 "memory_operand"))
22032 (set (match_operand 1 "memory_operand") (match_dup 4))
22033 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
22034 (clobber (reg:CC FLAGS_REG))])
22035 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
22036 (clobber (reg:CC FLAGS_REG))])]
22037 ""
22038 {
22039 /* Can't use this for non-default address spaces. */
22040 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
22041 FAIL;
22042
22043 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
22044
22045 /* If .md ever supports :P for Pmode, these can be directly
22046 in the pattern above. */
22047 operands[5] = plus_constant (Pmode, operands[0], piece_size);
22048 operands[6] = plus_constant (Pmode, operands[2], piece_size);
22049
22050 /* Can't use this if the user has appropriated esi or edi. */
22051 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22052 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
22053 {
22054 emit_insn (gen_strmov_singleop (operands[0], operands[1],
22055 operands[2], operands[3],
22056 operands[5], operands[6]));
22057 DONE;
22058 }
22059
22060 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
22061 })
22062
22063 (define_expand "strmov_singleop"
22064 [(parallel [(set (match_operand 1 "memory_operand")
22065 (match_operand 3 "memory_operand"))
22066 (set (match_operand 0 "register_operand")
22067 (match_operand 4))
22068 (set (match_operand 2 "register_operand")
22069 (match_operand 5))])]
22070 ""
22071 {
22072 if (TARGET_CLD)
22073 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22074 })
22075
22076 (define_insn "*strmovdi_rex_1"
22077 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22078 (mem:DI (match_operand:P 3 "register_operand" "1")))
22079 (set (match_operand:P 0 "register_operand" "=D")
22080 (plus:P (match_dup 2)
22081 (const_int 8)))
22082 (set (match_operand:P 1 "register_operand" "=S")
22083 (plus:P (match_dup 3)
22084 (const_int 8)))]
22085 "TARGET_64BIT
22086 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22087 && ix86_check_no_addr_space (insn)"
22088 "%^movsq"
22089 [(set_attr "type" "str")
22090 (set_attr "memory" "both")
22091 (set_attr "mode" "DI")])
22092
22093 (define_insn "*strmovsi_1"
22094 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22095 (mem:SI (match_operand:P 3 "register_operand" "1")))
22096 (set (match_operand:P 0 "register_operand" "=D")
22097 (plus:P (match_dup 2)
22098 (const_int 4)))
22099 (set (match_operand:P 1 "register_operand" "=S")
22100 (plus:P (match_dup 3)
22101 (const_int 4)))]
22102 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22103 && ix86_check_no_addr_space (insn)"
22104 "%^movs{l|d}"
22105 [(set_attr "type" "str")
22106 (set_attr "memory" "both")
22107 (set_attr "mode" "SI")])
22108
22109 (define_insn "*strmovhi_1"
22110 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22111 (mem:HI (match_operand:P 3 "register_operand" "1")))
22112 (set (match_operand:P 0 "register_operand" "=D")
22113 (plus:P (match_dup 2)
22114 (const_int 2)))
22115 (set (match_operand:P 1 "register_operand" "=S")
22116 (plus:P (match_dup 3)
22117 (const_int 2)))]
22118 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22119 && ix86_check_no_addr_space (insn)"
22120 "%^movsw"
22121 [(set_attr "type" "str")
22122 (set_attr "memory" "both")
22123 (set_attr "mode" "HI")])
22124
22125 (define_insn "*strmovqi_1"
22126 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22127 (mem:QI (match_operand:P 3 "register_operand" "1")))
22128 (set (match_operand:P 0 "register_operand" "=D")
22129 (plus:P (match_dup 2)
22130 (const_int 1)))
22131 (set (match_operand:P 1 "register_operand" "=S")
22132 (plus:P (match_dup 3)
22133 (const_int 1)))]
22134 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22135 && ix86_check_no_addr_space (insn)"
22136 "%^movsb"
22137 [(set_attr "type" "str")
22138 (set_attr "memory" "both")
22139 (set (attr "prefix_rex")
22140 (if_then_else
22141 (match_test "<P:MODE>mode == DImode")
22142 (const_string "0")
22143 (const_string "*")))
22144 (set_attr "mode" "QI")])
22145
22146 (define_expand "rep_mov"
22147 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22148 (set (match_operand 0 "register_operand")
22149 (match_operand 5))
22150 (set (match_operand 2 "register_operand")
22151 (match_operand 6))
22152 (set (match_operand 1 "memory_operand")
22153 (match_operand 3 "memory_operand"))
22154 (use (match_dup 4))])]
22155 ""
22156 {
22157 if (TARGET_CLD)
22158 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22159 })
22160
22161 (define_insn "*rep_movdi_rex64"
22162 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22163 (set (match_operand:P 0 "register_operand" "=D")
22164 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22165 (const_int 3))
22166 (match_operand:P 3 "register_operand" "0")))
22167 (set (match_operand:P 1 "register_operand" "=S")
22168 (plus:P (ashift:P (match_dup 5) (const_int 3))
22169 (match_operand:P 4 "register_operand" "1")))
22170 (set (mem:BLK (match_dup 3))
22171 (mem:BLK (match_dup 4)))
22172 (use (match_dup 5))]
22173 "TARGET_64BIT
22174 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22175 && ix86_check_no_addr_space (insn)"
22176 "%^rep{%;} movsq"
22177 [(set_attr "type" "str")
22178 (set_attr "prefix_rep" "1")
22179 (set_attr "memory" "both")
22180 (set_attr "mode" "DI")])
22181
22182 (define_insn "*rep_movsi"
22183 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22184 (set (match_operand:P 0 "register_operand" "=D")
22185 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22186 (const_int 2))
22187 (match_operand:P 3 "register_operand" "0")))
22188 (set (match_operand:P 1 "register_operand" "=S")
22189 (plus:P (ashift:P (match_dup 5) (const_int 2))
22190 (match_operand:P 4 "register_operand" "1")))
22191 (set (mem:BLK (match_dup 3))
22192 (mem:BLK (match_dup 4)))
22193 (use (match_dup 5))]
22194 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22195 && ix86_check_no_addr_space (insn)"
22196 "%^rep{%;} movs{l|d}"
22197 [(set_attr "type" "str")
22198 (set_attr "prefix_rep" "1")
22199 (set_attr "memory" "both")
22200 (set_attr "mode" "SI")])
22201
22202 (define_insn "*rep_movqi"
22203 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22204 (set (match_operand:P 0 "register_operand" "=D")
22205 (plus:P (match_operand:P 3 "register_operand" "0")
22206 (match_operand:P 5 "register_operand" "2")))
22207 (set (match_operand:P 1 "register_operand" "=S")
22208 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22209 (set (mem:BLK (match_dup 3))
22210 (mem:BLK (match_dup 4)))
22211 (use (match_dup 5))]
22212 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22213 && ix86_check_no_addr_space (insn)"
22214 "%^rep{%;} movsb"
22215 [(set_attr "type" "str")
22216 (set_attr "prefix_rep" "1")
22217 (set_attr "memory" "both")
22218 (set_attr "mode" "QI")])
22219
22220 (define_expand "setmem<mode>"
22221 [(use (match_operand:BLK 0 "memory_operand"))
22222 (use (match_operand:SWI48 1 "nonmemory_operand"))
22223 (use (match_operand:QI 2 "nonmemory_operand"))
22224 (use (match_operand 3 "const_int_operand"))
22225 (use (match_operand:SI 4 "const_int_operand"))
22226 (use (match_operand:SI 5 "const_int_operand"))
22227 (use (match_operand:SI 6 ""))
22228 (use (match_operand:SI 7 ""))
22229 (use (match_operand:SI 8 ""))]
22230 ""
22231 {
22232 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22233 operands[1], operands[2],
22234 operands[3], operands[4],
22235 operands[5], operands[6],
22236 operands[7], operands[8], true))
22237 DONE;
22238 else
22239 FAIL;
22240 })
22241
22242 ;; Most CPUs don't like single string operations
22243 ;; Handle this case here to simplify previous expander.
22244
22245 (define_expand "strset"
22246 [(set (match_operand 1 "memory_operand")
22247 (match_operand 2 "register_operand"))
22248 (parallel [(set (match_operand 0 "register_operand")
22249 (match_dup 3))
22250 (clobber (reg:CC FLAGS_REG))])]
22251 ""
22252 {
22253 /* Can't use this for non-default address spaces. */
22254 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22255 FAIL;
22256
22257 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22258 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22259
22260 /* If .md ever supports :P for Pmode, this can be directly
22261 in the pattern above. */
22262 operands[3] = plus_constant (Pmode, operands[0],
22263 GET_MODE_SIZE (GET_MODE (operands[2])));
22264
22265 /* Can't use this if the user has appropriated eax or edi. */
22266 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22267 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22268 {
22269 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22270 operands[3]));
22271 DONE;
22272 }
22273 })
22274
22275 (define_expand "strset_singleop"
22276 [(parallel [(set (match_operand 1 "memory_operand")
22277 (match_operand 2 "register_operand"))
22278 (set (match_operand 0 "register_operand")
22279 (match_operand 3))
22280 (unspec [(const_int 0)] UNSPEC_STOS)])]
22281 ""
22282 {
22283 if (TARGET_CLD)
22284 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22285 })
22286
22287 (define_insn "*strsetdi_rex_1"
22288 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22289 (match_operand:DI 2 "register_operand" "a"))
22290 (set (match_operand:P 0 "register_operand" "=D")
22291 (plus:P (match_dup 1)
22292 (const_int 8)))
22293 (unspec [(const_int 0)] UNSPEC_STOS)]
22294 "TARGET_64BIT
22295 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22296 && ix86_check_no_addr_space (insn)"
22297 "%^stosq"
22298 [(set_attr "type" "str")
22299 (set_attr "memory" "store")
22300 (set_attr "mode" "DI")])
22301
22302 (define_insn "*strsetsi_1"
22303 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22304 (match_operand:SI 2 "register_operand" "a"))
22305 (set (match_operand:P 0 "register_operand" "=D")
22306 (plus:P (match_dup 1)
22307 (const_int 4)))
22308 (unspec [(const_int 0)] UNSPEC_STOS)]
22309 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22310 && ix86_check_no_addr_space (insn)"
22311 "%^stos{l|d}"
22312 [(set_attr "type" "str")
22313 (set_attr "memory" "store")
22314 (set_attr "mode" "SI")])
22315
22316 (define_insn "*strsethi_1"
22317 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22318 (match_operand:HI 2 "register_operand" "a"))
22319 (set (match_operand:P 0 "register_operand" "=D")
22320 (plus:P (match_dup 1)
22321 (const_int 2)))
22322 (unspec [(const_int 0)] UNSPEC_STOS)]
22323 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22324 && ix86_check_no_addr_space (insn)"
22325 "%^stosw"
22326 [(set_attr "type" "str")
22327 (set_attr "memory" "store")
22328 (set_attr "mode" "HI")])
22329
22330 (define_insn "*strsetqi_1"
22331 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22332 (match_operand:QI 2 "register_operand" "a"))
22333 (set (match_operand:P 0 "register_operand" "=D")
22334 (plus:P (match_dup 1)
22335 (const_int 1)))
22336 (unspec [(const_int 0)] UNSPEC_STOS)]
22337 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22338 && ix86_check_no_addr_space (insn)"
22339 "%^stosb"
22340 [(set_attr "type" "str")
22341 (set_attr "memory" "store")
22342 (set (attr "prefix_rex")
22343 (if_then_else
22344 (match_test "<P:MODE>mode == DImode")
22345 (const_string "0")
22346 (const_string "*")))
22347 (set_attr "mode" "QI")])
22348
22349 (define_expand "rep_stos"
22350 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22351 (set (match_operand 0 "register_operand")
22352 (match_operand 4))
22353 (set (match_operand 2 "memory_operand") (const_int 0))
22354 (use (match_operand 3 "register_operand"))
22355 (use (match_dup 1))])]
22356 ""
22357 {
22358 if (TARGET_CLD)
22359 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22360 })
22361
22362 (define_insn "*rep_stosdi_rex64"
22363 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22364 (set (match_operand:P 0 "register_operand" "=D")
22365 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22366 (const_int 3))
22367 (match_operand:P 3 "register_operand" "0")))
22368 (set (mem:BLK (match_dup 3))
22369 (const_int 0))
22370 (use (match_operand:DI 2 "register_operand" "a"))
22371 (use (match_dup 4))]
22372 "TARGET_64BIT
22373 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22374 && ix86_check_no_addr_space (insn)"
22375 "%^rep{%;} stosq"
22376 [(set_attr "type" "str")
22377 (set_attr "prefix_rep" "1")
22378 (set_attr "memory" "store")
22379 (set_attr "mode" "DI")])
22380
22381 (define_insn "*rep_stossi"
22382 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22383 (set (match_operand:P 0 "register_operand" "=D")
22384 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22385 (const_int 2))
22386 (match_operand:P 3 "register_operand" "0")))
22387 (set (mem:BLK (match_dup 3))
22388 (const_int 0))
22389 (use (match_operand:SI 2 "register_operand" "a"))
22390 (use (match_dup 4))]
22391 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22392 && ix86_check_no_addr_space (insn)"
22393 "%^rep{%;} stos{l|d}"
22394 [(set_attr "type" "str")
22395 (set_attr "prefix_rep" "1")
22396 (set_attr "memory" "store")
22397 (set_attr "mode" "SI")])
22398
22399 (define_insn "*rep_stosqi"
22400 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22401 (set (match_operand:P 0 "register_operand" "=D")
22402 (plus:P (match_operand:P 3 "register_operand" "0")
22403 (match_operand:P 4 "register_operand" "1")))
22404 (set (mem:BLK (match_dup 3))
22405 (const_int 0))
22406 (use (match_operand:QI 2 "register_operand" "a"))
22407 (use (match_dup 4))]
22408 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22409 && ix86_check_no_addr_space (insn)"
22410 "%^rep{%;} stosb"
22411 [(set_attr "type" "str")
22412 (set_attr "prefix_rep" "1")
22413 (set_attr "memory" "store")
22414 (set (attr "prefix_rex")
22415 (if_then_else
22416 (match_test "<P:MODE>mode == DImode")
22417 (const_string "0")
22418 (const_string "*")))
22419 (set_attr "mode" "QI")])
22420
22421 (define_expand "cmpmemsi"
22422 [(set (match_operand:SI 0 "register_operand" "")
22423 (compare:SI (match_operand:BLK 1 "memory_operand" "")
22424 (match_operand:BLK 2 "memory_operand" "") ) )
22425 (use (match_operand 3 "general_operand"))
22426 (use (match_operand 4 "immediate_operand"))]
22427 ""
22428 {
22429 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22430 operands[2], operands[3],
22431 operands[4], false))
22432 DONE;
22433 else
22434 FAIL;
22435 })
22436
22437 (define_expand "cmpstrnsi"
22438 [(set (match_operand:SI 0 "register_operand")
22439 (compare:SI (match_operand:BLK 1 "general_operand")
22440 (match_operand:BLK 2 "general_operand")))
22441 (use (match_operand 3 "general_operand"))
22442 (use (match_operand 4 "immediate_operand"))]
22443 ""
22444 {
22445 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22446 operands[2], operands[3],
22447 operands[4], true))
22448 DONE;
22449 else
22450 FAIL;
22451 })
22452
22453 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
22454
22455 (define_expand "cmpintqi"
22456 [(set (match_dup 1)
22457 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22458 (set (match_dup 2)
22459 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22460 (parallel [(set (match_operand:QI 0 "register_operand")
22461 (minus:QI (match_dup 1)
22462 (match_dup 2)))
22463 (clobber (reg:CC FLAGS_REG))])]
22464 ""
22465 {
22466 operands[1] = gen_reg_rtx (QImode);
22467 operands[2] = gen_reg_rtx (QImode);
22468 })
22469
22470 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
22471 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
22472
22473 (define_expand "cmpstrnqi_nz_1"
22474 [(parallel [(set (reg:CC FLAGS_REG)
22475 (compare:CC (match_operand 4 "memory_operand")
22476 (match_operand 5 "memory_operand")))
22477 (use (match_operand 2 "register_operand"))
22478 (use (match_operand:SI 3 "immediate_operand"))
22479 (clobber (match_operand 0 "register_operand"))
22480 (clobber (match_operand 1 "register_operand"))
22481 (clobber (match_dup 2))])]
22482 ""
22483 {
22484 if (TARGET_CLD)
22485 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22486 })
22487
22488 (define_insn "*cmpstrnqi_nz_1"
22489 [(set (reg:CC FLAGS_REG)
22490 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22491 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
22492 (use (match_operand:P 6 "register_operand" "2"))
22493 (use (match_operand:SI 3 "immediate_operand" "i"))
22494 (clobber (match_operand:P 0 "register_operand" "=S"))
22495 (clobber (match_operand:P 1 "register_operand" "=D"))
22496 (clobber (match_operand:P 2 "register_operand" "=c"))]
22497 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22498 && ix86_check_no_addr_space (insn)"
22499 "%^repz{%;} cmpsb"
22500 [(set_attr "type" "str")
22501 (set_attr "mode" "QI")
22502 (set (attr "prefix_rex")
22503 (if_then_else
22504 (match_test "<P:MODE>mode == DImode")
22505 (const_string "0")
22506 (const_string "*")))
22507 (set_attr "prefix_rep" "1")])
22508
22509 ;; The same, but the count is not known to not be zero.
22510
22511 (define_expand "cmpstrnqi_1"
22512 [(parallel [(set (reg:CC FLAGS_REG)
22513 (if_then_else:CC (ne (match_operand 2 "register_operand")
22514 (const_int 0))
22515 (compare:CC (match_operand 4 "memory_operand")
22516 (match_operand 5 "memory_operand"))
22517 (const_int 0)))
22518 (use (match_operand:SI 3 "immediate_operand"))
22519 (use (reg:CC FLAGS_REG))
22520 (clobber (match_operand 0 "register_operand"))
22521 (clobber (match_operand 1 "register_operand"))
22522 (clobber (match_dup 2))])]
22523 ""
22524 {
22525 if (TARGET_CLD)
22526 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22527 })
22528
22529 (define_insn "*cmpstrnqi_1"
22530 [(set (reg:CC FLAGS_REG)
22531 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
22532 (const_int 0))
22533 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22534 (mem:BLK (match_operand:P 5 "register_operand" "1")))
22535 (const_int 0)))
22536 (use (match_operand:SI 3 "immediate_operand" "i"))
22537 (use (reg:CC FLAGS_REG))
22538 (clobber (match_operand:P 0 "register_operand" "=S"))
22539 (clobber (match_operand:P 1 "register_operand" "=D"))
22540 (clobber (match_operand:P 2 "register_operand" "=c"))]
22541 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22542 && ix86_check_no_addr_space (insn)"
22543 "%^repz{%;} cmpsb"
22544 [(set_attr "type" "str")
22545 (set_attr "mode" "QI")
22546 (set (attr "prefix_rex")
22547 (if_then_else
22548 (match_test "<P:MODE>mode == DImode")
22549 (const_string "0")
22550 (const_string "*")))
22551 (set_attr "prefix_rep" "1")])
22552
22553 (define_expand "strlen<mode>"
22554 [(set (match_operand:P 0 "register_operand")
22555 (unspec:P [(match_operand:BLK 1 "general_operand")
22556 (match_operand:QI 2 "immediate_operand")
22557 (match_operand 3 "immediate_operand")]
22558 UNSPEC_SCAS))]
22559 ""
22560 {
22561 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
22562 DONE;
22563 else
22564 FAIL;
22565 })
22566
22567 (define_expand "strlenqi_1"
22568 [(parallel [(set (match_operand 0 "register_operand")
22569 (match_operand 2))
22570 (clobber (match_operand 1 "register_operand"))
22571 (clobber (reg:CC FLAGS_REG))])]
22572 ""
22573 {
22574 if (TARGET_CLD)
22575 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22576 })
22577
22578 (define_insn "*strlenqi_1"
22579 [(set (match_operand:P 0 "register_operand" "=&c")
22580 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
22581 (match_operand:QI 2 "register_operand" "a")
22582 (match_operand:P 3 "immediate_operand" "i")
22583 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
22584 (clobber (match_operand:P 1 "register_operand" "=D"))
22585 (clobber (reg:CC FLAGS_REG))]
22586 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22587 && ix86_check_no_addr_space (insn)"
22588 "%^repnz{%;} scasb"
22589 [(set_attr "type" "str")
22590 (set_attr "mode" "QI")
22591 (set (attr "prefix_rex")
22592 (if_then_else
22593 (match_test "<P:MODE>mode == DImode")
22594 (const_string "0")
22595 (const_string "*")))
22596 (set_attr "prefix_rep" "1")])
22597
22598 ;; Peephole optimizations to clean up after cmpstrn*. This should be
22599 ;; handled in combine, but it is not currently up to the task.
22600 ;; When used for their truth value, the cmpstrn* expanders generate
22601 ;; code like this:
22602 ;;
22603 ;; repz cmpsb
22604 ;; seta %al
22605 ;; setb %dl
22606 ;; cmpb %al, %dl
22607 ;; jcc label
22608 ;;
22609 ;; The intermediate three instructions are unnecessary.
22610
22611 ;; This one handles cmpstrn*_nz_1...
22612 (define_peephole2
22613 [(parallel[
22614 (set (reg:CC FLAGS_REG)
22615 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22616 (mem:BLK (match_operand 5 "register_operand"))))
22617 (use (match_operand 6 "register_operand"))
22618 (use (match_operand:SI 3 "immediate_operand"))
22619 (clobber (match_operand 0 "register_operand"))
22620 (clobber (match_operand 1 "register_operand"))
22621 (clobber (match_operand 2 "register_operand"))])
22622 (set (match_operand:QI 7 "register_operand")
22623 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22624 (set (match_operand:QI 8 "register_operand")
22625 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22626 (set (reg FLAGS_REG)
22627 (compare (match_dup 7) (match_dup 8)))
22628 ]
22629 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22630 [(parallel[
22631 (set (reg:CC FLAGS_REG)
22632 (compare:CC (mem:BLK (match_dup 4))
22633 (mem:BLK (match_dup 5))))
22634 (use (match_dup 6))
22635 (use (match_dup 3))
22636 (clobber (match_dup 0))
22637 (clobber (match_dup 1))
22638 (clobber (match_dup 2))])])
22639
22640 ;; ...and this one handles cmpstrn*_1.
22641 (define_peephole2
22642 [(parallel[
22643 (set (reg:CC FLAGS_REG)
22644 (if_then_else:CC (ne (match_operand 6 "register_operand")
22645 (const_int 0))
22646 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22647 (mem:BLK (match_operand 5 "register_operand")))
22648 (const_int 0)))
22649 (use (match_operand:SI 3 "immediate_operand"))
22650 (use (reg:CC FLAGS_REG))
22651 (clobber (match_operand 0 "register_operand"))
22652 (clobber (match_operand 1 "register_operand"))
22653 (clobber (match_operand 2 "register_operand"))])
22654 (set (match_operand:QI 7 "register_operand")
22655 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22656 (set (match_operand:QI 8 "register_operand")
22657 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22658 (set (reg FLAGS_REG)
22659 (compare (match_dup 7) (match_dup 8)))
22660 ]
22661 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22662 [(parallel[
22663 (set (reg:CC FLAGS_REG)
22664 (if_then_else:CC (ne (match_dup 6)
22665 (const_int 0))
22666 (compare:CC (mem:BLK (match_dup 4))
22667 (mem:BLK (match_dup 5)))
22668 (const_int 0)))
22669 (use (match_dup 3))
22670 (use (reg:CC FLAGS_REG))
22671 (clobber (match_dup 0))
22672 (clobber (match_dup 1))
22673 (clobber (match_dup 2))])])
22674 \f
22675 ;; Conditional move instructions.
22676
22677 (define_expand "mov<mode>cc"
22678 [(set (match_operand:SWIM 0 "register_operand")
22679 (if_then_else:SWIM (match_operand 1 "comparison_operator")
22680 (match_operand:SWIM 2 "<general_operand>")
22681 (match_operand:SWIM 3 "<general_operand>")))]
22682 ""
22683 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
22684
22685 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
22686 ;; the register first winds up with `sbbl $0,reg', which is also weird.
22687 ;; So just document what we're doing explicitly.
22688
22689 (define_expand "x86_mov<mode>cc_0_m1"
22690 [(parallel
22691 [(set (match_operand:SWI48 0 "register_operand")
22692 (if_then_else:SWI48
22693 (match_operator:SWI48 2 "ix86_carry_flag_operator"
22694 [(match_operand 1 "flags_reg_operand")
22695 (const_int 0)])
22696 (const_int -1)
22697 (const_int 0)))
22698 (clobber (reg:CC FLAGS_REG))])])
22699
22700 (define_insn "*x86_mov<mode>cc_0_m1"
22701 [(set (match_operand:SWI48 0 "register_operand" "=r")
22702 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
22703 [(reg FLAGS_REG) (const_int 0)])
22704 (const_int -1)
22705 (const_int 0)))
22706 (clobber (reg:CC FLAGS_REG))]
22707 ""
22708 "sbb{<imodesuffix>}\t%0, %0"
22709 [(set_attr "type" "alu1")
22710 (set_attr "use_carry" "1")
22711 (set_attr "pent_pair" "pu")
22712 (set_attr "mode" "<MODE>")
22713 (set_attr "length_immediate" "0")])
22714
22715 (define_insn "*x86_mov<mode>cc_0_m1_se"
22716 [(set (match_operand:SWI48 0 "register_operand" "=r")
22717 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
22718 [(reg FLAGS_REG) (const_int 0)])
22719 (const_int 1)
22720 (const_int 0)))
22721 (clobber (reg:CC FLAGS_REG))]
22722 ""
22723 "sbb{<imodesuffix>}\t%0, %0"
22724 [(set_attr "type" "alu1")
22725 (set_attr "use_carry" "1")
22726 (set_attr "pent_pair" "pu")
22727 (set_attr "mode" "<MODE>")
22728 (set_attr "length_immediate" "0")])
22729
22730 (define_insn "*x86_mov<mode>cc_0_m1_neg"
22731 [(set (match_operand:SWI 0 "register_operand" "=<r>")
22732 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
22733 [(reg FLAGS_REG) (const_int 0)])))
22734 (clobber (reg:CC FLAGS_REG))]
22735 ""
22736 "sbb{<imodesuffix>}\t%0, %0"
22737 [(set_attr "type" "alu1")
22738 (set_attr "use_carry" "1")
22739 (set_attr "pent_pair" "pu")
22740 (set_attr "mode" "<MODE>")
22741 (set_attr "length_immediate" "0")])
22742
22743 (define_expand "x86_mov<mode>cc_0_m1_neg"
22744 [(parallel
22745 [(set (match_operand:SWI48 0 "register_operand")
22746 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
22747 (clobber (reg:CC FLAGS_REG))])])
22748
22749 (define_split
22750 [(set (match_operand:SWI48 0 "register_operand")
22751 (neg:SWI48
22752 (leu:SWI48
22753 (match_operand 1 "int_nonimmediate_operand")
22754 (match_operand 2 "const_int_operand"))))]
22755 "x86_64_immediate_operand (operands[2], VOIDmode)
22756 && INTVAL (operands[2]) != -1
22757 && INTVAL (operands[2]) != 2147483647"
22758 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
22759 (set (match_dup 0)
22760 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
22761 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
22762
22763 (define_split
22764 [(set (match_operand:SWI 0 "register_operand")
22765 (neg:SWI
22766 (eq:SWI
22767 (match_operand 1 "int_nonimmediate_operand")
22768 (const_int 0))))]
22769 ""
22770 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
22771 (set (match_dup 0)
22772 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
22773
22774 (define_split
22775 [(set (match_operand:SWI 0 "register_operand")
22776 (neg:SWI
22777 (ne:SWI
22778 (match_operand 1 "int_nonimmediate_operand")
22779 (const_int 0))))]
22780 ""
22781 [(set (reg:CCC FLAGS_REG)
22782 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
22783 (set (match_dup 0)
22784 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
22785
22786 (define_insn "*mov<mode>cc_noc"
22787 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
22788 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22789 [(reg FLAGS_REG) (const_int 0)])
22790 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
22791 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
22792 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22793 "@
22794 cmov%O2%C1\t{%2, %0|%0, %2}
22795 cmov%O2%c1\t{%3, %0|%0, %3}"
22796 [(set_attr "type" "icmov")
22797 (set_attr "mode" "<MODE>")])
22798
22799 (define_insn "*movsicc_noc_zext"
22800 [(set (match_operand:DI 0 "register_operand" "=r,r")
22801 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
22802 [(reg FLAGS_REG) (const_int 0)])
22803 (zero_extend:DI
22804 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
22805 (zero_extend:DI
22806 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
22807 "TARGET_64BIT
22808 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22809 "@
22810 cmov%O2%C1\t{%2, %k0|%k0, %2}
22811 cmov%O2%c1\t{%3, %k0|%k0, %3}"
22812 [(set_attr "type" "icmov")
22813 (set_attr "mode" "SI")])
22814
22815 (define_insn "*movsicc_noc_zext_1"
22816 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
22817 (zero_extend:DI
22818 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
22819 [(reg FLAGS_REG) (const_int 0)])
22820 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
22821 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
22822 "TARGET_64BIT
22823 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22824 "@
22825 cmov%O2%C1\t{%2, %k0|%k0, %2}
22826 cmov%O2%c1\t{%3, %k0|%k0, %3}"
22827 [(set_attr "type" "icmov")
22828 (set_attr "mode" "SI")])
22829
22830
22831 ;; Don't do conditional moves with memory inputs. This splitter helps
22832 ;; register starved x86_32 by forcing inputs into registers before reload.
22833 (define_split
22834 [(set (match_operand:SWI248 0 "register_operand")
22835 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22836 [(reg FLAGS_REG) (const_int 0)])
22837 (match_operand:SWI248 2 "nonimmediate_operand")
22838 (match_operand:SWI248 3 "nonimmediate_operand")))]
22839 "!TARGET_64BIT && TARGET_CMOVE
22840 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22841 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22842 && can_create_pseudo_p ()
22843 && optimize_insn_for_speed_p ()"
22844 [(set (match_dup 0)
22845 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
22846 {
22847 operands[2] = force_reg (<MODE>mode, operands[2]);
22848 operands[3] = force_reg (<MODE>mode, operands[3]);
22849 })
22850
22851 (define_insn "*movqicc_noc"
22852 [(set (match_operand:QI 0 "register_operand" "=r,r")
22853 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
22854 [(reg FLAGS_REG) (const_int 0)])
22855 (match_operand:QI 2 "register_operand" "r,0")
22856 (match_operand:QI 3 "register_operand" "0,r")))]
22857 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
22858 "#"
22859 [(set_attr "type" "icmov")
22860 (set_attr "mode" "QI")])
22861
22862 (define_split
22863 [(set (match_operand:SWI12 0 "register_operand")
22864 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
22865 [(reg FLAGS_REG) (const_int 0)])
22866 (match_operand:SWI12 2 "register_operand")
22867 (match_operand:SWI12 3 "register_operand")))]
22868 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
22869 && reload_completed"
22870 [(set (match_dup 0)
22871 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
22872 {
22873 operands[0] = gen_lowpart (SImode, operands[0]);
22874 operands[2] = gen_lowpart (SImode, operands[2]);
22875 operands[3] = gen_lowpart (SImode, operands[3]);
22876 })
22877
22878 ;; Don't do conditional moves with memory inputs
22879 (define_peephole2
22880 [(match_scratch:SWI248 4 "r")
22881 (set (match_operand:SWI248 0 "register_operand")
22882 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22883 [(reg FLAGS_REG) (const_int 0)])
22884 (match_operand:SWI248 2 "nonimmediate_operand")
22885 (match_operand:SWI248 3 "nonimmediate_operand")))]
22886 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22887 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22888 && optimize_insn_for_speed_p ()"
22889 [(set (match_dup 4) (match_dup 5))
22890 (set (match_dup 0)
22891 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
22892 {
22893 if (MEM_P (operands[2]))
22894 {
22895 operands[5] = operands[2];
22896 operands[2] = operands[4];
22897 }
22898 else if (MEM_P (operands[3]))
22899 {
22900 operands[5] = operands[3];
22901 operands[3] = operands[4];
22902 }
22903 else
22904 gcc_unreachable ();
22905 })
22906
22907 (define_peephole2
22908 [(match_scratch:SI 4 "r")
22909 (set (match_operand:DI 0 "register_operand")
22910 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
22911 [(reg FLAGS_REG) (const_int 0)])
22912 (zero_extend:DI
22913 (match_operand:SI 2 "nonimmediate_operand"))
22914 (zero_extend:DI
22915 (match_operand:SI 3 "nonimmediate_operand"))))]
22916 "TARGET_64BIT
22917 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22918 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22919 && optimize_insn_for_speed_p ()"
22920 [(set (match_dup 4) (match_dup 5))
22921 (set (match_dup 0)
22922 (if_then_else:DI (match_dup 1)
22923 (zero_extend:DI (match_dup 2))
22924 (zero_extend:DI (match_dup 3))))]
22925 {
22926 if (MEM_P (operands[2]))
22927 {
22928 operands[5] = operands[2];
22929 operands[2] = operands[4];
22930 }
22931 else if (MEM_P (operands[3]))
22932 {
22933 operands[5] = operands[3];
22934 operands[3] = operands[4];
22935 }
22936 else
22937 gcc_unreachable ();
22938 })
22939
22940 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
22941 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
22942 (define_peephole2
22943 [(set (match_operand:SWI248 0 "general_reg_operand")
22944 (match_operand:SWI248 1 "general_reg_operand"))
22945 (parallel [(set (reg FLAGS_REG) (match_operand 5))
22946 (set (match_dup 0) (match_operand:SWI248 6))])
22947 (set (match_operand:SWI248 2 "general_reg_operand")
22948 (match_operand:SWI248 3 "general_gr_operand"))
22949 (set (match_dup 0)
22950 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
22951 [(reg FLAGS_REG) (const_int 0)])
22952 (match_dup 0)
22953 (match_dup 2)))]
22954 "TARGET_CMOVE
22955 && REGNO (operands[2]) != REGNO (operands[0])
22956 && REGNO (operands[2]) != REGNO (operands[1])
22957 && peep2_reg_dead_p (1, operands[1])
22958 && peep2_reg_dead_p (4, operands[2])
22959 && !reg_overlap_mentioned_p (operands[0], operands[3])"
22960 [(parallel [(set (match_dup 7) (match_dup 8))
22961 (set (match_dup 1) (match_dup 9))])
22962 (set (match_dup 0) (match_dup 3))
22963 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
22964 (match_dup 1)
22965 (match_dup 0)))]
22966 {
22967 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
22968 operands[8]
22969 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
22970 operands[9]
22971 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
22972 })
22973
22974 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
22975 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
22976 (define_peephole2
22977 [(set (match_operand:SWI248 2 "general_reg_operand")
22978 (match_operand:SWI248 3 "general_gr_operand"))
22979 (set (match_operand:SWI248 0 "general_reg_operand")
22980 (match_operand:SWI248 1 "general_reg_operand"))
22981 (parallel [(set (reg FLAGS_REG) (match_operand 5))
22982 (set (match_dup 0) (match_operand:SWI248 6))])
22983 (set (match_dup 0)
22984 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
22985 [(reg FLAGS_REG) (const_int 0)])
22986 (match_dup 0)
22987 (match_dup 2)))]
22988 "TARGET_CMOVE
22989 && REGNO (operands[2]) != REGNO (operands[0])
22990 && REGNO (operands[2]) != REGNO (operands[1])
22991 && peep2_reg_dead_p (2, operands[1])
22992 && peep2_reg_dead_p (4, operands[2])
22993 && !reg_overlap_mentioned_p (operands[0], operands[3])
22994 && !reg_mentioned_p (operands[2], operands[6])"
22995 [(parallel [(set (match_dup 7) (match_dup 8))
22996 (set (match_dup 1) (match_dup 9))])
22997 (set (match_dup 0) (match_dup 3))
22998 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
22999 (match_dup 1)
23000 (match_dup 0)))]
23001 {
23002 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
23003 operands[8]
23004 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
23005 operands[9]
23006 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
23007 })
23008
23009 (define_insn "movhf_mask"
23010 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
23011 (unspec:HF
23012 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
23013 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
23014 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
23015 UNSPEC_MOVCC_MASK))]
23016 "TARGET_AVX512FP16"
23017 "@
23018 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23019 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
23020 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
23021 [(set_attr "type" "ssemov")
23022 (set_attr "prefix" "evex")
23023 (set_attr "mode" "HF")])
23024
23025 (define_expand "movhfcc"
23026 [(set (match_operand:HF 0 "register_operand")
23027 (if_then_else:HF
23028 (match_operand 1 "comparison_operator")
23029 (match_operand:HF 2 "register_operand")
23030 (match_operand:HF 3 "register_operand")))]
23031 "TARGET_AVX512FP16"
23032 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23033
23034 (define_expand "mov<mode>cc"
23035 [(set (match_operand:X87MODEF 0 "register_operand")
23036 (if_then_else:X87MODEF
23037 (match_operand 1 "comparison_operator")
23038 (match_operand:X87MODEF 2 "register_operand")
23039 (match_operand:X87MODEF 3 "register_operand")))]
23040 "(TARGET_80387 && TARGET_CMOVE)
23041 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
23042 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
23043
23044 (define_insn "*movxfcc_1"
23045 [(set (match_operand:XF 0 "register_operand" "=f,f")
23046 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
23047 [(reg FLAGS_REG) (const_int 0)])
23048 (match_operand:XF 2 "register_operand" "f,0")
23049 (match_operand:XF 3 "register_operand" "0,f")))]
23050 "TARGET_80387 && TARGET_CMOVE"
23051 "@
23052 fcmov%F1\t{%2, %0|%0, %2}
23053 fcmov%f1\t{%3, %0|%0, %3}"
23054 [(set_attr "type" "fcmov")
23055 (set_attr "mode" "XF")])
23056
23057 (define_insn "*movdfcc_1"
23058 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
23059 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23060 [(reg FLAGS_REG) (const_int 0)])
23061 (match_operand:DF 2 "nonimmediate_operand"
23062 "f ,0,rm,0 ,rm,0")
23063 (match_operand:DF 3 "nonimmediate_operand"
23064 "0 ,f,0 ,rm,0, rm")))]
23065 "TARGET_80387 && TARGET_CMOVE
23066 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23067 "@
23068 fcmov%F1\t{%2, %0|%0, %2}
23069 fcmov%f1\t{%3, %0|%0, %3}
23070 #
23071 #
23072 cmov%O2%C1\t{%2, %0|%0, %2}
23073 cmov%O2%c1\t{%3, %0|%0, %3}"
23074 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23075 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23076 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23077
23078 (define_split
23079 [(set (match_operand:DF 0 "general_reg_operand")
23080 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23081 [(reg FLAGS_REG) (const_int 0)])
23082 (match_operand:DF 2 "nonimmediate_operand")
23083 (match_operand:DF 3 "nonimmediate_operand")))]
23084 "!TARGET_64BIT && reload_completed"
23085 [(set (match_dup 2)
23086 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23087 (set (match_dup 3)
23088 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23089 {
23090 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23091 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23092 })
23093
23094 (define_insn "*movsfcc_1_387"
23095 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23096 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23097 [(reg FLAGS_REG) (const_int 0)])
23098 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23099 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23100 "TARGET_80387 && TARGET_CMOVE
23101 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23102 "@
23103 fcmov%F1\t{%2, %0|%0, %2}
23104 fcmov%f1\t{%3, %0|%0, %3}
23105 cmov%O2%C1\t{%2, %0|%0, %2}
23106 cmov%O2%c1\t{%3, %0|%0, %3}"
23107 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23108 (set_attr "mode" "SF,SF,SI,SI")])
23109
23110 ;; Don't do conditional moves with memory inputs. This splitter helps
23111 ;; register starved x86_32 by forcing inputs into registers before reload.
23112 (define_split
23113 [(set (match_operand:MODEF 0 "register_operand")
23114 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23115 [(reg FLAGS_REG) (const_int 0)])
23116 (match_operand:MODEF 2 "nonimmediate_operand")
23117 (match_operand:MODEF 3 "nonimmediate_operand")))]
23118 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23119 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23120 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23121 && can_create_pseudo_p ()
23122 && optimize_insn_for_speed_p ()"
23123 [(set (match_dup 0)
23124 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23125 {
23126 operands[2] = force_reg (<MODE>mode, operands[2]);
23127 operands[3] = force_reg (<MODE>mode, operands[3]);
23128 })
23129
23130 ;; Don't do conditional moves with memory inputs
23131 (define_peephole2
23132 [(match_scratch:MODEF 4 "r")
23133 (set (match_operand:MODEF 0 "general_reg_operand")
23134 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23135 [(reg FLAGS_REG) (const_int 0)])
23136 (match_operand:MODEF 2 "nonimmediate_operand")
23137 (match_operand:MODEF 3 "nonimmediate_operand")))]
23138 "(<MODE>mode != DFmode || TARGET_64BIT)
23139 && TARGET_80387 && TARGET_CMOVE
23140 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23141 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23142 && optimize_insn_for_speed_p ()"
23143 [(set (match_dup 4) (match_dup 5))
23144 (set (match_dup 0)
23145 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23146 {
23147 if (MEM_P (operands[2]))
23148 {
23149 operands[5] = operands[2];
23150 operands[2] = operands[4];
23151 }
23152 else if (MEM_P (operands[3]))
23153 {
23154 operands[5] = operands[3];
23155 operands[3] = operands[4];
23156 }
23157 else
23158 gcc_unreachable ();
23159 })
23160
23161 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23162 ;; the scalar versions to have only XMM registers as operands.
23163
23164 ;; XOP conditional move
23165 (define_insn "*xop_pcmov_<mode>"
23166 [(set (match_operand:MODEF 0 "register_operand" "=x")
23167 (if_then_else:MODEF
23168 (match_operand:MODEF 1 "register_operand" "x")
23169 (match_operand:MODEF 2 "register_operand" "x")
23170 (match_operand:MODEF 3 "register_operand" "x")))]
23171 "TARGET_XOP"
23172 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23173 [(set_attr "type" "sse4arg")])
23174
23175 ;; These versions of the min/max patterns are intentionally ignorant of
23176 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23177 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23178 ;; are undefined in this condition, we're certain this is correct.
23179
23180 (define_insn "<code><mode>3"
23181 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23182 (smaxmin:MODEF
23183 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23184 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23185 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23186 "@
23187 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23188 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23189 [(set_attr "isa" "noavx,avx")
23190 (set_attr "prefix" "orig,vex")
23191 (set_attr "type" "sseadd")
23192 (set_attr "mode" "<MODE>")])
23193
23194 (define_insn "<code>hf3"
23195 [(set (match_operand:HF 0 "register_operand" "=v")
23196 (smaxmin:HF
23197 (match_operand:HF 1 "nonimmediate_operand" "%v")
23198 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23199 "TARGET_AVX512FP16"
23200 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23201 [(set_attr "prefix" "evex")
23202 (set_attr "type" "sseadd")
23203 (set_attr "mode" "HF")])
23204
23205 ;; These versions of the min/max patterns implement exactly the operations
23206 ;; min = (op1 < op2 ? op1 : op2)
23207 ;; max = (!(op1 < op2) ? op1 : op2)
23208 ;; Their operands are not commutative, and thus they may be used in the
23209 ;; presence of -0.0 and NaN.
23210
23211 (define_insn "*ieee_s<ieee_maxmin>hf3"
23212 [(set (match_operand:HF 0 "register_operand" "=v")
23213 (unspec:HF
23214 [(match_operand:HF 1 "register_operand" "v")
23215 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23216 IEEE_MAXMIN))]
23217 "TARGET_AVX512FP16"
23218 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23219 [(set_attr "prefix" "evex")
23220 (set_attr "type" "sseadd")
23221 (set_attr "mode" "HF")])
23222
23223 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23224 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23225 (unspec:MODEF
23226 [(match_operand:MODEF 1 "register_operand" "0,v")
23227 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23228 IEEE_MAXMIN))]
23229 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23230 "@
23231 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23232 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23233 [(set_attr "isa" "noavx,avx")
23234 (set_attr "prefix" "orig,maybe_evex")
23235 (set_attr "type" "sseadd")
23236 (set_attr "mode" "<MODE>")])
23237
23238 ;; Operands order in min/max instruction matters for signed zero and NANs.
23239 (define_insn_and_split "*ieee_max<mode>3_1"
23240 [(set (match_operand:MODEF 0 "register_operand")
23241 (unspec:MODEF
23242 [(match_operand:MODEF 1 "register_operand")
23243 (match_operand:MODEF 2 "register_operand")
23244 (lt:MODEF
23245 (match_operand:MODEF 3 "register_operand")
23246 (match_operand:MODEF 4 "register_operand"))]
23247 UNSPEC_BLENDV))]
23248 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23249 && (rtx_equal_p (operands[1], operands[3])
23250 && rtx_equal_p (operands[2], operands[4]))
23251 && ix86_pre_reload_split ()"
23252 "#"
23253 "&& 1"
23254 [(set (match_dup 0)
23255 (unspec:MODEF
23256 [(match_dup 2)
23257 (match_dup 1)]
23258 UNSPEC_IEEE_MAX))])
23259
23260 (define_insn_and_split "*ieee_min<mode>3_1"
23261 [(set (match_operand:MODEF 0 "register_operand")
23262 (unspec:MODEF
23263 [(match_operand:MODEF 1 "register_operand")
23264 (match_operand:MODEF 2 "register_operand")
23265 (lt:MODEF
23266 (match_operand:MODEF 3 "register_operand")
23267 (match_operand:MODEF 4 "register_operand"))]
23268 UNSPEC_BLENDV))]
23269 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23270 && (rtx_equal_p (operands[1], operands[4])
23271 && rtx_equal_p (operands[2], operands[3]))
23272 && ix86_pre_reload_split ()"
23273 "#"
23274 "&& 1"
23275 [(set (match_dup 0)
23276 (unspec:MODEF
23277 [(match_dup 2)
23278 (match_dup 1)]
23279 UNSPEC_IEEE_MIN))])
23280
23281 ;; Make two stack loads independent:
23282 ;; fld aa fld aa
23283 ;; fld %st(0) -> fld bb
23284 ;; fmul bb fmul %st(1), %st
23285 ;;
23286 ;; Actually we only match the last two instructions for simplicity.
23287
23288 (define_peephole2
23289 [(set (match_operand 0 "fp_register_operand")
23290 (match_operand 1 "fp_register_operand"))
23291 (set (match_dup 0)
23292 (match_operator 2 "binary_fp_operator"
23293 [(match_dup 0)
23294 (match_operand 3 "memory_operand")]))]
23295 "REGNO (operands[0]) != REGNO (operands[1])"
23296 [(set (match_dup 0) (match_dup 3))
23297 (set (match_dup 0)
23298 (match_op_dup 2
23299 [(match_dup 5) (match_dup 4)]))]
23300 {
23301 operands[4] = operands[0];
23302 operands[5] = operands[1];
23303
23304 /* The % modifier is not operational anymore in peephole2's, so we have to
23305 swap the operands manually in the case of addition and multiplication. */
23306 if (COMMUTATIVE_ARITH_P (operands[2]))
23307 std::swap (operands[4], operands[5]);
23308 })
23309
23310 (define_peephole2
23311 [(set (match_operand 0 "fp_register_operand")
23312 (match_operand 1 "fp_register_operand"))
23313 (set (match_dup 0)
23314 (match_operator 2 "binary_fp_operator"
23315 [(match_operand 3 "memory_operand")
23316 (match_dup 0)]))]
23317 "REGNO (operands[0]) != REGNO (operands[1])"
23318 [(set (match_dup 0) (match_dup 3))
23319 (set (match_dup 0)
23320 (match_op_dup 2
23321 [(match_dup 4) (match_dup 5)]))]
23322 {
23323 operands[4] = operands[0];
23324 operands[5] = operands[1];
23325
23326 /* The % modifier is not operational anymore in peephole2's, so we have to
23327 swap the operands manually in the case of addition and multiplication. */
23328 if (COMMUTATIVE_ARITH_P (operands[2]))
23329 std::swap (operands[4], operands[5]);
23330 })
23331
23332 ;; Conditional addition patterns
23333 (define_expand "add<mode>cc"
23334 [(match_operand:SWI 0 "register_operand")
23335 (match_operand 1 "ordered_comparison_operator")
23336 (match_operand:SWI 2 "register_operand")
23337 (match_operand:SWI 3 "const_int_operand")]
23338 ""
23339 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23340
23341 ;; min/max patterns
23342
23343 (define_code_attr maxmin_rel
23344 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23345
23346 (define_expand "<code><mode>3"
23347 [(parallel
23348 [(set (match_operand:SDWIM 0 "register_operand")
23349 (maxmin:SDWIM
23350 (match_operand:SDWIM 1 "register_operand")
23351 (match_operand:SDWIM 2 "general_operand")))
23352 (clobber (reg:CC FLAGS_REG))])]
23353 "TARGET_CMOVE
23354 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23355
23356 (define_insn_and_split "*<code><dwi>3_doubleword"
23357 [(set (match_operand:<DWI> 0 "register_operand")
23358 (maxmin:<DWI>
23359 (match_operand:<DWI> 1 "register_operand")
23360 (match_operand:<DWI> 2 "general_operand")))
23361 (clobber (reg:CC FLAGS_REG))]
23362 "TARGET_CMOVE
23363 && ix86_pre_reload_split ()"
23364 "#"
23365 "&& 1"
23366 [(set (match_dup 0)
23367 (if_then_else:DWIH (match_dup 6)
23368 (match_dup 1)
23369 (match_dup 2)))
23370 (set (match_dup 3)
23371 (if_then_else:DWIH (match_dup 6)
23372 (match_dup 4)
23373 (match_dup 5)))]
23374 {
23375 operands[2] = force_reg (<DWI>mode, operands[2]);
23376
23377 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23378
23379 rtx cmplo[2] = { operands[1], operands[2] };
23380 rtx cmphi[2] = { operands[4], operands[5] };
23381
23382 enum rtx_code code = <maxmin_rel>;
23383
23384 switch (code)
23385 {
23386 case LE: case LEU:
23387 std::swap (cmplo[0], cmplo[1]);
23388 std::swap (cmphi[0], cmphi[1]);
23389 code = swap_condition (code);
23390 /* FALLTHRU */
23391
23392 case GE: case GEU:
23393 {
23394 bool uns = (code == GEU);
23395 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23396 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23397
23398 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23399
23400 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23401 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23402
23403 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23404 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23405
23406 break;
23407 }
23408
23409 default:
23410 gcc_unreachable ();
23411 }
23412 })
23413
23414 (define_insn_and_split "*<code><mode>3_1"
23415 [(set (match_operand:SWI 0 "register_operand")
23416 (maxmin:SWI
23417 (match_operand:SWI 1 "register_operand")
23418 (match_operand:SWI 2 "general_operand")))
23419 (clobber (reg:CC FLAGS_REG))]
23420 "TARGET_CMOVE
23421 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23422 && ix86_pre_reload_split ()"
23423 "#"
23424 "&& 1"
23425 [(set (match_dup 0)
23426 (if_then_else:SWI (match_dup 3)
23427 (match_dup 1)
23428 (match_dup 2)))]
23429 {
23430 machine_mode mode = <MODE>mode;
23431 rtx cmp_op = operands[2];
23432
23433 operands[2] = force_reg (mode, cmp_op);
23434
23435 enum rtx_code code = <maxmin_rel>;
23436
23437 if (cmp_op == const1_rtx)
23438 {
23439 /* Convert smax (x, 1) into (x > 0 ? x : 1).
23440 Convert umax (x, 1) into (x != 0 ? x : 1).
23441 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
23442 cmp_op = const0_rtx;
23443 if (code == GE)
23444 code = GT;
23445 else if (code == GEU)
23446 code = NE;
23447 }
23448 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
23449 else if (cmp_op == constm1_rtx && code == LE)
23450 {
23451 cmp_op = const0_rtx;
23452 code = LT;
23453 }
23454 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
23455 else if (cmp_op == constm1_rtx && code == GE)
23456 cmp_op = const0_rtx;
23457 else if (cmp_op != const0_rtx)
23458 cmp_op = operands[2];
23459
23460 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
23461 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
23462
23463 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
23464 emit_insn (gen_rtx_SET (flags, tmp));
23465
23466 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23467 })
23468
23469 ;; Avoid clearing a register between a flags setting comparison and its use,
23470 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
23471 (define_peephole2
23472 [(set (reg FLAGS_REG) (match_operand 0))
23473 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
23474 "peep2_regno_dead_p (0, FLAGS_REG)
23475 && !reg_overlap_mentioned_p (operands[1], operands[0])"
23476 [(set (match_dup 2) (match_dup 0))]
23477 {
23478 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
23479 ix86_expand_clear (operands[1]);
23480 })
23481
23482 ;; When optimizing for size, zeroing memory should use a register.
23483 (define_peephole2
23484 [(match_scratch:SWI48 0 "r")
23485 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23486 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23487 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23488 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23489 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23490 [(const_int 0)]
23491 {
23492 ix86_expand_clear (operands[0]);
23493 emit_move_insn (operands[1], operands[0]);
23494 emit_move_insn (operands[2], operands[0]);
23495 emit_move_insn (operands[3], operands[0]);
23496 ix86_last_zero_store_uid
23497 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23498 DONE;
23499 })
23500
23501 (define_peephole2
23502 [(match_scratch:SWI48 0 "r")
23503 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23504 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23505 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23506 [(const_int 0)]
23507 {
23508 ix86_expand_clear (operands[0]);
23509 emit_move_insn (operands[1], operands[0]);
23510 ix86_last_zero_store_uid
23511 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23512 DONE;
23513 })
23514
23515 (define_peephole2
23516 [(match_scratch:SWI48 0 "r")
23517 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23518 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23519 [(const_int 0)]
23520 {
23521 ix86_expand_clear (operands[0]);
23522 ix86_last_zero_store_uid
23523 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23524 DONE;
23525 })
23526
23527 (define_peephole2
23528 [(set (match_operand:SWI48 5 "memory_operand")
23529 (match_operand:SWI48 0 "general_reg_operand"))
23530 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23531 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23532 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23533 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23534 "optimize_insn_for_size_p ()
23535 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23536 [(const_int 0)]
23537 {
23538 emit_move_insn (operands[5], operands[0]);
23539 emit_move_insn (operands[1], operands[0]);
23540 emit_move_insn (operands[2], operands[0]);
23541 emit_move_insn (operands[3], operands[0]);
23542 ix86_last_zero_store_uid
23543 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23544 DONE;
23545 })
23546
23547 (define_peephole2
23548 [(set (match_operand:SWI48 3 "memory_operand")
23549 (match_operand:SWI48 0 "general_reg_operand"))
23550 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23551 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23552 "optimize_insn_for_size_p ()
23553 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23554 [(const_int 0)]
23555 {
23556 emit_move_insn (operands[3], operands[0]);
23557 emit_move_insn (operands[1], operands[0]);
23558 ix86_last_zero_store_uid
23559 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23560 DONE;
23561 })
23562
23563 (define_peephole2
23564 [(set (match_operand:SWI48 2 "memory_operand")
23565 (match_operand:SWI48 0 "general_reg_operand"))
23566 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23567 "optimize_insn_for_size_p ()
23568 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23569 [(const_int 0)]
23570 {
23571 emit_move_insn (operands[2], operands[0]);
23572 ix86_last_zero_store_uid
23573 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23574 DONE;
23575 })
23576
23577 ;; Reload dislikes loading constants directly into class_likely_spilled
23578 ;; hard registers. Try to tidy things up here.
23579 (define_peephole2
23580 [(set (match_operand:SWI 0 "general_reg_operand")
23581 (match_operand:SWI 1 "x86_64_general_operand"))
23582 (set (match_operand:SWI 2 "general_reg_operand")
23583 (match_dup 0))]
23584 "peep2_reg_dead_p (2, operands[0])"
23585 [(set (match_dup 2) (match_dup 1))])
23586 \f
23587 ;; Misc patterns (?)
23588
23589 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
23590 ;; Otherwise there will be nothing to keep
23591 ;;
23592 ;; [(set (reg ebp) (reg esp))]
23593 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
23594 ;; (clobber (eflags)]
23595 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
23596 ;;
23597 ;; in proper program order.
23598
23599 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
23600 [(set (match_operand:P 0 "register_operand" "=r,r")
23601 (plus:P (match_operand:P 1 "register_operand" "0,r")
23602 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
23603 (clobber (reg:CC FLAGS_REG))
23604 (clobber (mem:BLK (scratch)))]
23605 ""
23606 {
23607 switch (get_attr_type (insn))
23608 {
23609 case TYPE_IMOV:
23610 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
23611
23612 case TYPE_ALU:
23613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
23614 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
23615 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
23616
23617 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
23618
23619 default:
23620 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
23621 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
23622 }
23623 }
23624 [(set (attr "type")
23625 (cond [(and (eq_attr "alternative" "0")
23626 (not (match_test "TARGET_OPT_AGU")))
23627 (const_string "alu")
23628 (match_operand:<MODE> 2 "const0_operand")
23629 (const_string "imov")
23630 ]
23631 (const_string "lea")))
23632 (set (attr "length_immediate")
23633 (cond [(eq_attr "type" "imov")
23634 (const_string "0")
23635 (and (eq_attr "type" "alu")
23636 (match_operand 2 "const128_operand"))
23637 (const_string "1")
23638 ]
23639 (const_string "*")))
23640 (set_attr "mode" "<MODE>")])
23641
23642 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
23643 [(set (match_operand:P 0 "register_operand" "=r")
23644 (minus:P (match_operand:P 1 "register_operand" "0")
23645 (match_operand:P 2 "register_operand" "r")))
23646 (clobber (reg:CC FLAGS_REG))
23647 (clobber (mem:BLK (scratch)))]
23648 ""
23649 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
23650 [(set_attr "type" "alu")
23651 (set_attr "mode" "<MODE>")])
23652
23653 (define_insn "@allocate_stack_worker_probe_<mode>"
23654 [(set (match_operand:P 0 "register_operand" "=a")
23655 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23656 UNSPECV_STACK_PROBE))
23657 (clobber (reg:CC FLAGS_REG))]
23658 "ix86_target_stack_probe ()"
23659 "call\t___chkstk_ms"
23660 [(set_attr "type" "multi")
23661 (set_attr "length" "5")])
23662
23663 (define_expand "allocate_stack"
23664 [(match_operand 0 "register_operand")
23665 (match_operand 1 "general_operand")]
23666 "ix86_target_stack_probe ()"
23667 {
23668 rtx x;
23669
23670 #ifndef CHECK_STACK_LIMIT
23671 #define CHECK_STACK_LIMIT 0
23672 #endif
23673
23674 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
23675 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
23676 x = operands[1];
23677 else
23678 {
23679 x = copy_to_mode_reg (Pmode, operands[1]);
23680
23681 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
23682 }
23683
23684 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
23685 stack_pointer_rtx, 0, OPTAB_DIRECT);
23686
23687 if (x != stack_pointer_rtx)
23688 emit_move_insn (stack_pointer_rtx, x);
23689
23690 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
23691 DONE;
23692 })
23693
23694 (define_expand "probe_stack"
23695 [(match_operand 0 "memory_operand")]
23696 ""
23697 {
23698 emit_insn (gen_probe_stack_1
23699 (word_mode, operands[0], const0_rtx));
23700 DONE;
23701 })
23702
23703 ;; Use OR for stack probes, this is shorter.
23704 (define_insn "@probe_stack_1_<mode>"
23705 [(set (match_operand:W 0 "memory_operand" "=m")
23706 (unspec:W [(match_operand:W 1 "const0_operand")]
23707 UNSPEC_PROBE_STACK))
23708 (clobber (reg:CC FLAGS_REG))]
23709 ""
23710 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
23711 [(set_attr "type" "alu1")
23712 (set_attr "mode" "<MODE>")
23713 (set_attr "length_immediate" "1")])
23714
23715 (define_insn "@adjust_stack_and_probe_<mode>"
23716 [(set (match_operand:P 0 "register_operand" "=r")
23717 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23718 UNSPECV_PROBE_STACK_RANGE))
23719 (set (reg:P SP_REG)
23720 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
23721 (clobber (reg:CC FLAGS_REG))
23722 (clobber (mem:BLK (scratch)))]
23723 ""
23724 "* return output_adjust_stack_and_probe (operands[0]);"
23725 [(set_attr "type" "multi")])
23726
23727 (define_insn "@probe_stack_range_<mode>"
23728 [(set (match_operand:P 0 "register_operand" "=r")
23729 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
23730 (match_operand:P 2 "const_int_operand")]
23731 UNSPECV_PROBE_STACK_RANGE))
23732 (clobber (reg:CC FLAGS_REG))]
23733 ""
23734 "* return output_probe_stack_range (operands[0], operands[2]);"
23735 [(set_attr "type" "multi")])
23736
23737 (define_expand "builtin_setjmp_receiver"
23738 [(label_ref (match_operand 0))]
23739 "!TARGET_64BIT && flag_pic"
23740 {
23741 #if TARGET_MACHO
23742 if (TARGET_MACHO)
23743 {
23744 rtx xops[3];
23745 rtx_code_label *label_rtx = gen_label_rtx ();
23746 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
23747 xops[0] = xops[1] = pic_offset_table_rtx;
23748 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
23749 ix86_expand_binary_operator (MINUS, SImode, xops);
23750 }
23751 else
23752 #endif
23753 emit_insn (gen_set_got (pic_offset_table_rtx));
23754 DONE;
23755 })
23756
23757 (define_expand "save_stack_nonlocal"
23758 [(set (match_operand 0 "memory_operand")
23759 (match_operand 1 "register_operand"))]
23760 ""
23761 {
23762 rtx stack_slot;
23763
23764 if (flag_cf_protection & CF_RETURN)
23765 {
23766 /* Copy shadow stack pointer to the first slot
23767 and stack pointer to the second slot. */
23768 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
23769 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
23770
23771 rtx reg_ssp = force_reg (word_mode, const0_rtx);
23772 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
23773 emit_move_insn (ssp_slot, reg_ssp);
23774 }
23775 else
23776 stack_slot = adjust_address (operands[0], Pmode, 0);
23777 emit_move_insn (stack_slot, operands[1]);
23778 DONE;
23779 })
23780
23781 (define_expand "restore_stack_nonlocal"
23782 [(set (match_operand 0 "register_operand" "")
23783 (match_operand 1 "memory_operand" ""))]
23784 ""
23785 {
23786 rtx stack_slot;
23787
23788 if (flag_cf_protection & CF_RETURN)
23789 {
23790 /* Restore shadow stack pointer from the first slot
23791 and stack pointer from the second slot. */
23792 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
23793 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
23794
23795 /* Get the current shadow stack pointer. The code below will check if
23796 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
23797 is a NOP. */
23798 rtx reg_ssp = force_reg (word_mode, const0_rtx);
23799 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
23800
23801 /* Compare through subtraction the saved and the current ssp
23802 to decide if ssp has to be adjusted. */
23803 reg_ssp = expand_simple_binop (word_mode, MINUS,
23804 reg_ssp, ssp_slot,
23805 reg_ssp, 1, OPTAB_DIRECT);
23806
23807 /* Compare and jump over adjustment code. */
23808 rtx noadj_label = gen_label_rtx ();
23809 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
23810 word_mode, 1, noadj_label);
23811
23812 /* Compute the number of frames to adjust. */
23813 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
23814 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
23815 NULL_RTX, 1);
23816
23817 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
23818 GEN_INT (exact_log2 (UNITS_PER_WORD)),
23819 reg_adj, 1, OPTAB_DIRECT);
23820
23821 /* Check if number of frames <= 255 so no loop is needed. */
23822 rtx inc_label = gen_label_rtx ();
23823 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
23824 ptr_mode, 1, inc_label);
23825
23826 /* Adjust the ssp in a loop. */
23827 rtx loop_label = gen_label_rtx ();
23828 emit_label (loop_label);
23829 LABEL_NUSES (loop_label) = 1;
23830
23831 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
23832 emit_insn (gen_incssp (word_mode, reg_255));
23833
23834 reg_adj = expand_simple_binop (ptr_mode, MINUS,
23835 reg_adj, GEN_INT (255),
23836 reg_adj, 1, OPTAB_DIRECT);
23837
23838 /* Compare and jump to the loop label. */
23839 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
23840 ptr_mode, 1, loop_label);
23841
23842 emit_label (inc_label);
23843 LABEL_NUSES (inc_label) = 1;
23844
23845 emit_insn (gen_incssp (word_mode, reg_ssp));
23846
23847 emit_label (noadj_label);
23848 LABEL_NUSES (noadj_label) = 1;
23849 }
23850 else
23851 stack_slot = adjust_address (operands[1], Pmode, 0);
23852 emit_move_insn (operands[0], stack_slot);
23853 DONE;
23854 })
23855
23856
23857 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
23858 ;; Do not split instructions with mask registers.
23859 (define_split
23860 [(set (match_operand 0 "general_reg_operand")
23861 (match_operator 3 "promotable_binary_operator"
23862 [(match_operand 1 "general_reg_operand")
23863 (match_operand 2 "aligned_operand")]))
23864 (clobber (reg:CC FLAGS_REG))]
23865 "! TARGET_PARTIAL_REG_STALL && reload_completed
23866 && ((GET_MODE (operands[0]) == HImode
23867 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
23868 /* ??? next two lines just !satisfies_constraint_K (...) */
23869 || !CONST_INT_P (operands[2])
23870 || satisfies_constraint_K (operands[2])))
23871 || (GET_MODE (operands[0]) == QImode
23872 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
23873 [(parallel [(set (match_dup 0)
23874 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
23875 (clobber (reg:CC FLAGS_REG))])]
23876 {
23877 operands[0] = gen_lowpart (SImode, operands[0]);
23878 operands[1] = gen_lowpart (SImode, operands[1]);
23879 if (GET_CODE (operands[3]) != ASHIFT)
23880 operands[2] = gen_lowpart (SImode, operands[2]);
23881 operands[3] = shallow_copy_rtx (operands[3]);
23882 PUT_MODE (operands[3], SImode);
23883 })
23884
23885 ; Promote the QImode tests, as i386 has encoding of the AND
23886 ; instruction with 32-bit sign-extended immediate and thus the
23887 ; instruction size is unchanged, except in the %eax case for
23888 ; which it is increased by one byte, hence the ! optimize_size.
23889 (define_split
23890 [(set (match_operand 0 "flags_reg_operand")
23891 (match_operator 2 "compare_operator"
23892 [(and (match_operand 3 "aligned_operand")
23893 (match_operand 4 "const_int_operand"))
23894 (const_int 0)]))
23895 (set (match_operand 1 "register_operand")
23896 (and (match_dup 3) (match_dup 4)))]
23897 "! TARGET_PARTIAL_REG_STALL && reload_completed
23898 && optimize_insn_for_speed_p ()
23899 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
23900 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
23901 /* Ensure that the operand will remain sign-extended immediate. */
23902 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
23903 [(parallel [(set (match_dup 0)
23904 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
23905 (const_int 0)]))
23906 (set (match_dup 1)
23907 (and:SI (match_dup 3) (match_dup 4)))])]
23908 {
23909 operands[4]
23910 = gen_int_mode (INTVAL (operands[4])
23911 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
23912 operands[1] = gen_lowpart (SImode, operands[1]);
23913 operands[3] = gen_lowpart (SImode, operands[3]);
23914 })
23915
23916 ; Don't promote the QImode tests, as i386 doesn't have encoding of
23917 ; the TEST instruction with 32-bit sign-extended immediate and thus
23918 ; the instruction size would at least double, which is not what we
23919 ; want even with ! optimize_size.
23920 (define_split
23921 [(set (match_operand 0 "flags_reg_operand")
23922 (match_operator 1 "compare_operator"
23923 [(and (match_operand:HI 2 "aligned_operand")
23924 (match_operand:HI 3 "const_int_operand"))
23925 (const_int 0)]))]
23926 "! TARGET_PARTIAL_REG_STALL && reload_completed
23927 && ! TARGET_FAST_PREFIX
23928 && optimize_insn_for_speed_p ()
23929 /* Ensure that the operand will remain sign-extended immediate. */
23930 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
23931 [(set (match_dup 0)
23932 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
23933 (const_int 0)]))]
23934 {
23935 operands[3]
23936 = gen_int_mode (INTVAL (operands[3])
23937 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
23938 operands[2] = gen_lowpart (SImode, operands[2]);
23939 })
23940
23941 (define_split
23942 [(set (match_operand 0 "register_operand")
23943 (neg (match_operand 1 "register_operand")))
23944 (clobber (reg:CC FLAGS_REG))]
23945 "! TARGET_PARTIAL_REG_STALL && reload_completed
23946 && (GET_MODE (operands[0]) == HImode
23947 || (GET_MODE (operands[0]) == QImode
23948 && (TARGET_PROMOTE_QImode
23949 || optimize_insn_for_size_p ())))"
23950 [(parallel [(set (match_dup 0)
23951 (neg:SI (match_dup 1)))
23952 (clobber (reg:CC FLAGS_REG))])]
23953 {
23954 operands[0] = gen_lowpart (SImode, operands[0]);
23955 operands[1] = gen_lowpart (SImode, operands[1]);
23956 })
23957
23958 ;; Do not split instructions with mask regs.
23959 (define_split
23960 [(set (match_operand 0 "general_reg_operand")
23961 (not (match_operand 1 "general_reg_operand")))]
23962 "! TARGET_PARTIAL_REG_STALL && reload_completed
23963 && (GET_MODE (operands[0]) == HImode
23964 || (GET_MODE (operands[0]) == QImode
23965 && (TARGET_PROMOTE_QImode
23966 || optimize_insn_for_size_p ())))"
23967 [(set (match_dup 0)
23968 (not:SI (match_dup 1)))]
23969 {
23970 operands[0] = gen_lowpart (SImode, operands[0]);
23971 operands[1] = gen_lowpart (SImode, operands[1]);
23972 })
23973 \f
23974 ;; RTL Peephole optimizations, run before sched2. These primarily look to
23975 ;; transform a complex memory operation into two memory to register operations.
23976
23977 ;; Don't push memory operands
23978 (define_peephole2
23979 [(set (match_operand:SWI 0 "push_operand")
23980 (match_operand:SWI 1 "memory_operand"))
23981 (match_scratch:SWI 2 "<r>")]
23982 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
23983 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
23984 [(set (match_dup 2) (match_dup 1))
23985 (set (match_dup 0) (match_dup 2))])
23986
23987 ;; We need to handle SFmode only, because DFmode and XFmode are split to
23988 ;; SImode pushes.
23989 (define_peephole2
23990 [(set (match_operand:SF 0 "push_operand")
23991 (match_operand:SF 1 "memory_operand"))
23992 (match_scratch:SF 2 "r")]
23993 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
23994 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
23995 [(set (match_dup 2) (match_dup 1))
23996 (set (match_dup 0) (match_dup 2))])
23997
23998 ;; Don't move an immediate directly to memory when the instruction
23999 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
24000 (define_peephole2
24001 [(match_scratch:SWI124 1 "<r>")
24002 (set (match_operand:SWI124 0 "memory_operand")
24003 (const_int 0))]
24004 "optimize_insn_for_speed_p ()
24005 && ((<MODE>mode == HImode
24006 && TARGET_LCP_STALL)
24007 || (!TARGET_USE_MOV0
24008 && TARGET_SPLIT_LONG_MOVES
24009 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
24010 && peep2_regno_dead_p (0, FLAGS_REG)"
24011 [(parallel [(set (match_dup 2) (const_int 0))
24012 (clobber (reg:CC FLAGS_REG))])
24013 (set (match_dup 0) (match_dup 1))]
24014 "operands[2] = gen_lowpart (SImode, operands[1]);")
24015
24016 (define_peephole2
24017 [(match_scratch:SWI124 2 "<r>")
24018 (set (match_operand:SWI124 0 "memory_operand")
24019 (match_operand:SWI124 1 "immediate_operand"))]
24020 "optimize_insn_for_speed_p ()
24021 && ((<MODE>mode == HImode
24022 && TARGET_LCP_STALL)
24023 || (TARGET_SPLIT_LONG_MOVES
24024 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
24025 [(set (match_dup 2) (match_dup 1))
24026 (set (match_dup 0) (match_dup 2))])
24027
24028 ;; Don't compare memory with zero, load and use a test instead.
24029 (define_peephole2
24030 [(set (match_operand 0 "flags_reg_operand")
24031 (match_operator 1 "compare_operator"
24032 [(match_operand:SI 2 "memory_operand")
24033 (const_int 0)]))
24034 (match_scratch:SI 3 "r")]
24035 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
24036 [(set (match_dup 3) (match_dup 2))
24037 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
24038
24039 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
24040 ;; Don't split NOTs with a displacement operand, because resulting XOR
24041 ;; will not be pairable anyway.
24042 ;;
24043 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
24044 ;; represented using a modRM byte. The XOR replacement is long decoded,
24045 ;; so this split helps here as well.
24046 ;;
24047 ;; Note: Can't do this as a regular split because we can't get proper
24048 ;; lifetime information then.
24049
24050 (define_peephole2
24051 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
24052 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
24053 "optimize_insn_for_speed_p ()
24054 && ((TARGET_NOT_UNPAIRABLE
24055 && (!MEM_P (operands[0])
24056 || !memory_displacement_operand (operands[0], <MODE>mode)))
24057 || (TARGET_NOT_VECTORMODE
24058 && long_memory_operand (operands[0], <MODE>mode)))
24059 && peep2_regno_dead_p (0, FLAGS_REG)"
24060 [(parallel [(set (match_dup 0)
24061 (xor:SWI124 (match_dup 1) (const_int -1)))
24062 (clobber (reg:CC FLAGS_REG))])])
24063
24064 ;; Non pairable "test imm, reg" instructions can be translated to
24065 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
24066 ;; byte opcode instead of two, have a short form for byte operands),
24067 ;; so do it for other CPUs as well. Given that the value was dead,
24068 ;; this should not create any new dependencies. Pass on the sub-word
24069 ;; versions if we're concerned about partial register stalls.
24070
24071 (define_peephole2
24072 [(set (match_operand 0 "flags_reg_operand")
24073 (match_operator 1 "compare_operator"
24074 [(and:SI (match_operand:SI 2 "register_operand")
24075 (match_operand:SI 3 "immediate_operand"))
24076 (const_int 0)]))]
24077 "ix86_match_ccmode (insn, CCNOmode)
24078 && (REGNO (operands[2]) != AX_REG
24079 || satisfies_constraint_K (operands[3]))
24080 && peep2_reg_dead_p (1, operands[2])"
24081 [(parallel
24082 [(set (match_dup 0)
24083 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24084 (const_int 0)]))
24085 (set (match_dup 2)
24086 (and:SI (match_dup 2) (match_dup 3)))])])
24087
24088 ;; We don't need to handle HImode case, because it will be promoted to SImode
24089 ;; on ! TARGET_PARTIAL_REG_STALL
24090
24091 (define_peephole2
24092 [(set (match_operand 0 "flags_reg_operand")
24093 (match_operator 1 "compare_operator"
24094 [(and:QI (match_operand:QI 2 "register_operand")
24095 (match_operand:QI 3 "immediate_operand"))
24096 (const_int 0)]))]
24097 "! TARGET_PARTIAL_REG_STALL
24098 && ix86_match_ccmode (insn, CCNOmode)
24099 && REGNO (operands[2]) != AX_REG
24100 && peep2_reg_dead_p (1, operands[2])"
24101 [(parallel
24102 [(set (match_dup 0)
24103 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24104 (const_int 0)]))
24105 (set (match_dup 2)
24106 (and:QI (match_dup 2) (match_dup 3)))])])
24107
24108 (define_peephole2
24109 [(set (match_operand 0 "flags_reg_operand")
24110 (match_operator 1 "compare_operator"
24111 [(and:QI
24112 (subreg:QI
24113 (match_operator:SWI248 4 "extract_operator"
24114 [(match_operand 2 "int248_register_operand")
24115 (const_int 8)
24116 (const_int 8)]) 0)
24117 (match_operand 3 "const_int_operand"))
24118 (const_int 0)]))]
24119 "! TARGET_PARTIAL_REG_STALL
24120 && ix86_match_ccmode (insn, CCNOmode)
24121 && REGNO (operands[2]) != AX_REG
24122 && peep2_reg_dead_p (1, operands[2])"
24123 [(parallel
24124 [(set (match_dup 0)
24125 (match_op_dup 1
24126 [(and:QI
24127 (subreg:QI
24128 (match_op_dup 4 [(match_dup 2)
24129 (const_int 8)
24130 (const_int 8)]) 0)
24131 (match_dup 3))
24132 (const_int 0)]))
24133 (set (zero_extract:SWI248 (match_dup 2)
24134 (const_int 8)
24135 (const_int 8))
24136 (subreg:SWI248
24137 (and:QI
24138 (subreg:QI
24139 (match_op_dup 4 [(match_dup 2)
24140 (const_int 8)
24141 (const_int 8)]) 0)
24142 (match_dup 3)) 0))])])
24143
24144 ;; Don't do logical operations with memory inputs.
24145 (define_peephole2
24146 [(match_scratch:SWI 2 "<r>")
24147 (parallel [(set (match_operand:SWI 0 "register_operand")
24148 (match_operator:SWI 3 "arith_or_logical_operator"
24149 [(match_dup 0)
24150 (match_operand:SWI 1 "memory_operand")]))
24151 (clobber (reg:CC FLAGS_REG))])]
24152 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24153 [(set (match_dup 2) (match_dup 1))
24154 (parallel [(set (match_dup 0)
24155 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24156 (clobber (reg:CC FLAGS_REG))])])
24157
24158 (define_peephole2
24159 [(match_scratch:SWI 2 "<r>")
24160 (parallel [(set (match_operand:SWI 0 "register_operand")
24161 (match_operator:SWI 3 "arith_or_logical_operator"
24162 [(match_operand:SWI 1 "memory_operand")
24163 (match_dup 0)]))
24164 (clobber (reg:CC FLAGS_REG))])]
24165 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24166 [(set (match_dup 2) (match_dup 1))
24167 (parallel [(set (match_dup 0)
24168 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24169 (clobber (reg:CC FLAGS_REG))])])
24170
24171 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
24172 ;; the memory address refers to the destination of the load!
24173
24174 (define_peephole2
24175 [(set (match_operand:SWI 0 "general_reg_operand")
24176 (match_operand:SWI 1 "general_reg_operand"))
24177 (parallel [(set (match_dup 0)
24178 (match_operator:SWI 3 "commutative_operator"
24179 [(match_dup 0)
24180 (match_operand:SWI 2 "memory_operand")]))
24181 (clobber (reg:CC FLAGS_REG))])]
24182 "REGNO (operands[0]) != REGNO (operands[1])
24183 && (<MODE>mode != QImode
24184 || any_QIreg_operand (operands[1], QImode))"
24185 [(set (match_dup 0) (match_dup 4))
24186 (parallel [(set (match_dup 0)
24187 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24188 (clobber (reg:CC FLAGS_REG))])]
24189 {
24190 operands[4]
24191 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24192 })
24193
24194 (define_peephole2
24195 [(set (match_operand 0 "mmx_reg_operand")
24196 (match_operand 1 "mmx_reg_operand"))
24197 (set (match_dup 0)
24198 (match_operator 3 "commutative_operator"
24199 [(match_dup 0)
24200 (match_operand 2 "memory_operand")]))]
24201 "REGNO (operands[0]) != REGNO (operands[1])"
24202 [(set (match_dup 0) (match_dup 2))
24203 (set (match_dup 0)
24204 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24205
24206 (define_peephole2
24207 [(set (match_operand 0 "sse_reg_operand")
24208 (match_operand 1 "sse_reg_operand"))
24209 (set (match_dup 0)
24210 (match_operator 3 "commutative_operator"
24211 [(match_dup 0)
24212 (match_operand 2 "memory_operand")]))]
24213 "REGNO (operands[0]) != REGNO (operands[1])
24214 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
24215 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
24216 instructions require AVX512BW and AVX512VL, but with the original
24217 instructions it might require just AVX512VL.
24218 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
24219 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
24220 || TARGET_AVX512BW
24221 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
24222 || logic_operator (operands[3], VOIDmode))"
24223 [(set (match_dup 0) (match_dup 2))
24224 (set (match_dup 0)
24225 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24226
24227 ; Don't do logical operations with memory outputs
24228 ;
24229 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
24230 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
24231 ; the same decoder scheduling characteristics as the original.
24232
24233 (define_peephole2
24234 [(match_scratch:SWI 2 "<r>")
24235 (parallel [(set (match_operand:SWI 0 "memory_operand")
24236 (match_operator:SWI 3 "arith_or_logical_operator"
24237 [(match_dup 0)
24238 (match_operand:SWI 1 "<nonmemory_operand>")]))
24239 (clobber (reg:CC FLAGS_REG))])]
24240 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24241 [(set (match_dup 2) (match_dup 0))
24242 (parallel [(set (match_dup 2)
24243 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
24244 (clobber (reg:CC FLAGS_REG))])
24245 (set (match_dup 0) (match_dup 2))])
24246
24247 (define_peephole2
24248 [(match_scratch:SWI 2 "<r>")
24249 (parallel [(set (match_operand:SWI 0 "memory_operand")
24250 (match_operator:SWI 3 "arith_or_logical_operator"
24251 [(match_operand:SWI 1 "<nonmemory_operand>")
24252 (match_dup 0)]))
24253 (clobber (reg:CC FLAGS_REG))])]
24254 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24255 [(set (match_dup 2) (match_dup 0))
24256 (parallel [(set (match_dup 2)
24257 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24258 (clobber (reg:CC FLAGS_REG))])
24259 (set (match_dup 0) (match_dup 2))])
24260
24261 ;; Attempt to use arith or logical operations with memory outputs with
24262 ;; setting of flags.
24263 (define_peephole2
24264 [(set (match_operand:SWI 0 "register_operand")
24265 (match_operand:SWI 1 "memory_operand"))
24266 (parallel [(set (match_dup 0)
24267 (match_operator:SWI 3 "plusminuslogic_operator"
24268 [(match_dup 0)
24269 (match_operand:SWI 2 "<nonmemory_operand>")]))
24270 (clobber (reg:CC FLAGS_REG))])
24271 (set (match_dup 1) (match_dup 0))
24272 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24273 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24274 && peep2_reg_dead_p (4, operands[0])
24275 && !reg_overlap_mentioned_p (operands[0], operands[1])
24276 && !reg_overlap_mentioned_p (operands[0], operands[2])
24277 && (<MODE>mode != QImode
24278 || immediate_operand (operands[2], QImode)
24279 || any_QIreg_operand (operands[2], QImode))
24280 && ix86_match_ccmode (peep2_next_insn (3),
24281 (GET_CODE (operands[3]) == PLUS
24282 || GET_CODE (operands[3]) == MINUS)
24283 ? CCGOCmode : CCNOmode)"
24284 [(parallel [(set (match_dup 4) (match_dup 6))
24285 (set (match_dup 1) (match_dup 5))])]
24286 {
24287 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
24288 operands[5]
24289 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24290 copy_rtx (operands[1]),
24291 operands[2]);
24292 operands[6]
24293 = gen_rtx_COMPARE (GET_MODE (operands[4]),
24294 copy_rtx (operands[5]),
24295 const0_rtx);
24296 })
24297
24298 ;; Likewise for cmpelim optimized pattern.
24299 (define_peephole2
24300 [(set (match_operand:SWI 0 "register_operand")
24301 (match_operand:SWI 1 "memory_operand"))
24302 (parallel [(set (reg FLAGS_REG)
24303 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24304 [(match_dup 0)
24305 (match_operand:SWI 2 "<nonmemory_operand>")])
24306 (const_int 0)))
24307 (set (match_dup 0) (match_dup 3))])
24308 (set (match_dup 1) (match_dup 0))]
24309 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24310 && peep2_reg_dead_p (3, operands[0])
24311 && !reg_overlap_mentioned_p (operands[0], operands[1])
24312 && !reg_overlap_mentioned_p (operands[0], operands[2])
24313 && ix86_match_ccmode (peep2_next_insn (1),
24314 (GET_CODE (operands[3]) == PLUS
24315 || GET_CODE (operands[3]) == MINUS)
24316 ? CCGOCmode : CCNOmode)"
24317 [(parallel [(set (match_dup 4) (match_dup 6))
24318 (set (match_dup 1) (match_dup 5))])]
24319 {
24320 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24321 operands[5]
24322 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24323 copy_rtx (operands[1]), operands[2]);
24324 operands[6]
24325 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
24326 const0_rtx);
24327 })
24328
24329 ;; Likewise for instances where we have a lea pattern.
24330 (define_peephole2
24331 [(set (match_operand:SWI 0 "register_operand")
24332 (match_operand:SWI 1 "memory_operand"))
24333 (set (match_operand:<LEAMODE> 3 "register_operand")
24334 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
24335 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
24336 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
24337 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24338 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24339 && REGNO (operands[4]) == REGNO (operands[0])
24340 && REGNO (operands[5]) == REGNO (operands[3])
24341 && peep2_reg_dead_p (4, operands[3])
24342 && ((REGNO (operands[0]) == REGNO (operands[3]))
24343 || peep2_reg_dead_p (2, operands[0]))
24344 && !reg_overlap_mentioned_p (operands[0], operands[1])
24345 && !reg_overlap_mentioned_p (operands[3], operands[1])
24346 && !reg_overlap_mentioned_p (operands[0], operands[2])
24347 && (<MODE>mode != QImode
24348 || immediate_operand (operands[2], QImode)
24349 || any_QIreg_operand (operands[2], QImode))
24350 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
24351 [(parallel [(set (match_dup 6) (match_dup 8))
24352 (set (match_dup 1) (match_dup 7))])]
24353 {
24354 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
24355 operands[7]
24356 = gen_rtx_PLUS (<MODE>mode,
24357 copy_rtx (operands[1]),
24358 gen_lowpart (<MODE>mode, operands[2]));
24359 operands[8]
24360 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24361 copy_rtx (operands[7]),
24362 const0_rtx);
24363 })
24364
24365 (define_peephole2
24366 [(parallel [(set (match_operand:SWI 0 "register_operand")
24367 (match_operator:SWI 2 "plusminuslogic_operator"
24368 [(match_dup 0)
24369 (match_operand:SWI 1 "memory_operand")]))
24370 (clobber (reg:CC FLAGS_REG))])
24371 (set (match_dup 1) (match_dup 0))
24372 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24373 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24374 && COMMUTATIVE_ARITH_P (operands[2])
24375 && peep2_reg_dead_p (3, operands[0])
24376 && !reg_overlap_mentioned_p (operands[0], operands[1])
24377 && ix86_match_ccmode (peep2_next_insn (2),
24378 GET_CODE (operands[2]) == PLUS
24379 ? CCGOCmode : CCNOmode)"
24380 [(parallel [(set (match_dup 3) (match_dup 5))
24381 (set (match_dup 1) (match_dup 4))])]
24382 {
24383 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
24384 operands[4]
24385 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24386 copy_rtx (operands[1]),
24387 operands[0]);
24388 operands[5]
24389 = gen_rtx_COMPARE (GET_MODE (operands[3]),
24390 copy_rtx (operands[4]),
24391 const0_rtx);
24392 })
24393
24394 ;; Likewise for cmpelim optimized pattern.
24395 (define_peephole2
24396 [(parallel [(set (reg FLAGS_REG)
24397 (compare (match_operator:SWI 2 "plusminuslogic_operator"
24398 [(match_operand:SWI 0 "register_operand")
24399 (match_operand:SWI 1 "memory_operand")])
24400 (const_int 0)))
24401 (set (match_dup 0) (match_dup 2))])
24402 (set (match_dup 1) (match_dup 0))]
24403 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24404 && COMMUTATIVE_ARITH_P (operands[2])
24405 && peep2_reg_dead_p (2, operands[0])
24406 && !reg_overlap_mentioned_p (operands[0], operands[1])
24407 && ix86_match_ccmode (peep2_next_insn (0),
24408 GET_CODE (operands[2]) == PLUS
24409 ? CCGOCmode : CCNOmode)"
24410 [(parallel [(set (match_dup 3) (match_dup 5))
24411 (set (match_dup 1) (match_dup 4))])]
24412 {
24413 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
24414 operands[4]
24415 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24416 copy_rtx (operands[1]), operands[0]);
24417 operands[5]
24418 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
24419 const0_rtx);
24420 })
24421
24422 (define_peephole2
24423 [(set (match_operand:SWI12 0 "register_operand")
24424 (match_operand:SWI12 1 "memory_operand"))
24425 (parallel [(set (match_operand:SI 4 "register_operand")
24426 (match_operator:SI 3 "plusminuslogic_operator"
24427 [(match_dup 4)
24428 (match_operand:SI 2 "nonmemory_operand")]))
24429 (clobber (reg:CC FLAGS_REG))])
24430 (set (match_dup 1) (match_dup 0))
24431 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24432 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24433 && REGNO (operands[0]) == REGNO (operands[4])
24434 && peep2_reg_dead_p (4, operands[0])
24435 && (<MODE>mode != QImode
24436 || immediate_operand (operands[2], SImode)
24437 || any_QIreg_operand (operands[2], SImode))
24438 && !reg_overlap_mentioned_p (operands[0], operands[1])
24439 && !reg_overlap_mentioned_p (operands[0], operands[2])
24440 && ix86_match_ccmode (peep2_next_insn (3),
24441 (GET_CODE (operands[3]) == PLUS
24442 || GET_CODE (operands[3]) == MINUS)
24443 ? CCGOCmode : CCNOmode)"
24444 [(parallel [(set (match_dup 5) (match_dup 7))
24445 (set (match_dup 1) (match_dup 6))])]
24446 {
24447 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
24448 operands[6]
24449 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24450 copy_rtx (operands[1]),
24451 gen_lowpart (<MODE>mode, operands[2]));
24452 operands[7]
24453 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24454 copy_rtx (operands[6]),
24455 const0_rtx);
24456 })
24457
24458 ;; peephole2 comes before regcprop, so deal also with a case that
24459 ;; would be cleaned up by regcprop.
24460 (define_peephole2
24461 [(set (match_operand:SWI 0 "register_operand")
24462 (match_operand:SWI 1 "memory_operand"))
24463 (parallel [(set (match_dup 0)
24464 (match_operator:SWI 3 "plusminuslogic_operator"
24465 [(match_dup 0)
24466 (match_operand:SWI 2 "<nonmemory_operand>")]))
24467 (clobber (reg:CC FLAGS_REG))])
24468 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24469 (set (match_dup 1) (match_dup 4))
24470 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
24471 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24472 && peep2_reg_dead_p (3, operands[0])
24473 && peep2_reg_dead_p (5, operands[4])
24474 && !reg_overlap_mentioned_p (operands[0], operands[1])
24475 && !reg_overlap_mentioned_p (operands[0], operands[2])
24476 && !reg_overlap_mentioned_p (operands[4], operands[1])
24477 && (<MODE>mode != QImode
24478 || immediate_operand (operands[2], QImode)
24479 || any_QIreg_operand (operands[2], QImode))
24480 && ix86_match_ccmode (peep2_next_insn (4),
24481 (GET_CODE (operands[3]) == PLUS
24482 || GET_CODE (operands[3]) == MINUS)
24483 ? CCGOCmode : CCNOmode)"
24484 [(parallel [(set (match_dup 5) (match_dup 7))
24485 (set (match_dup 1) (match_dup 6))])]
24486 {
24487 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
24488 operands[6]
24489 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24490 copy_rtx (operands[1]),
24491 operands[2]);
24492 operands[7]
24493 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24494 copy_rtx (operands[6]),
24495 const0_rtx);
24496 })
24497
24498 (define_peephole2
24499 [(set (match_operand:SWI12 0 "register_operand")
24500 (match_operand:SWI12 1 "memory_operand"))
24501 (parallel [(set (match_operand:SI 4 "register_operand")
24502 (match_operator:SI 3 "plusminuslogic_operator"
24503 [(match_dup 4)
24504 (match_operand:SI 2 "nonmemory_operand")]))
24505 (clobber (reg:CC FLAGS_REG))])
24506 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
24507 (set (match_dup 1) (match_dup 5))
24508 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24509 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24510 && REGNO (operands[0]) == REGNO (operands[4])
24511 && peep2_reg_dead_p (3, operands[0])
24512 && peep2_reg_dead_p (5, operands[5])
24513 && (<MODE>mode != QImode
24514 || immediate_operand (operands[2], SImode)
24515 || any_QIreg_operand (operands[2], SImode))
24516 && !reg_overlap_mentioned_p (operands[0], operands[1])
24517 && !reg_overlap_mentioned_p (operands[0], operands[2])
24518 && !reg_overlap_mentioned_p (operands[5], operands[1])
24519 && ix86_match_ccmode (peep2_next_insn (4),
24520 (GET_CODE (operands[3]) == PLUS
24521 || GET_CODE (operands[3]) == MINUS)
24522 ? CCGOCmode : CCNOmode)"
24523 [(parallel [(set (match_dup 6) (match_dup 8))
24524 (set (match_dup 1) (match_dup 7))])]
24525 {
24526 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
24527 operands[7]
24528 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24529 copy_rtx (operands[1]),
24530 gen_lowpart (<MODE>mode, operands[2]));
24531 operands[8]
24532 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24533 copy_rtx (operands[7]),
24534 const0_rtx);
24535 })
24536
24537 ;; Likewise for cmpelim optimized pattern.
24538 (define_peephole2
24539 [(set (match_operand:SWI 0 "register_operand")
24540 (match_operand:SWI 1 "memory_operand"))
24541 (parallel [(set (reg FLAGS_REG)
24542 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24543 [(match_dup 0)
24544 (match_operand:SWI 2 "<nonmemory_operand>")])
24545 (const_int 0)))
24546 (set (match_dup 0) (match_dup 3))])
24547 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24548 (set (match_dup 1) (match_dup 4))]
24549 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24550 && peep2_reg_dead_p (3, operands[0])
24551 && peep2_reg_dead_p (4, operands[4])
24552 && !reg_overlap_mentioned_p (operands[0], operands[1])
24553 && !reg_overlap_mentioned_p (operands[0], operands[2])
24554 && !reg_overlap_mentioned_p (operands[4], operands[1])
24555 && ix86_match_ccmode (peep2_next_insn (1),
24556 (GET_CODE (operands[3]) == PLUS
24557 || GET_CODE (operands[3]) == MINUS)
24558 ? CCGOCmode : CCNOmode)"
24559 [(parallel [(set (match_dup 5) (match_dup 7))
24560 (set (match_dup 1) (match_dup 6))])]
24561 {
24562 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24563 operands[6]
24564 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24565 copy_rtx (operands[1]), operands[2]);
24566 operands[7]
24567 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
24568 const0_rtx);
24569 })
24570
24571 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
24572 ;; into x = z; x ^= y; x != z
24573 (define_peephole2
24574 [(set (match_operand:SWI 0 "register_operand")
24575 (match_operand:SWI 1 "memory_operand"))
24576 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
24577 (parallel [(set (match_operand:SWI 4 "register_operand")
24578 (xor:SWI (match_dup 4)
24579 (match_operand:SWI 2 "<nonmemory_operand>")))
24580 (clobber (reg:CC FLAGS_REG))])
24581 (set (match_dup 1) (match_dup 4))
24582 (set (reg:CCZ FLAGS_REG)
24583 (compare:CCZ (match_operand:SWI 5 "register_operand")
24584 (match_operand:SWI 6 "<nonmemory_operand>")))]
24585 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24586 && (REGNO (operands[4]) == REGNO (operands[0])
24587 || REGNO (operands[4]) == REGNO (operands[3]))
24588 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
24589 ? 3 : 0], operands[5])
24590 ? rtx_equal_p (operands[2], operands[6])
24591 : rtx_equal_p (operands[2], operands[5])
24592 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
24593 ? 3 : 0], operands[6]))
24594 && peep2_reg_dead_p (4, operands[4])
24595 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
24596 ? 3 : 0])
24597 && !reg_overlap_mentioned_p (operands[0], operands[1])
24598 && !reg_overlap_mentioned_p (operands[0], operands[2])
24599 && !reg_overlap_mentioned_p (operands[3], operands[0])
24600 && !reg_overlap_mentioned_p (operands[3], operands[1])
24601 && !reg_overlap_mentioned_p (operands[3], operands[2])
24602 && (<MODE>mode != QImode
24603 || immediate_operand (operands[2], QImode)
24604 || any_QIreg_operand (operands[2], QImode))"
24605 [(parallel [(set (match_dup 7) (match_dup 9))
24606 (set (match_dup 1) (match_dup 8))])]
24607 {
24608 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
24609 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
24610 operands[2]);
24611 operands[9]
24612 = gen_rtx_COMPARE (GET_MODE (operands[7]),
24613 copy_rtx (operands[8]),
24614 const0_rtx);
24615 })
24616
24617 (define_peephole2
24618 [(set (match_operand:SWI12 0 "register_operand")
24619 (match_operand:SWI12 1 "memory_operand"))
24620 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
24621 (parallel [(set (match_operand:SI 4 "register_operand")
24622 (xor:SI (match_dup 4)
24623 (match_operand:SI 2 "<nonmemory_operand>")))
24624 (clobber (reg:CC FLAGS_REG))])
24625 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
24626 (set (reg:CCZ FLAGS_REG)
24627 (compare:CCZ (match_operand:SWI12 6 "register_operand")
24628 (match_operand:SWI12 7 "<nonmemory_operand>")))]
24629 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24630 && (REGNO (operands[5]) == REGNO (operands[0])
24631 || REGNO (operands[5]) == REGNO (operands[3]))
24632 && REGNO (operands[5]) == REGNO (operands[4])
24633 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
24634 ? 3 : 0], operands[6])
24635 ? (REG_P (operands[2])
24636 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
24637 : rtx_equal_p (operands[2], operands[7]))
24638 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
24639 ? 3 : 0], operands[7])
24640 && REG_P (operands[2])
24641 && REGNO (operands[2]) == REGNO (operands[6])))
24642 && peep2_reg_dead_p (4, operands[5])
24643 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
24644 ? 3 : 0])
24645 && !reg_overlap_mentioned_p (operands[0], operands[1])
24646 && !reg_overlap_mentioned_p (operands[0], operands[2])
24647 && !reg_overlap_mentioned_p (operands[3], operands[0])
24648 && !reg_overlap_mentioned_p (operands[3], operands[1])
24649 && !reg_overlap_mentioned_p (operands[3], operands[2])
24650 && (<MODE>mode != QImode
24651 || immediate_operand (operands[2], SImode)
24652 || any_QIreg_operand (operands[2], SImode))"
24653 [(parallel [(set (match_dup 8) (match_dup 10))
24654 (set (match_dup 1) (match_dup 9))])]
24655 {
24656 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
24657 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
24658 gen_lowpart (<MODE>mode, operands[2]));
24659 operands[10]
24660 = gen_rtx_COMPARE (GET_MODE (operands[8]),
24661 copy_rtx (operands[9]),
24662 const0_rtx);
24663 })
24664
24665 ;; Attempt to optimize away memory stores of values the memory already
24666 ;; has. See PR79593.
24667 (define_peephole2
24668 [(set (match_operand 0 "register_operand")
24669 (match_operand 1 "memory_operand"))
24670 (set (match_operand 2 "memory_operand") (match_dup 0))]
24671 "!MEM_VOLATILE_P (operands[1])
24672 && !MEM_VOLATILE_P (operands[2])
24673 && rtx_equal_p (operands[1], operands[2])
24674 && !reg_overlap_mentioned_p (operands[0], operands[2])"
24675 [(set (match_dup 0) (match_dup 1))])
24676
24677 ;; Attempt to always use XOR for zeroing registers (including FP modes).
24678 (define_peephole2
24679 [(set (match_operand 0 "general_reg_operand")
24680 (match_operand 1 "const0_operand"))]
24681 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
24682 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24683 && peep2_regno_dead_p (0, FLAGS_REG)"
24684 [(parallel [(set (match_dup 0) (const_int 0))
24685 (clobber (reg:CC FLAGS_REG))])]
24686 "operands[0] = gen_lowpart (word_mode, operands[0]);")
24687
24688 (define_peephole2
24689 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
24690 (const_int 0))]
24691 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24692 && peep2_regno_dead_p (0, FLAGS_REG)"
24693 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
24694 (clobber (reg:CC FLAGS_REG))])])
24695
24696 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
24697 (define_peephole2
24698 [(set (match_operand:SWI248 0 "general_reg_operand")
24699 (const_int -1))]
24700 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
24701 && peep2_regno_dead_p (0, FLAGS_REG)"
24702 [(parallel [(set (match_dup 0) (const_int -1))
24703 (clobber (reg:CC FLAGS_REG))])]
24704 {
24705 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
24706 operands[0] = gen_lowpart (SImode, operands[0]);
24707 })
24708
24709 ;; Attempt to convert simple lea to add/shift.
24710 ;; These can be created by move expanders.
24711 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
24712 ;; relevant lea instructions were already split.
24713
24714 (define_peephole2
24715 [(set (match_operand:SWI48 0 "register_operand")
24716 (plus:SWI48 (match_dup 0)
24717 (match_operand:SWI48 1 "<nonmemory_operand>")))]
24718 "!TARGET_OPT_AGU
24719 && peep2_regno_dead_p (0, FLAGS_REG)"
24720 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
24721 (clobber (reg:CC FLAGS_REG))])])
24722
24723 (define_peephole2
24724 [(set (match_operand:SWI48 0 "register_operand")
24725 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
24726 (match_dup 0)))]
24727 "!TARGET_OPT_AGU
24728 && peep2_regno_dead_p (0, FLAGS_REG)"
24729 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
24730 (clobber (reg:CC FLAGS_REG))])])
24731
24732 (define_peephole2
24733 [(set (match_operand:DI 0 "register_operand")
24734 (zero_extend:DI
24735 (plus:SI (match_operand:SI 1 "register_operand")
24736 (match_operand:SI 2 "nonmemory_operand"))))]
24737 "TARGET_64BIT && !TARGET_OPT_AGU
24738 && REGNO (operands[0]) == REGNO (operands[1])
24739 && peep2_regno_dead_p (0, FLAGS_REG)"
24740 [(parallel [(set (match_dup 0)
24741 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
24742 (clobber (reg:CC FLAGS_REG))])])
24743
24744 (define_peephole2
24745 [(set (match_operand:DI 0 "register_operand")
24746 (zero_extend:DI
24747 (plus:SI (match_operand:SI 1 "nonmemory_operand")
24748 (match_operand:SI 2 "register_operand"))))]
24749 "TARGET_64BIT && !TARGET_OPT_AGU
24750 && REGNO (operands[0]) == REGNO (operands[2])
24751 && peep2_regno_dead_p (0, FLAGS_REG)"
24752 [(parallel [(set (match_dup 0)
24753 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
24754 (clobber (reg:CC FLAGS_REG))])])
24755
24756 (define_peephole2
24757 [(set (match_operand:SWI48 0 "register_operand")
24758 (mult:SWI48 (match_dup 0)
24759 (match_operand:SWI48 1 "const_int_operand")))]
24760 "pow2p_hwi (INTVAL (operands[1]))
24761 && peep2_regno_dead_p (0, FLAGS_REG)"
24762 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
24763 (clobber (reg:CC FLAGS_REG))])]
24764 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
24765
24766 (define_peephole2
24767 [(set (match_operand:DI 0 "register_operand")
24768 (zero_extend:DI
24769 (mult:SI (match_operand:SI 1 "register_operand")
24770 (match_operand:SI 2 "const_int_operand"))))]
24771 "TARGET_64BIT
24772 && pow2p_hwi (INTVAL (operands[2]))
24773 && REGNO (operands[0]) == REGNO (operands[1])
24774 && peep2_regno_dead_p (0, FLAGS_REG)"
24775 [(parallel [(set (match_dup 0)
24776 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
24777 (clobber (reg:CC FLAGS_REG))])]
24778 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
24779
24780 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
24781 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
24782 ;; On many CPUs it is also faster, since special hardware to avoid esp
24783 ;; dependencies is present.
24784
24785 ;; While some of these conversions may be done using splitters, we use
24786 ;; peepholes in order to allow combine_stack_adjustments pass to see
24787 ;; nonobfuscated RTL.
24788
24789 ;; Convert prologue esp subtractions to push.
24790 ;; We need register to push. In order to keep verify_flow_info happy we have
24791 ;; two choices
24792 ;; - use scratch and clobber it in order to avoid dependencies
24793 ;; - use already live register
24794 ;; We can't use the second way right now, since there is no reliable way how to
24795 ;; verify that given register is live. First choice will also most likely in
24796 ;; fewer dependencies. On the place of esp adjustments it is very likely that
24797 ;; call clobbered registers are dead. We may want to use base pointer as an
24798 ;; alternative when no register is available later.
24799
24800 (define_peephole2
24801 [(match_scratch:W 1 "r")
24802 (parallel [(set (reg:P SP_REG)
24803 (plus:P (reg:P SP_REG)
24804 (match_operand:P 0 "const_int_operand")))
24805 (clobber (reg:CC FLAGS_REG))
24806 (clobber (mem:BLK (scratch)))])]
24807 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
24808 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
24809 && !ix86_red_zone_used"
24810 [(clobber (match_dup 1))
24811 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24812 (clobber (mem:BLK (scratch)))])])
24813
24814 (define_peephole2
24815 [(match_scratch:W 1 "r")
24816 (parallel [(set (reg:P SP_REG)
24817 (plus:P (reg:P SP_REG)
24818 (match_operand:P 0 "const_int_operand")))
24819 (clobber (reg:CC FLAGS_REG))
24820 (clobber (mem:BLK (scratch)))])]
24821 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
24822 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
24823 && !ix86_red_zone_used"
24824 [(clobber (match_dup 1))
24825 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24826 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24827 (clobber (mem:BLK (scratch)))])])
24828
24829 ;; Convert esp subtractions to push.
24830 (define_peephole2
24831 [(match_scratch:W 1 "r")
24832 (parallel [(set (reg:P SP_REG)
24833 (plus:P (reg:P SP_REG)
24834 (match_operand:P 0 "const_int_operand")))
24835 (clobber (reg:CC FLAGS_REG))])]
24836 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
24837 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
24838 && !ix86_red_zone_used"
24839 [(clobber (match_dup 1))
24840 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
24841
24842 (define_peephole2
24843 [(match_scratch:W 1 "r")
24844 (parallel [(set (reg:P SP_REG)
24845 (plus:P (reg:P SP_REG)
24846 (match_operand:P 0 "const_int_operand")))
24847 (clobber (reg:CC FLAGS_REG))])]
24848 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
24849 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
24850 && !ix86_red_zone_used"
24851 [(clobber (match_dup 1))
24852 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24853 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
24854
24855 ;; Convert epilogue deallocator to pop.
24856 (define_peephole2
24857 [(match_scratch:W 1 "r")
24858 (parallel [(set (reg:P SP_REG)
24859 (plus:P (reg:P SP_REG)
24860 (match_operand:P 0 "const_int_operand")))
24861 (clobber (reg:CC FLAGS_REG))
24862 (clobber (mem:BLK (scratch)))])]
24863 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
24864 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
24865 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24866 (clobber (mem:BLK (scratch)))])])
24867
24868 ;; Two pops case is tricky, since pop causes dependency
24869 ;; on destination register. We use two registers if available.
24870 (define_peephole2
24871 [(match_scratch:W 1 "r")
24872 (match_scratch:W 2 "r")
24873 (parallel [(set (reg:P SP_REG)
24874 (plus:P (reg:P SP_REG)
24875 (match_operand:P 0 "const_int_operand")))
24876 (clobber (reg:CC FLAGS_REG))
24877 (clobber (mem:BLK (scratch)))])]
24878 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
24879 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24880 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24881 (clobber (mem:BLK (scratch)))])
24882 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
24883
24884 (define_peephole2
24885 [(match_scratch:W 1 "r")
24886 (parallel [(set (reg:P SP_REG)
24887 (plus:P (reg:P SP_REG)
24888 (match_operand:P 0 "const_int_operand")))
24889 (clobber (reg:CC FLAGS_REG))
24890 (clobber (mem:BLK (scratch)))])]
24891 "optimize_insn_for_size_p ()
24892 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24893 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24894 (clobber (mem:BLK (scratch)))])
24895 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
24896
24897 ;; Convert esp additions to pop.
24898 (define_peephole2
24899 [(match_scratch:W 1 "r")
24900 (parallel [(set (reg:P SP_REG)
24901 (plus:P (reg:P SP_REG)
24902 (match_operand:P 0 "const_int_operand")))
24903 (clobber (reg:CC FLAGS_REG))])]
24904 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
24905 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
24906
24907 ;; Two pops case is tricky, since pop causes dependency
24908 ;; on destination register. We use two registers if available.
24909 (define_peephole2
24910 [(match_scratch:W 1 "r")
24911 (match_scratch:W 2 "r")
24912 (parallel [(set (reg:P SP_REG)
24913 (plus:P (reg:P SP_REG)
24914 (match_operand:P 0 "const_int_operand")))
24915 (clobber (reg:CC FLAGS_REG))])]
24916 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24917 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24918 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
24919
24920 (define_peephole2
24921 [(match_scratch:W 1 "r")
24922 (parallel [(set (reg:P SP_REG)
24923 (plus:P (reg:P SP_REG)
24924 (match_operand:P 0 "const_int_operand")))
24925 (clobber (reg:CC FLAGS_REG))])]
24926 "optimize_insn_for_size_p ()
24927 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24928 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24929 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
24930 \f
24931 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
24932 ;; required and register dies. Similarly for 128 to -128.
24933 (define_peephole2
24934 [(set (match_operand 0 "flags_reg_operand")
24935 (match_operator 1 "compare_operator"
24936 [(match_operand 2 "register_operand")
24937 (match_operand 3 "const_int_operand")]))]
24938 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
24939 && incdec_operand (operands[3], GET_MODE (operands[3])))
24940 || (!TARGET_FUSE_CMP_AND_BRANCH
24941 && INTVAL (operands[3]) == 128))
24942 && ix86_match_ccmode (insn, CCGCmode)
24943 && peep2_reg_dead_p (1, operands[2])"
24944 [(parallel [(set (match_dup 0)
24945 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
24946 (clobber (match_dup 2))])])
24947 \f
24948 ;; Convert imul by three, five and nine into lea
24949 (define_peephole2
24950 [(parallel
24951 [(set (match_operand:SWI48 0 "register_operand")
24952 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
24953 (match_operand:SWI48 2 "const359_operand")))
24954 (clobber (reg:CC FLAGS_REG))])]
24955 "!TARGET_PARTIAL_REG_STALL
24956 || <MODE>mode == SImode
24957 || optimize_function_for_size_p (cfun)"
24958 [(set (match_dup 0)
24959 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
24960 (match_dup 1)))]
24961 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
24962
24963 (define_peephole2
24964 [(parallel
24965 [(set (match_operand:SWI48 0 "register_operand")
24966 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
24967 (match_operand:SWI48 2 "const359_operand")))
24968 (clobber (reg:CC FLAGS_REG))])]
24969 "optimize_insn_for_speed_p ()
24970 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
24971 [(set (match_dup 0) (match_dup 1))
24972 (set (match_dup 0)
24973 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
24974 (match_dup 0)))]
24975 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
24976
24977 ;; imul $32bit_imm, mem, reg is vector decoded, while
24978 ;; imul $32bit_imm, reg, reg is direct decoded.
24979 (define_peephole2
24980 [(match_scratch:SWI48 3 "r")
24981 (parallel [(set (match_operand:SWI48 0 "register_operand")
24982 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
24983 (match_operand:SWI48 2 "immediate_operand")))
24984 (clobber (reg:CC FLAGS_REG))])]
24985 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
24986 && !satisfies_constraint_K (operands[2])"
24987 [(set (match_dup 3) (match_dup 1))
24988 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
24989 (clobber (reg:CC FLAGS_REG))])])
24990
24991 (define_peephole2
24992 [(match_scratch:SI 3 "r")
24993 (parallel [(set (match_operand:DI 0 "register_operand")
24994 (zero_extend:DI
24995 (mult:SI (match_operand:SI 1 "memory_operand")
24996 (match_operand:SI 2 "immediate_operand"))))
24997 (clobber (reg:CC FLAGS_REG))])]
24998 "TARGET_64BIT
24999 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
25000 && !satisfies_constraint_K (operands[2])"
25001 [(set (match_dup 3) (match_dup 1))
25002 (parallel [(set (match_dup 0)
25003 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
25004 (clobber (reg:CC FLAGS_REG))])])
25005
25006 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
25007 ;; Convert it into imul reg, reg
25008 ;; It would be better to force assembler to encode instruction using long
25009 ;; immediate, but there is apparently no way to do so.
25010 (define_peephole2
25011 [(parallel [(set (match_operand:SWI248 0 "register_operand")
25012 (mult:SWI248
25013 (match_operand:SWI248 1 "nonimmediate_operand")
25014 (match_operand:SWI248 2 "const_int_operand")))
25015 (clobber (reg:CC FLAGS_REG))])
25016 (match_scratch:SWI248 3 "r")]
25017 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
25018 && satisfies_constraint_K (operands[2])"
25019 [(set (match_dup 3) (match_dup 2))
25020 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
25021 (clobber (reg:CC FLAGS_REG))])]
25022 {
25023 if (!rtx_equal_p (operands[0], operands[1]))
25024 emit_move_insn (operands[0], operands[1]);
25025 })
25026
25027 ;; After splitting up read-modify operations, array accesses with memory
25028 ;; operands might end up in form:
25029 ;; sall $2, %eax
25030 ;; movl 4(%esp), %edx
25031 ;; addl %edx, %eax
25032 ;; instead of pre-splitting:
25033 ;; sall $2, %eax
25034 ;; addl 4(%esp), %eax
25035 ;; Turn it into:
25036 ;; movl 4(%esp), %edx
25037 ;; leal (%edx,%eax,4), %eax
25038
25039 (define_peephole2
25040 [(match_scratch:W 5 "r")
25041 (parallel [(set (match_operand 0 "register_operand")
25042 (ashift (match_operand 1 "register_operand")
25043 (match_operand 2 "const_int_operand")))
25044 (clobber (reg:CC FLAGS_REG))])
25045 (parallel [(set (match_operand 3 "register_operand")
25046 (plus (match_dup 0)
25047 (match_operand 4 "x86_64_general_operand")))
25048 (clobber (reg:CC FLAGS_REG))])]
25049 "IN_RANGE (INTVAL (operands[2]), 1, 3)
25050 /* Validate MODE for lea. */
25051 && ((!TARGET_PARTIAL_REG_STALL
25052 && (GET_MODE (operands[0]) == QImode
25053 || GET_MODE (operands[0]) == HImode))
25054 || GET_MODE (operands[0]) == SImode
25055 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
25056 && (rtx_equal_p (operands[0], operands[3])
25057 || peep2_reg_dead_p (2, operands[0]))
25058 /* We reorder load and the shift. */
25059 && !reg_overlap_mentioned_p (operands[0], operands[4])"
25060 [(set (match_dup 5) (match_dup 4))
25061 (set (match_dup 0) (match_dup 1))]
25062 {
25063 machine_mode op1mode = GET_MODE (operands[1]);
25064 machine_mode mode = op1mode == DImode ? DImode : SImode;
25065 int scale = 1 << INTVAL (operands[2]);
25066 rtx index = gen_lowpart (word_mode, operands[1]);
25067 rtx base = gen_lowpart (word_mode, operands[5]);
25068 rtx dest = gen_lowpart (mode, operands[3]);
25069
25070 operands[1] = gen_rtx_PLUS (word_mode, base,
25071 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25072 if (mode != word_mode)
25073 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25074
25075 operands[5] = base;
25076 if (op1mode != word_mode)
25077 operands[5] = gen_lowpart (op1mode, operands[5]);
25078
25079 operands[0] = dest;
25080 })
25081 \f
25082 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25083 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25084 ;; caught for use by garbage collectors and the like. Using an insn that
25085 ;; maps to SIGILL makes it more likely the program will rightfully die.
25086 ;; Keeping with tradition, "6" is in honor of #UD.
25087 (define_insn "trap"
25088 [(trap_if (const_int 1) (const_int 6))]
25089 ""
25090 {
25091 #ifdef HAVE_AS_IX86_UD2
25092 return "ud2";
25093 #else
25094 return ASM_SHORT "0x0b0f";
25095 #endif
25096 }
25097 [(set_attr "length" "2")])
25098
25099 (define_insn "ud2"
25100 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25101 ""
25102 {
25103 #ifdef HAVE_AS_IX86_UD2
25104 return "ud2";
25105 #else
25106 return ASM_SHORT "0x0b0f";
25107 #endif
25108 }
25109 [(set_attr "length" "2")])
25110
25111 (define_expand "prefetch"
25112 [(prefetch (match_operand 0 "address_operand")
25113 (match_operand:SI 1 "const_int_operand")
25114 (match_operand:SI 2 "const_int_operand"))]
25115 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25116 {
25117 bool write = operands[1] != const0_rtx;
25118 int locality = INTVAL (operands[2]);
25119
25120 gcc_assert (IN_RANGE (locality, 0, 3));
25121
25122 /* Use 3dNOW prefetch in case we are asking for write prefetch not
25123 supported by SSE counterpart (non-SSE2 athlon machines) or the
25124 SSE prefetch is not available (K6 machines). Otherwise use SSE
25125 prefetch as it allows specifying of locality. */
25126
25127 if (write)
25128 {
25129 if (TARGET_PREFETCHWT1)
25130 operands[2] = GEN_INT (MAX (locality, 2));
25131 else if (TARGET_PRFCHW)
25132 operands[2] = GEN_INT (3);
25133 else if (TARGET_3DNOW && !TARGET_SSE2)
25134 operands[2] = GEN_INT (3);
25135 else if (TARGET_PREFETCH_SSE)
25136 operands[1] = const0_rtx;
25137 else
25138 {
25139 gcc_assert (TARGET_3DNOW);
25140 operands[2] = GEN_INT (3);
25141 }
25142 }
25143 else
25144 {
25145 if (TARGET_PREFETCH_SSE)
25146 ;
25147 else
25148 {
25149 gcc_assert (TARGET_3DNOW);
25150 operands[2] = GEN_INT (3);
25151 }
25152 }
25153 })
25154
25155 (define_insn "*prefetch_sse"
25156 [(prefetch (match_operand 0 "address_operand" "p")
25157 (const_int 0)
25158 (match_operand:SI 1 "const_int_operand"))]
25159 "TARGET_PREFETCH_SSE"
25160 {
25161 static const char * const patterns[4] = {
25162 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25163 };
25164
25165 int locality = INTVAL (operands[1]);
25166 gcc_assert (IN_RANGE (locality, 0, 3));
25167
25168 return patterns[locality];
25169 }
25170 [(set_attr "type" "sse")
25171 (set_attr "atom_sse_attr" "prefetch")
25172 (set (attr "length_address")
25173 (symbol_ref "memory_address_length (operands[0], false)"))
25174 (set_attr "memory" "none")])
25175
25176 (define_insn "*prefetch_3dnow"
25177 [(prefetch (match_operand 0 "address_operand" "p")
25178 (match_operand:SI 1 "const_int_operand")
25179 (const_int 3))]
25180 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25181 {
25182 if (operands[1] == const0_rtx)
25183 return "prefetch\t%a0";
25184 else
25185 return "prefetchw\t%a0";
25186 }
25187 [(set_attr "type" "mmx")
25188 (set (attr "length_address")
25189 (symbol_ref "memory_address_length (operands[0], false)"))
25190 (set_attr "memory" "none")])
25191
25192 (define_insn "*prefetch_prefetchwt1"
25193 [(prefetch (match_operand 0 "address_operand" "p")
25194 (const_int 1)
25195 (const_int 2))]
25196 "TARGET_PREFETCHWT1"
25197 "prefetchwt1\t%a0";
25198 [(set_attr "type" "sse")
25199 (set (attr "length_address")
25200 (symbol_ref "memory_address_length (operands[0], false)"))
25201 (set_attr "memory" "none")])
25202
25203 (define_insn "prefetchi"
25204 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
25205 (match_operand:SI 1 "const_int_operand")]
25206 UNSPECV_PREFETCHI)]
25207 "TARGET_PREFETCHI && TARGET_64BIT"
25208 {
25209 static const char * const patterns[2] = {
25210 "prefetchit1\t%0", "prefetchit0\t%0"
25211 };
25212
25213 int locality = INTVAL (operands[1]);
25214 gcc_assert (IN_RANGE (locality, 2, 3));
25215
25216 return patterns[locality - 2];
25217 }
25218 [(set_attr "type" "sse")
25219 (set (attr "length_address")
25220 (symbol_ref "memory_address_length (operands[0], false)"))
25221 (set_attr "memory" "none")])
25222
25223 (define_expand "stack_protect_set"
25224 [(match_operand 0 "memory_operand")
25225 (match_operand 1 "memory_operand")]
25226 ""
25227 {
25228 emit_insn (gen_stack_protect_set_1
25229 (ptr_mode, operands[0], operands[1]));
25230 DONE;
25231 })
25232
25233 (define_insn "@stack_protect_set_1_<mode>"
25234 [(set (match_operand:PTR 0 "memory_operand" "=m")
25235 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
25236 UNSPEC_SP_SET))
25237 (set (match_scratch:PTR 2 "=&r") (const_int 0))
25238 (clobber (reg:CC FLAGS_REG))]
25239 ""
25240 {
25241 output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
25242 output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
25243 return "xor{l}\t%k2, %k2";
25244 }
25245 [(set_attr "type" "multi")])
25246
25247 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
25248 ;; immediately followed by *mov{s,d}i_internal to the same register,
25249 ;; where we can avoid the xor{l} above. We don't split this, so that
25250 ;; scheduling or anything else doesn't separate the *stack_protect_set*
25251 ;; pattern from the set of the register that overwrites the register
25252 ;; with a new value.
25253 (define_insn "*stack_protect_set_2_<mode>"
25254 [(set (match_operand:PTR 0 "memory_operand" "=m")
25255 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25256 UNSPEC_SP_SET))
25257 (set (match_operand:SI 1 "register_operand" "=&r")
25258 (match_operand:SI 2 "general_operand" "g"))
25259 (clobber (reg:CC FLAGS_REG))]
25260 "reload_completed
25261 && !reg_overlap_mentioned_p (operands[1], operands[2])"
25262 {
25263 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25264 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25265 if (pic_32bit_operand (operands[2], SImode)
25266 || ix86_use_lea_for_mov (insn, operands + 1))
25267 return "lea{l}\t{%E2, %1|%1, %E2}";
25268 else
25269 return "mov{l}\t{%2, %1|%1, %2}";
25270 }
25271 [(set_attr "type" "multi")
25272 (set_attr "length" "24")])
25273
25274 (define_peephole2
25275 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25276 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25277 UNSPEC_SP_SET))
25278 (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
25279 (clobber (reg:CC FLAGS_REG))])
25280 (set (match_operand:SI 3 "general_reg_operand")
25281 (match_operand:SI 4))]
25282 "REGNO (operands[2]) == REGNO (operands[3])
25283 && general_operand (operands[4], SImode)
25284 && (general_reg_operand (operands[4], SImode)
25285 || memory_operand (operands[4], SImode)
25286 || immediate_operand (operands[4], SImode))
25287 && !reg_overlap_mentioned_p (operands[3], operands[4])"
25288 [(parallel [(set (match_dup 0)
25289 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25290 (set (match_dup 3) (match_dup 4))
25291 (clobber (reg:CC FLAGS_REG))])])
25292
25293 (define_insn "*stack_protect_set_3"
25294 [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
25295 (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
25296 UNSPEC_SP_SET))
25297 (set (match_operand:DI 1 "register_operand" "=&r,r,r")
25298 (match_operand:DI 2 "general_operand" "Z,rem,i"))
25299 (clobber (reg:CC FLAGS_REG))]
25300 "TARGET_64BIT
25301 && reload_completed
25302 && !reg_overlap_mentioned_p (operands[1], operands[2])"
25303 {
25304 output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
25305 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
25306 if (pic_32bit_operand (operands[2], DImode))
25307 return "lea{q}\t{%E2, %1|%1, %E2}";
25308 else if (which_alternative == 0)
25309 return "mov{l}\t{%k2, %k1|%k1, %k2}";
25310 else if (which_alternative == 2)
25311 return "movabs{q}\t{%2, %1|%1, %2}";
25312 else if (ix86_use_lea_for_mov (insn, operands + 1))
25313 return "lea{q}\t{%E2, %1|%1, %E2}";
25314 else
25315 return "mov{q}\t{%2, %1|%1, %2}";
25316 }
25317 [(set_attr "type" "multi")
25318 (set_attr "length" "24")])
25319
25320 (define_peephole2
25321 [(parallel [(set (match_operand:DI 0 "memory_operand")
25322 (unspec:DI [(match_operand:DI 1 "memory_operand")]
25323 UNSPEC_SP_SET))
25324 (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
25325 (clobber (reg:CC FLAGS_REG))])
25326 (set (match_dup 2) (match_operand:DI 3))]
25327 "TARGET_64BIT
25328 && general_operand (operands[3], DImode)
25329 && (general_reg_operand (operands[3], DImode)
25330 || memory_operand (operands[3], DImode)
25331 || x86_64_zext_immediate_operand (operands[3], DImode)
25332 || x86_64_immediate_operand (operands[3], DImode)
25333 || (CONSTANT_P (operands[3])
25334 && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
25335 && !reg_overlap_mentioned_p (operands[2], operands[3])"
25336 [(parallel [(set (match_dup 0)
25337 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25338 (set (match_dup 2) (match_dup 3))
25339 (clobber (reg:CC FLAGS_REG))])])
25340
25341 (define_expand "stack_protect_test"
25342 [(match_operand 0 "memory_operand")
25343 (match_operand 1 "memory_operand")
25344 (match_operand 2)]
25345 ""
25346 {
25347 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
25348
25349 emit_insn (gen_stack_protect_test_1
25350 (ptr_mode, flags, operands[0], operands[1]));
25351
25352 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
25353 flags, const0_rtx, operands[2]));
25354 DONE;
25355 })
25356
25357 (define_insn "@stack_protect_test_1_<mode>"
25358 [(set (match_operand:CCZ 0 "flags_reg_operand")
25359 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
25360 (match_operand:PTR 2 "memory_operand" "m")]
25361 UNSPEC_SP_TEST))
25362 (clobber (match_scratch:PTR 3 "=&r"))]
25363 ""
25364 {
25365 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
25366 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
25367 }
25368 [(set_attr "type" "multi")])
25369
25370 (define_insn "sse4_2_crc32<mode>"
25371 [(set (match_operand:SI 0 "register_operand" "=r")
25372 (unspec:SI
25373 [(match_operand:SI 1 "register_operand" "0")
25374 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
25375 UNSPEC_CRC32))]
25376 "TARGET_CRC32"
25377 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
25378 [(set_attr "type" "sselog1")
25379 (set_attr "prefix_rep" "1")
25380 (set_attr "prefix_extra" "1")
25381 (set (attr "prefix_data16")
25382 (if_then_else (match_operand:HI 2)
25383 (const_string "1")
25384 (const_string "*")))
25385 (set (attr "prefix_rex")
25386 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
25387 (const_string "1")
25388 (const_string "*")))
25389 (set_attr "mode" "SI")])
25390
25391 (define_insn "sse4_2_crc32di"
25392 [(set (match_operand:DI 0 "register_operand" "=r")
25393 (zero_extend:DI
25394 (unspec:SI
25395 [(match_operand:SI 1 "register_operand" "0")
25396 (match_operand:DI 2 "nonimmediate_operand" "rm")]
25397 UNSPEC_CRC32)))]
25398 "TARGET_64BIT && TARGET_CRC32"
25399 "crc32{q}\t{%2, %0|%0, %2}"
25400 [(set_attr "type" "sselog1")
25401 (set_attr "prefix_rep" "1")
25402 (set_attr "prefix_extra" "1")
25403 (set_attr "mode" "DI")])
25404
25405 (define_insn "rdpmc"
25406 [(set (match_operand:DI 0 "register_operand" "=A")
25407 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25408 UNSPECV_RDPMC))]
25409 "!TARGET_64BIT"
25410 "rdpmc"
25411 [(set_attr "type" "other")
25412 (set_attr "length" "2")])
25413
25414 (define_insn "rdpmc_rex64"
25415 [(set (match_operand:DI 0 "register_operand" "=a")
25416 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25417 UNSPECV_RDPMC))
25418 (set (match_operand:DI 1 "register_operand" "=d")
25419 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
25420 "TARGET_64BIT"
25421 "rdpmc"
25422 [(set_attr "type" "other")
25423 (set_attr "length" "2")])
25424
25425 (define_insn "rdtsc"
25426 [(set (match_operand:DI 0 "register_operand" "=A")
25427 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25428 "!TARGET_64BIT"
25429 "rdtsc"
25430 [(set_attr "type" "other")
25431 (set_attr "length" "2")])
25432
25433 (define_insn "rdtsc_rex64"
25434 [(set (match_operand:DI 0 "register_operand" "=a")
25435 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
25436 (set (match_operand:DI 1 "register_operand" "=d")
25437 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25438 "TARGET_64BIT"
25439 "rdtsc"
25440 [(set_attr "type" "other")
25441 (set_attr "length" "2")])
25442
25443 (define_insn "rdtscp"
25444 [(set (match_operand:DI 0 "register_operand" "=A")
25445 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25446 (set (match_operand:SI 1 "register_operand" "=c")
25447 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25448 "!TARGET_64BIT"
25449 "rdtscp"
25450 [(set_attr "type" "other")
25451 (set_attr "length" "3")])
25452
25453 (define_insn "rdtscp_rex64"
25454 [(set (match_operand:DI 0 "register_operand" "=a")
25455 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25456 (set (match_operand:DI 1 "register_operand" "=d")
25457 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25458 (set (match_operand:SI 2 "register_operand" "=c")
25459 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25460 "TARGET_64BIT"
25461 "rdtscp"
25462 [(set_attr "type" "other")
25463 (set_attr "length" "3")])
25464
25465 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25466 ;;
25467 ;; FXSR, XSAVE and XSAVEOPT instructions
25468 ;;
25469 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25470
25471 (define_insn "fxsave"
25472 [(set (match_operand:BLK 0 "memory_operand" "=m")
25473 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
25474 "TARGET_FXSR"
25475 "fxsave\t%0"
25476 [(set_attr "type" "other")
25477 (set_attr "memory" "store")
25478 (set (attr "length")
25479 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25480
25481 (define_insn "fxsave64"
25482 [(set (match_operand:BLK 0 "memory_operand" "=m")
25483 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
25484 "TARGET_64BIT && TARGET_FXSR"
25485 "fxsave64\t%0"
25486 [(set_attr "type" "other")
25487 (set_attr "memory" "store")
25488 (set (attr "length")
25489 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25490
25491 (define_insn "fxrstor"
25492 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25493 UNSPECV_FXRSTOR)]
25494 "TARGET_FXSR"
25495 "fxrstor\t%0"
25496 [(set_attr "type" "other")
25497 (set_attr "memory" "load")
25498 (set (attr "length")
25499 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25500
25501 (define_insn "fxrstor64"
25502 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25503 UNSPECV_FXRSTOR64)]
25504 "TARGET_64BIT && TARGET_FXSR"
25505 "fxrstor64\t%0"
25506 [(set_attr "type" "other")
25507 (set_attr "memory" "load")
25508 (set (attr "length")
25509 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25510
25511 (define_int_iterator ANY_XSAVE
25512 [UNSPECV_XSAVE
25513 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
25514 (UNSPECV_XSAVEC "TARGET_XSAVEC")
25515 (UNSPECV_XSAVES "TARGET_XSAVES")])
25516
25517 (define_int_iterator ANY_XSAVE64
25518 [UNSPECV_XSAVE64
25519 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
25520 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
25521 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
25522
25523 (define_int_attr xsave
25524 [(UNSPECV_XSAVE "xsave")
25525 (UNSPECV_XSAVE64 "xsave64")
25526 (UNSPECV_XSAVEOPT "xsaveopt")
25527 (UNSPECV_XSAVEOPT64 "xsaveopt64")
25528 (UNSPECV_XSAVEC "xsavec")
25529 (UNSPECV_XSAVEC64 "xsavec64")
25530 (UNSPECV_XSAVES "xsaves")
25531 (UNSPECV_XSAVES64 "xsaves64")])
25532
25533 (define_int_iterator ANY_XRSTOR
25534 [UNSPECV_XRSTOR
25535 (UNSPECV_XRSTORS "TARGET_XSAVES")])
25536
25537 (define_int_iterator ANY_XRSTOR64
25538 [UNSPECV_XRSTOR64
25539 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
25540
25541 (define_int_attr xrstor
25542 [(UNSPECV_XRSTOR "xrstor")
25543 (UNSPECV_XRSTOR64 "xrstor")
25544 (UNSPECV_XRSTORS "xrstors")
25545 (UNSPECV_XRSTORS64 "xrstors")])
25546
25547 (define_insn "<xsave>"
25548 [(set (match_operand:BLK 0 "memory_operand" "=m")
25549 (unspec_volatile:BLK
25550 [(match_operand:DI 1 "register_operand" "A")]
25551 ANY_XSAVE))]
25552 "!TARGET_64BIT && TARGET_XSAVE"
25553 "<xsave>\t%0"
25554 [(set_attr "type" "other")
25555 (set_attr "memory" "store")
25556 (set (attr "length")
25557 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25558
25559 (define_insn "<xsave>_rex64"
25560 [(set (match_operand:BLK 0 "memory_operand" "=m")
25561 (unspec_volatile:BLK
25562 [(match_operand:SI 1 "register_operand" "a")
25563 (match_operand:SI 2 "register_operand" "d")]
25564 ANY_XSAVE))]
25565 "TARGET_64BIT && TARGET_XSAVE"
25566 "<xsave>\t%0"
25567 [(set_attr "type" "other")
25568 (set_attr "memory" "store")
25569 (set (attr "length")
25570 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25571
25572 (define_insn "<xsave>"
25573 [(set (match_operand:BLK 0 "memory_operand" "=m")
25574 (unspec_volatile:BLK
25575 [(match_operand:SI 1 "register_operand" "a")
25576 (match_operand:SI 2 "register_operand" "d")]
25577 ANY_XSAVE64))]
25578 "TARGET_64BIT && TARGET_XSAVE"
25579 "<xsave>\t%0"
25580 [(set_attr "type" "other")
25581 (set_attr "memory" "store")
25582 (set (attr "length")
25583 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25584
25585 (define_insn "<xrstor>"
25586 [(unspec_volatile:BLK
25587 [(match_operand:BLK 0 "memory_operand" "m")
25588 (match_operand:DI 1 "register_operand" "A")]
25589 ANY_XRSTOR)]
25590 "!TARGET_64BIT && TARGET_XSAVE"
25591 "<xrstor>\t%0"
25592 [(set_attr "type" "other")
25593 (set_attr "memory" "load")
25594 (set (attr "length")
25595 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25596
25597 (define_insn "<xrstor>_rex64"
25598 [(unspec_volatile:BLK
25599 [(match_operand:BLK 0 "memory_operand" "m")
25600 (match_operand:SI 1 "register_operand" "a")
25601 (match_operand:SI 2 "register_operand" "d")]
25602 ANY_XRSTOR)]
25603 "TARGET_64BIT && TARGET_XSAVE"
25604 "<xrstor>\t%0"
25605 [(set_attr "type" "other")
25606 (set_attr "memory" "load")
25607 (set (attr "length")
25608 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25609
25610 (define_insn "<xrstor>64"
25611 [(unspec_volatile:BLK
25612 [(match_operand:BLK 0 "memory_operand" "m")
25613 (match_operand:SI 1 "register_operand" "a")
25614 (match_operand:SI 2 "register_operand" "d")]
25615 ANY_XRSTOR64)]
25616 "TARGET_64BIT && TARGET_XSAVE"
25617 "<xrstor>64\t%0"
25618 [(set_attr "type" "other")
25619 (set_attr "memory" "load")
25620 (set (attr "length")
25621 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25622
25623 (define_insn "xsetbv"
25624 [(unspec_volatile:SI
25625 [(match_operand:SI 0 "register_operand" "c")
25626 (match_operand:DI 1 "register_operand" "A")]
25627 UNSPECV_XSETBV)]
25628 "!TARGET_64BIT && TARGET_XSAVE"
25629 "xsetbv"
25630 [(set_attr "type" "other")])
25631
25632 (define_insn "xsetbv_rex64"
25633 [(unspec_volatile:SI
25634 [(match_operand:SI 0 "register_operand" "c")
25635 (match_operand:SI 1 "register_operand" "a")
25636 (match_operand:SI 2 "register_operand" "d")]
25637 UNSPECV_XSETBV)]
25638 "TARGET_64BIT && TARGET_XSAVE"
25639 "xsetbv"
25640 [(set_attr "type" "other")])
25641
25642 (define_insn "xgetbv"
25643 [(set (match_operand:DI 0 "register_operand" "=A")
25644 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25645 UNSPECV_XGETBV))]
25646 "!TARGET_64BIT && TARGET_XSAVE"
25647 "xgetbv"
25648 [(set_attr "type" "other")])
25649
25650 (define_insn "xgetbv_rex64"
25651 [(set (match_operand:DI 0 "register_operand" "=a")
25652 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25653 UNSPECV_XGETBV))
25654 (set (match_operand:DI 1 "register_operand" "=d")
25655 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
25656 "TARGET_64BIT && TARGET_XSAVE"
25657 "xgetbv"
25658 [(set_attr "type" "other")])
25659
25660 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25661 ;;
25662 ;; Floating-point instructions for atomic compound assignments
25663 ;;
25664 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25665
25666 ; Clobber all floating-point registers on environment save and restore
25667 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
25668 (define_insn "fnstenv"
25669 [(set (match_operand:BLK 0 "memory_operand" "=m")
25670 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
25671 (clobber (reg:XF ST0_REG))
25672 (clobber (reg:XF ST1_REG))
25673 (clobber (reg:XF ST2_REG))
25674 (clobber (reg:XF ST3_REG))
25675 (clobber (reg:XF ST4_REG))
25676 (clobber (reg:XF ST5_REG))
25677 (clobber (reg:XF ST6_REG))
25678 (clobber (reg:XF ST7_REG))]
25679 "TARGET_80387"
25680 "fnstenv\t%0"
25681 [(set_attr "type" "other")
25682 (set_attr "memory" "store")
25683 (set (attr "length")
25684 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25685
25686 (define_insn "fldenv"
25687 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25688 UNSPECV_FLDENV)
25689 (clobber (reg:XF ST0_REG))
25690 (clobber (reg:XF ST1_REG))
25691 (clobber (reg:XF ST2_REG))
25692 (clobber (reg:XF ST3_REG))
25693 (clobber (reg:XF ST4_REG))
25694 (clobber (reg:XF ST5_REG))
25695 (clobber (reg:XF ST6_REG))
25696 (clobber (reg:XF ST7_REG))]
25697 "TARGET_80387"
25698 "fldenv\t%0"
25699 [(set_attr "type" "other")
25700 (set_attr "memory" "load")
25701 (set (attr "length")
25702 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25703
25704 (define_insn "fnstsw"
25705 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
25706 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
25707 "TARGET_80387"
25708 "fnstsw\t%0"
25709 [(set_attr "type" "other,other")
25710 (set_attr "memory" "none,store")
25711 (set (attr "length")
25712 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25713
25714 (define_insn "fnclex"
25715 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
25716 "TARGET_80387"
25717 "fnclex"
25718 [(set_attr "type" "other")
25719 (set_attr "memory" "none")
25720 (set_attr "length" "2")])
25721
25722 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25723 ;;
25724 ;; LWP instructions
25725 ;;
25726 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25727
25728 (define_insn "@lwp_llwpcb<mode>"
25729 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
25730 UNSPECV_LLWP_INTRINSIC)]
25731 "TARGET_LWP"
25732 "llwpcb\t%0"
25733 [(set_attr "type" "lwp")
25734 (set_attr "mode" "<MODE>")
25735 (set_attr "length" "5")])
25736
25737 (define_insn "@lwp_slwpcb<mode>"
25738 [(set (match_operand:P 0 "register_operand" "=r")
25739 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
25740 "TARGET_LWP"
25741 "slwpcb\t%0"
25742 [(set_attr "type" "lwp")
25743 (set_attr "mode" "<MODE>")
25744 (set_attr "length" "5")])
25745
25746 (define_insn "@lwp_lwpval<mode>"
25747 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25748 (match_operand:SI 1 "nonimmediate_operand" "rm")
25749 (match_operand:SI 2 "const_int_operand")]
25750 UNSPECV_LWPVAL_INTRINSIC)]
25751 "TARGET_LWP"
25752 "lwpval\t{%2, %1, %0|%0, %1, %2}"
25753 [(set_attr "type" "lwp")
25754 (set_attr "mode" "<MODE>")
25755 (set (attr "length")
25756 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
25757
25758 (define_insn "@lwp_lwpins<mode>"
25759 [(set (reg:CCC FLAGS_REG)
25760 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
25761 (match_operand:SI 1 "nonimmediate_operand" "rm")
25762 (match_operand:SI 2 "const_int_operand")]
25763 UNSPECV_LWPINS_INTRINSIC))]
25764 "TARGET_LWP"
25765 "lwpins\t{%2, %1, %0|%0, %1, %2}"
25766 [(set_attr "type" "lwp")
25767 (set_attr "mode" "<MODE>")
25768 (set (attr "length")
25769 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
25770
25771 (define_int_iterator RDFSGSBASE
25772 [UNSPECV_RDFSBASE
25773 UNSPECV_RDGSBASE])
25774
25775 (define_int_iterator WRFSGSBASE
25776 [UNSPECV_WRFSBASE
25777 UNSPECV_WRGSBASE])
25778
25779 (define_int_attr fsgs
25780 [(UNSPECV_RDFSBASE "fs")
25781 (UNSPECV_RDGSBASE "gs")
25782 (UNSPECV_WRFSBASE "fs")
25783 (UNSPECV_WRGSBASE "gs")])
25784
25785 (define_insn "rd<fsgs>base<mode>"
25786 [(set (match_operand:SWI48 0 "register_operand" "=r")
25787 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
25788 "TARGET_64BIT && TARGET_FSGSBASE"
25789 "rd<fsgs>base\t%0"
25790 [(set_attr "type" "other")
25791 (set_attr "prefix_extra" "2")])
25792
25793 (define_insn "wr<fsgs>base<mode>"
25794 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
25795 WRFSGSBASE)]
25796 "TARGET_64BIT && TARGET_FSGSBASE"
25797 "wr<fsgs>base\t%0"
25798 [(set_attr "type" "other")
25799 (set_attr "prefix_extra" "2")])
25800
25801 (define_insn "ptwrite<mode>"
25802 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
25803 UNSPECV_PTWRITE)]
25804 "TARGET_PTWRITE"
25805 "ptwrite\t%0"
25806 [(set_attr "type" "other")
25807 (set_attr "prefix_extra" "2")])
25808
25809 (define_insn "@rdrand<mode>"
25810 [(set (match_operand:SWI248 0 "register_operand" "=r")
25811 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
25812 (set (reg:CCC FLAGS_REG)
25813 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
25814 "TARGET_RDRND"
25815 "rdrand\t%0"
25816 [(set_attr "type" "other")
25817 (set_attr "prefix_extra" "1")])
25818
25819 (define_insn "@rdseed<mode>"
25820 [(set (match_operand:SWI248 0 "register_operand" "=r")
25821 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
25822 (set (reg:CCC FLAGS_REG)
25823 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
25824 "TARGET_RDSEED"
25825 "rdseed\t%0"
25826 [(set_attr "type" "other")
25827 (set_attr "prefix_extra" "1")])
25828
25829 (define_expand "pause"
25830 [(set (match_dup 0)
25831 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
25832 ""
25833 {
25834 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
25835 MEM_VOLATILE_P (operands[0]) = 1;
25836 })
25837
25838 ;; Use "rep; nop", instead of "pause", to support older assemblers.
25839 ;; They have the same encoding.
25840 (define_insn "*pause"
25841 [(set (match_operand:BLK 0)
25842 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
25843 ""
25844 "rep%; nop"
25845 [(set_attr "length" "2")
25846 (set_attr "memory" "unknown")])
25847
25848 ;; CET instructions
25849 (define_insn "@rdssp<mode>"
25850 [(set (match_operand:SWI48 0 "register_operand" "=r")
25851 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
25852 UNSPECV_NOP_RDSSP))]
25853 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
25854 "rdssp<mskmodesuffix>\t%0"
25855 [(set_attr "length" "6")
25856 (set_attr "type" "other")])
25857
25858 (define_insn "@incssp<mode>"
25859 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
25860 UNSPECV_INCSSP)]
25861 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
25862 "incssp<mskmodesuffix>\t%0"
25863 [(set_attr "length" "4")
25864 (set_attr "type" "other")])
25865
25866 (define_insn "saveprevssp"
25867 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
25868 "TARGET_SHSTK"
25869 "saveprevssp"
25870 [(set_attr "length" "5")
25871 (set_attr "type" "other")])
25872
25873 (define_insn "rstorssp"
25874 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
25875 UNSPECV_RSTORSSP)]
25876 "TARGET_SHSTK"
25877 "rstorssp\t%0"
25878 [(set_attr "length" "5")
25879 (set_attr "type" "other")])
25880
25881 (define_insn "@wrss<mode>"
25882 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25883 (match_operand:SWI48 1 "memory_operand" "m")]
25884 UNSPECV_WRSS)]
25885 "TARGET_SHSTK"
25886 "wrss<mskmodesuffix>\t%0, %1"
25887 [(set_attr "length" "3")
25888 (set_attr "type" "other")])
25889
25890 (define_insn "@wruss<mode>"
25891 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25892 (match_operand:SWI48 1 "memory_operand" "m")]
25893 UNSPECV_WRUSS)]
25894 "TARGET_SHSTK"
25895 "wruss<mskmodesuffix>\t%0, %1"
25896 [(set_attr "length" "4")
25897 (set_attr "type" "other")])
25898
25899 (define_insn "setssbsy"
25900 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
25901 "TARGET_SHSTK"
25902 "setssbsy"
25903 [(set_attr "length" "4")
25904 (set_attr "type" "other")])
25905
25906 (define_insn "clrssbsy"
25907 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
25908 UNSPECV_CLRSSBSY)]
25909 "TARGET_SHSTK"
25910 "clrssbsy\t%0"
25911 [(set_attr "length" "4")
25912 (set_attr "type" "other")])
25913
25914 (define_insn "nop_endbr"
25915 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
25916 "(flag_cf_protection & CF_BRANCH)"
25917 {
25918 return TARGET_64BIT ? "endbr64" : "endbr32";
25919 }
25920 [(set_attr "length" "4")
25921 (set_attr "length_immediate" "0")
25922 (set_attr "modrm" "0")])
25923
25924 ;; For RTM support
25925 (define_expand "xbegin"
25926 [(set (match_operand:SI 0 "register_operand")
25927 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
25928 "TARGET_RTM"
25929 {
25930 rtx_code_label *label = gen_label_rtx ();
25931
25932 /* xbegin is emitted as jump_insn, so reload won't be able
25933 to reload its operand. Force the value into AX hard register. */
25934 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
25935 emit_move_insn (ax_reg, constm1_rtx);
25936
25937 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
25938
25939 emit_label (label);
25940 LABEL_NUSES (label) = 1;
25941
25942 emit_move_insn (operands[0], ax_reg);
25943
25944 DONE;
25945 })
25946
25947 (define_insn "xbegin_1"
25948 [(set (pc)
25949 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
25950 (const_int 0))
25951 (label_ref (match_operand 1))
25952 (pc)))
25953 (set (match_operand:SI 0 "register_operand" "+a")
25954 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
25955 "TARGET_RTM"
25956 "xbegin\t%l1"
25957 [(set_attr "type" "other")
25958 (set_attr "length" "6")])
25959
25960 (define_insn "xend"
25961 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
25962 "TARGET_RTM"
25963 "xend"
25964 [(set_attr "type" "other")
25965 (set_attr "length" "3")])
25966
25967 (define_insn "xabort"
25968 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
25969 UNSPECV_XABORT)]
25970 "TARGET_RTM"
25971 "xabort\t%0"
25972 [(set_attr "type" "other")
25973 (set_attr "length" "3")])
25974
25975 (define_expand "xtest"
25976 [(set (match_operand:QI 0 "register_operand")
25977 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
25978 "TARGET_RTM"
25979 {
25980 emit_insn (gen_xtest_1 ());
25981
25982 ix86_expand_setcc (operands[0], NE,
25983 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
25984 DONE;
25985 })
25986
25987 (define_insn "xtest_1"
25988 [(set (reg:CCZ FLAGS_REG)
25989 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
25990 "TARGET_RTM"
25991 "xtest"
25992 [(set_attr "type" "other")
25993 (set_attr "length" "3")])
25994
25995 (define_insn "clwb"
25996 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
25997 UNSPECV_CLWB)]
25998 "TARGET_CLWB"
25999 "clwb\t%a0"
26000 [(set_attr "type" "sse")
26001 (set_attr "atom_sse_attr" "fence")
26002 (set_attr "memory" "unknown")])
26003
26004 (define_insn "clflushopt"
26005 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
26006 UNSPECV_CLFLUSHOPT)]
26007 "TARGET_CLFLUSHOPT"
26008 "clflushopt\t%a0"
26009 [(set_attr "type" "sse")
26010 (set_attr "atom_sse_attr" "fence")
26011 (set_attr "memory" "unknown")])
26012
26013 ;; MONITORX and MWAITX
26014 (define_insn "mwaitx"
26015 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
26016 (match_operand:SI 1 "register_operand" "a")
26017 (match_operand:SI 2 "register_operand" "b")]
26018 UNSPECV_MWAITX)]
26019 "TARGET_MWAITX"
26020 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
26021 ;; Since 32bit register operands are implicitly zero extended to 64bit,
26022 ;; we only need to set up 32bit registers.
26023 "mwaitx"
26024 [(set_attr "length" "3")])
26025
26026 (define_insn "@monitorx_<mode>"
26027 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
26028 (match_operand:SI 1 "register_operand" "c")
26029 (match_operand:SI 2 "register_operand" "d")]
26030 UNSPECV_MONITORX)]
26031 "TARGET_MWAITX"
26032 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
26033 ;; RCX and RDX are used. Since 32bit register operands are implicitly
26034 ;; zero extended to 64bit, we only need to set up 32bit registers.
26035 "%^monitorx"
26036 [(set (attr "length")
26037 (symbol_ref ("(Pmode != word_mode) + 3")))])
26038
26039 ;; CLZERO
26040 (define_insn "@clzero_<mode>"
26041 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
26042 UNSPECV_CLZERO)]
26043 "TARGET_CLZERO"
26044 "clzero"
26045 [(set_attr "length" "3")
26046 (set_attr "memory" "unknown")])
26047
26048 ;; RDPKRU and WRPKRU
26049
26050 (define_expand "rdpkru"
26051 [(parallel
26052 [(set (match_operand:SI 0 "register_operand")
26053 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
26054 (set (match_dup 2) (const_int 0))])]
26055 "TARGET_PKU"
26056 {
26057 operands[1] = force_reg (SImode, const0_rtx);
26058 operands[2] = gen_reg_rtx (SImode);
26059 })
26060
26061 (define_insn "*rdpkru"
26062 [(set (match_operand:SI 0 "register_operand" "=a")
26063 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
26064 UNSPECV_PKU))
26065 (set (match_operand:SI 1 "register_operand" "=d")
26066 (const_int 0))]
26067 "TARGET_PKU"
26068 "rdpkru"
26069 [(set_attr "type" "other")])
26070
26071 (define_expand "wrpkru"
26072 [(unspec_volatile:SI
26073 [(match_operand:SI 0 "register_operand")
26074 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26075 "TARGET_PKU"
26076 {
26077 operands[1] = force_reg (SImode, const0_rtx);
26078 operands[2] = force_reg (SImode, const0_rtx);
26079 })
26080
26081 (define_insn "*wrpkru"
26082 [(unspec_volatile:SI
26083 [(match_operand:SI 0 "register_operand" "a")
26084 (match_operand:SI 1 "register_operand" "d")
26085 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26086 "TARGET_PKU"
26087 "wrpkru"
26088 [(set_attr "type" "other")])
26089
26090 (define_insn "rdpid"
26091 [(set (match_operand:SI 0 "register_operand" "=r")
26092 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26093 "!TARGET_64BIT && TARGET_RDPID"
26094 "rdpid\t%0"
26095 [(set_attr "type" "other")])
26096
26097 (define_insn "rdpid_rex64"
26098 [(set (match_operand:DI 0 "register_operand" "=r")
26099 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26100 "TARGET_64BIT && TARGET_RDPID"
26101 "rdpid\t%0"
26102 [(set_attr "type" "other")])
26103
26104 ;; Intirinsics for > i486
26105
26106 (define_insn "wbinvd"
26107 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26108 ""
26109 "wbinvd"
26110 [(set_attr "type" "other")])
26111
26112 (define_insn "wbnoinvd"
26113 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26114 "TARGET_WBNOINVD"
26115 "wbnoinvd"
26116 [(set_attr "type" "other")])
26117
26118 ;; MOVDIRI and MOVDIR64B
26119
26120 (define_insn "movdiri<mode>"
26121 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26122 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26123 UNSPEC_MOVDIRI))]
26124 "TARGET_MOVDIRI"
26125 "movdiri\t{%1, %0|%0, %1}"
26126 [(set_attr "type" "other")])
26127
26128 (define_insn "@movdir64b_<mode>"
26129 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26130 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26131 UNSPEC_MOVDIR64B))]
26132 "TARGET_MOVDIR64B"
26133 "movdir64b\t{%1, %0|%0, %1}"
26134 [(set_attr "type" "other")])
26135
26136 ;; TSXLDTRK
26137 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26138 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26139 (UNSPECV_XRESLDTRK "xresldtrk")])
26140 (define_insn "<tsxldtrk>"
26141 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26142 "TARGET_TSXLDTRK"
26143 "<tsxldtrk>"
26144 [(set_attr "type" "other")
26145 (set_attr "length" "4")])
26146
26147 ;; ENQCMD and ENQCMDS
26148
26149 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26150 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26151
26152 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26153 [(set (reg:CCZ FLAGS_REG)
26154 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26155 (match_operand:XI 1 "memory_operand" "m")]
26156 ENQCMD))]
26157 "TARGET_ENQCMD"
26158 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26159 [(set_attr "type" "other")])
26160
26161 ;; UINTR
26162 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26163 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26164
26165 (define_insn "<uintr>"
26166 [(unspec_volatile [(const_int 0)] UINTR)]
26167 "TARGET_UINTR && TARGET_64BIT"
26168 "<uintr>"
26169 [(set_attr "type" "other")
26170 (set_attr "length" "4")])
26171
26172 (define_insn "testui"
26173 [(set (reg:CCC FLAGS_REG)
26174 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26175 "TARGET_UINTR && TARGET_64BIT"
26176 "testui"
26177 [(set_attr "type" "other")
26178 (set_attr "length" "4")])
26179
26180 (define_insn "senduipi"
26181 [(unspec_volatile
26182 [(match_operand:DI 0 "register_operand" "r")]
26183 UNSPECV_SENDUIPI)]
26184 "TARGET_UINTR && TARGET_64BIT"
26185 "senduipi\t%0"
26186 [(set_attr "type" "other")
26187 (set_attr "length" "4")])
26188
26189 ;; WAITPKG
26190
26191 (define_insn "umwait"
26192 [(set (reg:CCC FLAGS_REG)
26193 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26194 (match_operand:DI 1 "register_operand" "A")]
26195 UNSPECV_UMWAIT))]
26196 "!TARGET_64BIT && TARGET_WAITPKG"
26197 "umwait\t%0"
26198 [(set_attr "length" "3")])
26199
26200 (define_insn "umwait_rex64"
26201 [(set (reg:CCC FLAGS_REG)
26202 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26203 (match_operand:SI 1 "register_operand" "a")
26204 (match_operand:SI 2 "register_operand" "d")]
26205 UNSPECV_UMWAIT))]
26206 "TARGET_64BIT && TARGET_WAITPKG"
26207 "umwait\t%0"
26208 [(set_attr "length" "3")])
26209
26210 (define_insn "@umonitor_<mode>"
26211 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26212 UNSPECV_UMONITOR)]
26213 "TARGET_WAITPKG"
26214 "umonitor\t%0"
26215 [(set (attr "length")
26216 (symbol_ref ("(Pmode != word_mode) + 3")))])
26217
26218 (define_insn "tpause"
26219 [(set (reg:CCC FLAGS_REG)
26220 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26221 (match_operand:DI 1 "register_operand" "A")]
26222 UNSPECV_TPAUSE))]
26223 "!TARGET_64BIT && TARGET_WAITPKG"
26224 "tpause\t%0"
26225 [(set_attr "length" "3")])
26226
26227 (define_insn "tpause_rex64"
26228 [(set (reg:CCC FLAGS_REG)
26229 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26230 (match_operand:SI 1 "register_operand" "a")
26231 (match_operand:SI 2 "register_operand" "d")]
26232 UNSPECV_TPAUSE))]
26233 "TARGET_64BIT && TARGET_WAITPKG"
26234 "tpause\t%0"
26235 [(set_attr "length" "3")])
26236
26237 (define_insn "cldemote"
26238 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26239 UNSPECV_CLDEMOTE)]
26240 "TARGET_CLDEMOTE"
26241 "cldemote\t%a0"
26242 [(set_attr "type" "other")
26243 (set_attr "memory" "unknown")])
26244
26245 (define_insn "speculation_barrier"
26246 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26247 ""
26248 "lfence"
26249 [(set_attr "type" "other")
26250 (set_attr "length" "3")])
26251
26252 (define_insn "serialize"
26253 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26254 "TARGET_SERIALIZE"
26255 "serialize"
26256 [(set_attr "type" "other")
26257 (set_attr "length" "3")])
26258
26259 (define_insn "patchable_area"
26260 [(unspec_volatile [(match_operand 0 "const_int_operand")
26261 (match_operand 1 "const_int_operand")]
26262 UNSPECV_PATCHABLE_AREA)]
26263 ""
26264 {
26265 ix86_output_patchable_area (INTVAL (operands[0]),
26266 INTVAL (operands[1]) != 0);
26267 return "";
26268 }
26269 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26270 (set_attr "length_immediate" "0")
26271 (set_attr "modrm" "0")])
26272
26273 (define_insn "hreset"
26274 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26275 UNSPECV_HRESET)]
26276 "TARGET_HRESET"
26277 "hreset\t{$0|0}"
26278 [(set_attr "type" "other")
26279 (set_attr "length" "4")])
26280
26281 ;; Spaceship optimization
26282 (define_expand "spaceship<mode>3"
26283 [(match_operand:SI 0 "register_operand")
26284 (match_operand:MODEF 1 "cmp_fp_expander_operand")
26285 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26286 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26287 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26288 {
26289 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26290 DONE;
26291 })
26292
26293 (define_expand "spaceshipxf3"
26294 [(match_operand:SI 0 "register_operand")
26295 (match_operand:XF 1 "nonmemory_operand")
26296 (match_operand:XF 2 "nonmemory_operand")]
26297 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26298 {
26299 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26300 DONE;
26301 })
26302
26303 ;; Defined because the generic expand_builtin_issignaling for XFmode
26304 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26305 ;; signaling.
26306 (define_expand "issignalingxf2"
26307 [(match_operand:SI 0 "register_operand")
26308 (match_operand:XF 1 "general_operand")]
26309 ""
26310 {
26311 rtx temp = operands[1];
26312 if (!MEM_P (temp))
26313 {
26314 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26315 emit_move_insn (mem, temp);
26316 temp = mem;
26317 }
26318 rtx ex = adjust_address (temp, HImode, 8);
26319 rtx hi = adjust_address (temp, SImode, 4);
26320 rtx lo = adjust_address (temp, SImode, 0);
26321 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26322 rtx mask = GEN_INT (0x7fff);
26323 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26324 /* Expand to:
26325 ((ex & mask) && (int) hi >= 0)
26326 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
26327 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26328 lo = expand_binop (SImode, ior_optab, lo, nlo,
26329 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26330 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26331 temp = expand_binop (SImode, xor_optab, hi, bit,
26332 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26333 temp = expand_binop (SImode, ior_optab, temp, lo,
26334 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26335 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
26336 SImode, 1, 1);
26337 ex = expand_binop (HImode, and_optab, ex, mask,
26338 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26339 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
26340 ex, const0_rtx, SImode, 1, 1);
26341 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
26342 ex, mask, HImode, 1, 1);
26343 temp = expand_binop (SImode, and_optab, temp, ex,
26344 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26345 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
26346 hi, const0_rtx, SImode, 0, 1);
26347 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
26348 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26349 temp = expand_binop (SImode, ior_optab, temp, temp2,
26350 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26351 emit_move_insn (operands[0], temp);
26352 DONE;
26353 })
26354
26355 (include "mmx.md")
26356 (include "sse.md")
26357 (include "sync.md")