Daily bump.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2021 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
117 ;; For SSE/MMX support:
118 UNSPEC_FIX_NOTRUNC
119 UNSPEC_MASKMOV
120 UNSPEC_MOVMSK
121 UNSPEC_RCP
122 UNSPEC_RSQRT
123 UNSPEC_PSADBW
124
125 ;; Generic math support
126 UNSPEC_COPYSIGN
127 UNSPEC_XORSIGN
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
130
131 ;; x87 Floating point
132 UNSPEC_SIN
133 UNSPEC_COS
134 UNSPEC_FPATAN
135 UNSPEC_FYL2X
136 UNSPEC_FYL2XP1
137 UNSPEC_FRNDINT
138 UNSPEC_FIST
139 UNSPEC_F2XM1
140 UNSPEC_TAN
141 UNSPEC_FXAM
142
143 ;; x87 Rounding
144 UNSPEC_FRNDINT_ROUNDEVEN
145 UNSPEC_FRNDINT_FLOOR
146 UNSPEC_FRNDINT_CEIL
147 UNSPEC_FRNDINT_TRUNC
148 UNSPEC_FIST_FLOOR
149 UNSPEC_FIST_CEIL
150
151 ;; x87 Double output FP
152 UNSPEC_SINCOS_COS
153 UNSPEC_SINCOS_SIN
154 UNSPEC_XTRACT_FRACT
155 UNSPEC_XTRACT_EXP
156 UNSPEC_FSCALE_FRACT
157 UNSPEC_FSCALE_EXP
158 UNSPEC_FPREM_F
159 UNSPEC_FPREM_U
160 UNSPEC_FPREM1_F
161 UNSPEC_FPREM1_U
162
163 UNSPEC_C2_FLAG
164 UNSPEC_FXAM_MEM
165
166 ;; SSP patterns
167 UNSPEC_SP_SET
168 UNSPEC_SP_TEST
169
170 ;; For ROUND support
171 UNSPEC_ROUND
172
173 ;; For CRC32 support
174 UNSPEC_CRC32
175
176 ;; For LZCNT suppoprt
177 UNSPEC_LZCNT
178
179 ;; For BMI support
180 UNSPEC_TZCNT
181 UNSPEC_BEXTR
182
183 ;; For BMI2 support
184 UNSPEC_PDEP
185 UNSPEC_PEXT
186
187 ;; IRET support
188 UNSPEC_INTERRUPT_RETURN
189
190 ;; For MOVDIRI and MOVDIR64B support
191 UNSPEC_MOVDIRI
192 UNSPEC_MOVDIR64B
193 ])
194
195 (define_c_enum "unspecv" [
196 UNSPECV_UD2
197 UNSPECV_BLOCKAGE
198 UNSPECV_STACK_PROBE
199 UNSPECV_PROBE_STACK_RANGE
200 UNSPECV_ALIGN
201 UNSPECV_PROLOGUE_USE
202 UNSPECV_SPLIT_STACK_RETURN
203 UNSPECV_CLD
204 UNSPECV_NOPS
205 UNSPECV_RDTSC
206 UNSPECV_RDTSCP
207 UNSPECV_RDPMC
208 UNSPECV_LLWP_INTRINSIC
209 UNSPECV_SLWP_INTRINSIC
210 UNSPECV_LWPVAL_INTRINSIC
211 UNSPECV_LWPINS_INTRINSIC
212 UNSPECV_RDFSBASE
213 UNSPECV_RDGSBASE
214 UNSPECV_WRFSBASE
215 UNSPECV_WRGSBASE
216 UNSPECV_FXSAVE
217 UNSPECV_FXRSTOR
218 UNSPECV_FXSAVE64
219 UNSPECV_FXRSTOR64
220 UNSPECV_XSAVE
221 UNSPECV_XRSTOR
222 UNSPECV_XSAVE64
223 UNSPECV_XRSTOR64
224 UNSPECV_XSAVEOPT
225 UNSPECV_XSAVEOPT64
226 UNSPECV_XSAVES
227 UNSPECV_XRSTORS
228 UNSPECV_XSAVES64
229 UNSPECV_XRSTORS64
230 UNSPECV_XSAVEC
231 UNSPECV_XSAVEC64
232 UNSPECV_XGETBV
233 UNSPECV_XSETBV
234 UNSPECV_WBINVD
235 UNSPECV_WBNOINVD
236
237 ;; For atomic compound assignments.
238 UNSPECV_FNSTENV
239 UNSPECV_FLDENV
240 UNSPECV_FNSTSW
241 UNSPECV_FNCLEX
242
243 ;; For RDRAND support
244 UNSPECV_RDRAND
245
246 ;; For RDSEED support
247 UNSPECV_RDSEED
248
249 ;; For RTM support
250 UNSPECV_XBEGIN
251 UNSPECV_XEND
252 UNSPECV_XABORT
253 UNSPECV_XTEST
254
255 UNSPECV_NLGR
256
257 ;; For CLWB support
258 UNSPECV_CLWB
259
260 ;; For CLFLUSHOPT support
261 UNSPECV_CLFLUSHOPT
262
263 ;; For MONITORX and MWAITX support
264 UNSPECV_MONITORX
265 UNSPECV_MWAITX
266
267 ;; For CLZERO support
268 UNSPECV_CLZERO
269
270 ;; For RDPKRU and WRPKRU support
271 UNSPECV_PKU
272
273 ;; For RDPID support
274 UNSPECV_RDPID
275
276 ;; For CET support
277 UNSPECV_NOP_ENDBR
278 UNSPECV_NOP_RDSSP
279 UNSPECV_INCSSP
280 UNSPECV_SAVEPREVSSP
281 UNSPECV_RSTORSSP
282 UNSPECV_WRSS
283 UNSPECV_WRUSS
284 UNSPECV_SETSSBSY
285 UNSPECV_CLRSSBSY
286
287 ;; For TSXLDTRK support
288 UNSPECV_XSUSLDTRK
289 UNSPECV_XRESLDTRK
290
291 ;; For WAITPKG support
292 UNSPECV_UMWAIT
293 UNSPECV_UMONITOR
294 UNSPECV_TPAUSE
295
296 ;; For UINTR support
297 UNSPECV_CLUI
298 UNSPECV_STUI
299 UNSPECV_TESTUI
300 UNSPECV_SENDUIPI
301
302 ;; For CLDEMOTE support
303 UNSPECV_CLDEMOTE
304
305 ;; For Speculation Barrier support
306 UNSPECV_SPECULATION_BARRIER
307
308 UNSPECV_PTWRITE
309
310 ;; For ENQCMD and ENQCMDS support
311 UNSPECV_ENQCMD
312 UNSPECV_ENQCMDS
313
314 ;; For SERIALIZE support
315 UNSPECV_SERIALIZE
316
317 ;; For patchable area support
318 UNSPECV_PATCHABLE_AREA
319
320 ;; For HRESET support
321 UNSPECV_HRESET
322 ])
323
324 ;; Constants to represent rounding modes in the ROUND instruction
325 (define_constants
326 [(ROUND_ROUNDEVEN 0x0)
327 (ROUND_FLOOR 0x1)
328 (ROUND_CEIL 0x2)
329 (ROUND_TRUNC 0x3)
330 (ROUND_MXCSR 0x4)
331 (ROUND_NO_EXC 0x8)
332 ])
333
334 ;; Constants to represent AVX512F embeded rounding
335 (define_constants
336 [(ROUND_NEAREST_INT 0)
337 (ROUND_NEG_INF 1)
338 (ROUND_POS_INF 2)
339 (ROUND_ZERO 3)
340 (NO_ROUND 4)
341 (ROUND_SAE 8)
342 ])
343
344 ;; Constants to represent pcomtrue/pcomfalse variants
345 (define_constants
346 [(PCOM_FALSE 0)
347 (PCOM_TRUE 1)
348 (COM_FALSE_S 2)
349 (COM_FALSE_P 3)
350 (COM_TRUE_S 4)
351 (COM_TRUE_P 5)
352 ])
353
354 ;; Constants used in the XOP pperm instruction
355 (define_constants
356 [(PPERM_SRC 0x00) /* copy source */
357 (PPERM_INVERT 0x20) /* invert source */
358 (PPERM_REVERSE 0x40) /* bit reverse source */
359 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
360 (PPERM_ZERO 0x80) /* all 0's */
361 (PPERM_ONES 0xa0) /* all 1's */
362 (PPERM_SIGN 0xc0) /* propagate sign bit */
363 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
364 (PPERM_SRC1 0x00) /* use first source byte */
365 (PPERM_SRC2 0x10) /* use second source byte */
366 ])
367
368 ;; Registers by name.
369 (define_constants
370 [(AX_REG 0)
371 (DX_REG 1)
372 (CX_REG 2)
373 (BX_REG 3)
374 (SI_REG 4)
375 (DI_REG 5)
376 (BP_REG 6)
377 (SP_REG 7)
378 (ST0_REG 8)
379 (ST1_REG 9)
380 (ST2_REG 10)
381 (ST3_REG 11)
382 (ST4_REG 12)
383 (ST5_REG 13)
384 (ST6_REG 14)
385 (ST7_REG 15)
386 (ARGP_REG 16)
387 (FLAGS_REG 17)
388 (FPSR_REG 18)
389 (FRAME_REG 19)
390 (XMM0_REG 20)
391 (XMM1_REG 21)
392 (XMM2_REG 22)
393 (XMM3_REG 23)
394 (XMM4_REG 24)
395 (XMM5_REG 25)
396 (XMM6_REG 26)
397 (XMM7_REG 27)
398 (MM0_REG 28)
399 (MM1_REG 29)
400 (MM2_REG 30)
401 (MM3_REG 31)
402 (MM4_REG 32)
403 (MM5_REG 33)
404 (MM6_REG 34)
405 (MM7_REG 35)
406 (R8_REG 36)
407 (R9_REG 37)
408 (R10_REG 38)
409 (R11_REG 39)
410 (R12_REG 40)
411 (R13_REG 41)
412 (R14_REG 42)
413 (R15_REG 43)
414 (XMM8_REG 44)
415 (XMM9_REG 45)
416 (XMM10_REG 46)
417 (XMM11_REG 47)
418 (XMM12_REG 48)
419 (XMM13_REG 49)
420 (XMM14_REG 50)
421 (XMM15_REG 51)
422 (XMM16_REG 52)
423 (XMM17_REG 53)
424 (XMM18_REG 54)
425 (XMM19_REG 55)
426 (XMM20_REG 56)
427 (XMM21_REG 57)
428 (XMM22_REG 58)
429 (XMM23_REG 59)
430 (XMM24_REG 60)
431 (XMM25_REG 61)
432 (XMM26_REG 62)
433 (XMM27_REG 63)
434 (XMM28_REG 64)
435 (XMM29_REG 65)
436 (XMM30_REG 66)
437 (XMM31_REG 67)
438 (MASK0_REG 68)
439 (MASK1_REG 69)
440 (MASK2_REG 70)
441 (MASK3_REG 71)
442 (MASK4_REG 72)
443 (MASK5_REG 73)
444 (MASK6_REG 74)
445 (MASK7_REG 75)
446 (FIRST_PSEUDO_REG 76)
447 ])
448
449 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
450 ;; from i386.c.
451
452 ;; In C guard expressions, put expressions which may be compile-time
453 ;; constants first. This allows for better optimization. For
454 ;; example, write "TARGET_64BIT && reload_completed", not
455 ;; "reload_completed && TARGET_64BIT".
456
457 \f
458 ;; Processor type.
459 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
460 atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
461 bdver4,btver2,znver1,znver2,znver3"
462 (const (symbol_ref "ix86_schedule")))
463
464 ;; A basic instruction type. Refinements due to arguments to be
465 ;; provided in other attributes.
466 (define_attr "type"
467 "other,multi,
468 alu,alu1,negnot,imov,imovx,lea,
469 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
470 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
471 push,pop,call,callv,leave,
472 str,bitmanip,
473 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
474 fxch,fistp,fisttp,frndint,
475 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
476 ssemul,sseimul,ssediv,sselog,sselog1,
477 sseishft,sseishft1,ssecmp,ssecomi,
478 ssecvt,ssecvt1,sseicvt,sseins,
479 sseshuf,sseshuf1,ssemuladd,sse4arg,
480 lwp,mskmov,msklog,
481 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
482 (const_string "other"))
483
484 ;; Main data type used by the insn
485 (define_attr "mode"
486 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
487 V2DF,V2SF,V1DF,V8DF"
488 (const_string "unknown"))
489
490 ;; The CPU unit operations uses.
491 (define_attr "unit" "integer,i387,sse,mmx,unknown"
492 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
493 fxch,fistp,fisttp,frndint")
494 (const_string "i387")
495 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
496 ssemul,sseimul,ssediv,sselog,sselog1,
497 sseishft,sseishft1,ssecmp,ssecomi,
498 ssecvt,ssecvt1,sseicvt,sseins,
499 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
500 (const_string "sse")
501 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
502 (const_string "mmx")
503 (eq_attr "type" "other")
504 (const_string "unknown")]
505 (const_string "integer")))
506
507 ;; The (bounding maximum) length of an instruction immediate.
508 (define_attr "length_immediate" ""
509 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
510 bitmanip,imulx,msklog,mskmov")
511 (const_int 0)
512 (eq_attr "unit" "i387,sse,mmx")
513 (const_int 0)
514 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
515 rotate,rotatex,rotate1,imul,icmp,push,pop")
516 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
517 (eq_attr "type" "imov,test")
518 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
519 (eq_attr "type" "call")
520 (if_then_else (match_operand 0 "constant_call_address_operand")
521 (const_int 4)
522 (const_int 0))
523 (eq_attr "type" "callv")
524 (if_then_else (match_operand 1 "constant_call_address_operand")
525 (const_int 4)
526 (const_int 0))
527 ;; We don't know the size before shorten_branches. Expect
528 ;; the instruction to fit for better scheduling.
529 (eq_attr "type" "ibr")
530 (const_int 1)
531 ]
532 (symbol_ref "/* Update immediate_length and other attributes! */
533 gcc_unreachable (),1")))
534
535 ;; The (bounding maximum) length of an instruction address.
536 (define_attr "length_address" ""
537 (cond [(eq_attr "type" "str,other,multi,fxch")
538 (const_int 0)
539 (and (eq_attr "type" "call")
540 (match_operand 0 "constant_call_address_operand"))
541 (const_int 0)
542 (and (eq_attr "type" "callv")
543 (match_operand 1 "constant_call_address_operand"))
544 (const_int 0)
545 ]
546 (symbol_ref "ix86_attr_length_address_default (insn)")))
547
548 ;; Set when length prefix is used.
549 (define_attr "prefix_data16" ""
550 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
551 (const_int 0)
552 (eq_attr "mode" "HI")
553 (const_int 1)
554 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
555 (const_int 1)
556 ]
557 (const_int 0)))
558
559 ;; Set when string REP prefix is used.
560 (define_attr "prefix_rep" ""
561 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
562 (const_int 0)
563 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
564 (const_int 1)
565 ]
566 (const_int 0)))
567
568 ;; Set when 0f opcode prefix is used.
569 (define_attr "prefix_0f" ""
570 (if_then_else
571 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
572 (eq_attr "unit" "sse,mmx"))
573 (const_int 1)
574 (const_int 0)))
575
576 ;; Set when REX opcode prefix is used.
577 (define_attr "prefix_rex" ""
578 (cond [(not (match_test "TARGET_64BIT"))
579 (const_int 0)
580 (and (eq_attr "mode" "DI")
581 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
582 (eq_attr "unit" "!mmx")))
583 (const_int 1)
584 (and (eq_attr "mode" "QI")
585 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
586 (const_int 1)
587 (match_test "x86_extended_reg_mentioned_p (insn)")
588 (const_int 1)
589 (and (eq_attr "type" "imovx")
590 (match_operand:QI 1 "ext_QIreg_operand"))
591 (const_int 1)
592 ]
593 (const_int 0)))
594
595 ;; There are also additional prefixes in 3DNOW, SSSE3.
596 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
597 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
598 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
599 (define_attr "prefix_extra" ""
600 (cond [(eq_attr "type" "ssemuladd,sse4arg")
601 (const_int 2)
602 (eq_attr "type" "sseiadd1,ssecvt1")
603 (const_int 1)
604 ]
605 (const_int 0)))
606
607 ;; Prefix used: original, VEX or maybe VEX.
608 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
609 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
610 (const_string "vex")
611 (eq_attr "mode" "XI,V16SF,V8DF")
612 (const_string "evex")
613 ]
614 (const_string "orig")))
615
616 ;; VEX W bit is used.
617 (define_attr "prefix_vex_w" "" (const_int 0))
618
619 ;; The length of VEX prefix
620 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
621 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
622 ;; still prefix_0f 1, with prefix_extra 1.
623 (define_attr "length_vex" ""
624 (if_then_else (and (eq_attr "prefix_0f" "1")
625 (eq_attr "prefix_extra" "0"))
626 (if_then_else (eq_attr "prefix_vex_w" "1")
627 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
628 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
629 (if_then_else (eq_attr "prefix_vex_w" "1")
630 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
631 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
632
633 ;; 4-bytes evex prefix and 1 byte opcode.
634 (define_attr "length_evex" "" (const_int 5))
635
636 ;; Set when modrm byte is used.
637 (define_attr "modrm" ""
638 (cond [(eq_attr "type" "str,leave")
639 (const_int 0)
640 (eq_attr "unit" "i387")
641 (const_int 0)
642 (and (eq_attr "type" "incdec")
643 (and (not (match_test "TARGET_64BIT"))
644 (ior (match_operand:SI 1 "register_operand")
645 (match_operand:HI 1 "register_operand"))))
646 (const_int 0)
647 (and (eq_attr "type" "push")
648 (not (match_operand 1 "memory_operand")))
649 (const_int 0)
650 (and (eq_attr "type" "pop")
651 (not (match_operand 0 "memory_operand")))
652 (const_int 0)
653 (and (eq_attr "type" "imov")
654 (and (not (eq_attr "mode" "DI"))
655 (ior (and (match_operand 0 "register_operand")
656 (match_operand 1 "immediate_operand"))
657 (ior (and (match_operand 0 "ax_reg_operand")
658 (match_operand 1 "memory_displacement_only_operand"))
659 (and (match_operand 0 "memory_displacement_only_operand")
660 (match_operand 1 "ax_reg_operand"))))))
661 (const_int 0)
662 (and (eq_attr "type" "call")
663 (match_operand 0 "constant_call_address_operand"))
664 (const_int 0)
665 (and (eq_attr "type" "callv")
666 (match_operand 1 "constant_call_address_operand"))
667 (const_int 0)
668 (and (eq_attr "type" "alu,alu1,icmp,test")
669 (match_operand 0 "ax_reg_operand"))
670 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
671 ]
672 (const_int 1)))
673
674 ;; The (bounding maximum) length of an instruction in bytes.
675 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
676 ;; Later we may want to split them and compute proper length as for
677 ;; other insns.
678 (define_attr "length" ""
679 (cond [(eq_attr "type" "other,multi,fistp,frndint")
680 (const_int 16)
681 (eq_attr "type" "fcmp")
682 (const_int 4)
683 (eq_attr "unit" "i387")
684 (plus (const_int 2)
685 (plus (attr "prefix_data16")
686 (attr "length_address")))
687 (ior (eq_attr "prefix" "evex")
688 (and (ior (eq_attr "prefix" "maybe_evex")
689 (eq_attr "prefix" "maybe_vex"))
690 (match_test "TARGET_AVX512F")))
691 (plus (attr "length_evex")
692 (plus (attr "length_immediate")
693 (plus (attr "modrm")
694 (attr "length_address"))))
695 (ior (eq_attr "prefix" "vex")
696 (and (ior (eq_attr "prefix" "maybe_vex")
697 (eq_attr "prefix" "maybe_evex"))
698 (match_test "TARGET_AVX")))
699 (plus (attr "length_vex")
700 (plus (attr "length_immediate")
701 (plus (attr "modrm")
702 (attr "length_address"))))]
703 (plus (plus (attr "modrm")
704 (plus (attr "prefix_0f")
705 (plus (attr "prefix_rex")
706 (plus (attr "prefix_extra")
707 (const_int 1)))))
708 (plus (attr "prefix_rep")
709 (plus (attr "prefix_data16")
710 (plus (attr "length_immediate")
711 (attr "length_address")))))))
712
713 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
714 ;; `store' if there is a simple memory reference therein, or `unknown'
715 ;; if the instruction is complex.
716
717 (define_attr "memory" "none,load,store,both,unknown"
718 (cond [(eq_attr "type" "other,multi,str,lwp")
719 (const_string "unknown")
720 (eq_attr "type" "lea,fcmov,fpspc")
721 (const_string "none")
722 (eq_attr "type" "fistp,leave")
723 (const_string "both")
724 (eq_attr "type" "frndint")
725 (const_string "load")
726 (eq_attr "type" "push")
727 (if_then_else (match_operand 1 "memory_operand")
728 (const_string "both")
729 (const_string "store"))
730 (eq_attr "type" "pop")
731 (if_then_else (match_operand 0 "memory_operand")
732 (const_string "both")
733 (const_string "load"))
734 (eq_attr "type" "setcc")
735 (if_then_else (match_operand 0 "memory_operand")
736 (const_string "store")
737 (const_string "none"))
738 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
739 (if_then_else (ior (match_operand 0 "memory_operand")
740 (match_operand 1 "memory_operand"))
741 (const_string "load")
742 (const_string "none"))
743 (eq_attr "type" "ibr")
744 (if_then_else (match_operand 0 "memory_operand")
745 (const_string "load")
746 (const_string "none"))
747 (eq_attr "type" "call")
748 (if_then_else (match_operand 0 "constant_call_address_operand")
749 (const_string "none")
750 (const_string "load"))
751 (eq_attr "type" "callv")
752 (if_then_else (match_operand 1 "constant_call_address_operand")
753 (const_string "none")
754 (const_string "load"))
755 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
756 (match_operand 1 "memory_operand"))
757 (const_string "both")
758 (and (match_operand 0 "memory_operand")
759 (match_operand 1 "memory_operand"))
760 (const_string "both")
761 (match_operand 0 "memory_operand")
762 (const_string "store")
763 (match_operand 1 "memory_operand")
764 (const_string "load")
765 (and (eq_attr "type"
766 "!alu1,negnot,ishift1,rotate1,
767 imov,imovx,icmp,test,bitmanip,
768 fmov,fcmp,fsgn,
769 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
770 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
771 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
772 (match_operand 2 "memory_operand"))
773 (const_string "load")
774 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
775 (match_operand 3 "memory_operand"))
776 (const_string "load")
777 ]
778 (const_string "none")))
779
780 ;; Indicates if an instruction has both an immediate and a displacement.
781
782 (define_attr "imm_disp" "false,true,unknown"
783 (cond [(eq_attr "type" "other,multi")
784 (const_string "unknown")
785 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
786 (and (match_operand 0 "memory_displacement_operand")
787 (match_operand 1 "immediate_operand")))
788 (const_string "true")
789 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
790 (and (match_operand 0 "memory_displacement_operand")
791 (match_operand 2 "immediate_operand")))
792 (const_string "true")
793 ]
794 (const_string "false")))
795
796 ;; Indicates if an FP operation has an integer source.
797
798 (define_attr "fp_int_src" "false,true"
799 (const_string "false"))
800
801 ;; Defines rounding mode of an FP operation.
802
803 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
804 (const_string "any"))
805
806 ;; Define attribute to indicate AVX insns with partial XMM register update.
807 (define_attr "avx_partial_xmm_update" "false,true"
808 (const_string "false"))
809
810 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
811 (define_attr "use_carry" "0,1" (const_string "0"))
812
813 ;; Define attribute to indicate unaligned ssemov insns
814 (define_attr "movu" "0,1" (const_string "0"))
815
816 ;; Used to control the "enabled" attribute on a per-instruction basis.
817 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
818 sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
819 avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
820 avx512bw,noavx512bw,avx512dq,noavx512dq,
821 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw,
822 avxvnni,avx512vnnivl"
823 (const_string "base"))
824
825 ;; Define instruction set of MMX instructions
826 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
827 (const_string "base"))
828
829 (define_attr "enabled" ""
830 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
831 (eq_attr "isa" "x64_sse2")
832 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
833 (eq_attr "isa" "x64_sse4")
834 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
835 (eq_attr "isa" "x64_sse4_noavx")
836 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
837 (eq_attr "isa" "x64_avx")
838 (symbol_ref "TARGET_64BIT && TARGET_AVX")
839 (eq_attr "isa" "x64_avx512dq")
840 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
841 (eq_attr "isa" "x64_avx512bw")
842 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
843 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
844 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
845 (eq_attr "isa" "sse_noavx")
846 (symbol_ref "TARGET_SSE && !TARGET_AVX")
847 (eq_attr "isa" "sse2_noavx")
848 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
849 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
850 (eq_attr "isa" "sse3_noavx")
851 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
852 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
853 (eq_attr "isa" "sse4_noavx")
854 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
855 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
856 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
857 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
858 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
859 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
860 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
861 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
862 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
863 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
864 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
865 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
866 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
867 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
868 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
869 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
870 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
871 (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
872 (eq_attr "isa" "avx512vnnivl")
873 (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
874
875 (eq_attr "mmx_isa" "native")
876 (symbol_ref "!TARGET_MMX_WITH_SSE")
877 (eq_attr "mmx_isa" "sse")
878 (symbol_ref "TARGET_MMX_WITH_SSE")
879 (eq_attr "mmx_isa" "sse_noavx")
880 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
881 (eq_attr "mmx_isa" "avx")
882 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
883 ]
884 (const_int 1)))
885
886 (define_attr "preferred_for_size" "" (const_int 1))
887 (define_attr "preferred_for_speed" "" (const_int 1))
888
889 ;; Describe a user's asm statement.
890 (define_asm_attributes
891 [(set_attr "length" "128")
892 (set_attr "type" "multi")])
893
894 (define_code_iterator plusminus [plus minus])
895
896 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
897
898 ;; Base name for insn mnemonic.
899 (define_code_attr plusminus_mnemonic
900 [(plus "add") (ss_plus "adds") (us_plus "addus")
901 (minus "sub") (ss_minus "subs") (us_minus "subus")])
902
903 (define_code_iterator multdiv [mult div])
904
905 (define_code_attr multdiv_mnemonic
906 [(mult "mul") (div "div")])
907
908 ;; Mark commutative operators as such in constraints.
909 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
910 (minus "") (ss_minus "") (us_minus "")])
911
912 ;; Mapping of max and min
913 (define_code_iterator maxmin [smax smin umax umin])
914
915 ;; Mapping of signed max and min
916 (define_code_iterator smaxmin [smax smin])
917
918 ;; Mapping of unsigned max and min
919 (define_code_iterator umaxmin [umax umin])
920
921 ;; Base name for integer and FP insn mnemonic
922 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
923 (umax "maxu") (umin "minu")])
924 (define_code_attr maxmin_float [(smax "max") (smin "min")])
925
926 (define_int_iterator IEEE_MAXMIN
927 [UNSPEC_IEEE_MAX
928 UNSPEC_IEEE_MIN])
929
930 (define_int_attr ieee_maxmin
931 [(UNSPEC_IEEE_MAX "max")
932 (UNSPEC_IEEE_MIN "min")])
933
934 ;; Mapping of logic operators
935 (define_code_iterator any_logic [and ior xor])
936 (define_code_iterator any_or [ior xor])
937 (define_code_iterator fpint_logic [and xor])
938
939 ;; Base name for insn mnemonic.
940 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
941
942 ;; Mapping of logic-shift operators
943 (define_code_iterator any_lshift [ashift lshiftrt])
944
945 ;; Mapping of shift-right operators
946 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
947
948 ;; Mapping of all shift operators
949 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
950
951 ;; Base name for insn mnemonic.
952 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
953 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
954
955 ;; Mapping of rotate operators
956 (define_code_iterator any_rotate [rotate rotatert])
957
958 ;; Base name for insn mnemonic.
959 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
960
961 ;; Mapping of abs neg operators
962 (define_code_iterator absneg [abs neg])
963
964 ;; Mapping of abs neg operators to logic operation
965 (define_code_attr absneg_op [(abs "and") (neg "xor")])
966
967 ;; Base name for x87 insn mnemonic.
968 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
969
970 ;; Mapping of extend operators
971 (define_code_iterator any_extend [sign_extend zero_extend])
972
973 ;; Prefix for insn menmonic.
974 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
975 (div "i") (udiv "")])
976 ;; Prefix for define_insn
977 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
978 (define_code_attr u [(sign_extend "") (zero_extend "u")
979 (div "") (udiv "u")])
980 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
981 (div "false") (udiv "true")])
982
983 ;; Used in signed and unsigned truncations.
984 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
985 ;; Instruction suffix for truncations.
986 (define_code_attr trunsuffix
987 [(ss_truncate "s") (truncate "") (us_truncate "us")])
988
989 ;; Used in signed and unsigned fix.
990 (define_code_iterator any_fix [fix unsigned_fix])
991 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
992 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
993 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
994
995 ;; Used in signed and unsigned float.
996 (define_code_iterator any_float [float unsigned_float])
997 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
998 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
999 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1000
1001 ;; Base name for expression
1002 (define_code_attr insn
1003 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1004 (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1005 (sign_extend "extend") (zero_extend "zero_extend")
1006 (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1007 (rotate "rotl") (rotatert "rotr")])
1008
1009 ;; All integer modes.
1010 (define_mode_iterator SWI1248x [QI HI SI DI])
1011
1012 ;; All integer modes without QImode.
1013 (define_mode_iterator SWI248x [HI SI DI])
1014
1015 ;; All integer modes without QImode and HImode.
1016 (define_mode_iterator SWI48x [SI DI])
1017
1018 ;; All integer modes without SImode and DImode.
1019 (define_mode_iterator SWI12 [QI HI])
1020
1021 ;; All integer modes without DImode.
1022 (define_mode_iterator SWI124 [QI HI SI])
1023
1024 ;; All integer modes without QImode and DImode.
1025 (define_mode_iterator SWI24 [HI SI])
1026
1027 ;; Single word integer modes.
1028 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1029
1030 ;; Single word integer modes without QImode.
1031 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1032
1033 ;; Single word integer modes without QImode and HImode.
1034 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1035
1036 ;; All math-dependant single and double word integer modes.
1037 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1038 (HI "TARGET_HIMODE_MATH")
1039 SI DI (TI "TARGET_64BIT")])
1040
1041 ;; Math-dependant single word integer modes.
1042 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1043 (HI "TARGET_HIMODE_MATH")
1044 SI (DI "TARGET_64BIT")])
1045
1046 ;; Math-dependant integer modes without DImode.
1047 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1048 (HI "TARGET_HIMODE_MATH")
1049 SI])
1050
1051 ;; Math-dependant integer modes with DImode (enabled for 32bit with STV).
1052 (define_mode_iterator SWIM1248s
1053 [(QI "TARGET_QIMODE_MATH")
1054 (HI "TARGET_HIMODE_MATH")
1055 SI (DI "TARGET_64BIT || (TARGET_STV && TARGET_SSE2)")])
1056
1057 ;; Math-dependant single word integer modes without QImode.
1058 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1059 SI (DI "TARGET_64BIT")])
1060
1061 ;; Double word integer modes.
1062 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1063 (TI "TARGET_64BIT")])
1064
1065 ;; SWI and DWI together.
1066 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1067
1068 ;; SWI48 and DWI together.
1069 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1070
1071 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1072 ;; compile time constant, it is faster to use <MODE_SIZE> than
1073 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1074 ;; command line options just use GET_MODE_SIZE macro.
1075 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1076 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1077 (V16QI "16") (V32QI "32") (V64QI "64")
1078 (V8HI "16") (V16HI "32") (V32HI "64")
1079 (V4SI "16") (V8SI "32") (V16SI "64")
1080 (V2DI "16") (V4DI "32") (V8DI "64")
1081 (V1TI "16") (V2TI "32") (V4TI "64")
1082 (V2DF "16") (V4DF "32") (V8DF "64")
1083 (V4SF "16") (V8SF "32") (V16SF "64")])
1084
1085 ;; Double word integer modes as mode attribute.
1086 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1087 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1088
1089 ;; LEA mode corresponding to an integer mode
1090 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1091
1092 ;; Half mode for double word integer modes.
1093 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1094 (DI "TARGET_64BIT")])
1095
1096 ;; Instruction suffix for integer modes.
1097 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1098
1099 ;; Instruction suffix for masks.
1100 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1101
1102 ;; Pointer size prefix for integer modes (Intel asm dialect)
1103 (define_mode_attr iptrsize [(QI "BYTE")
1104 (HI "WORD")
1105 (SI "DWORD")
1106 (DI "QWORD")])
1107
1108 ;; Register class for integer modes.
1109 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1110
1111 ;; Immediate operand constraint for integer modes.
1112 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1113
1114 ;; General operand constraint for word modes.
1115 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1116
1117 ;; Immediate operand constraint for double integer modes.
1118 (define_mode_attr di [(SI "nF") (DI "Wd")])
1119
1120 ;; Immediate operand constraint for shifts.
1121 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1122
1123 ;; Print register name in the specified mode.
1124 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1125
1126 ;; General operand predicate for integer modes.
1127 (define_mode_attr general_operand
1128 [(QI "general_operand")
1129 (HI "general_operand")
1130 (SI "x86_64_general_operand")
1131 (DI "x86_64_general_operand")
1132 (TI "x86_64_general_operand")])
1133
1134 ;; General operand predicate for integer modes, where for TImode
1135 ;; we need both words of the operand to be general operands.
1136 (define_mode_attr general_hilo_operand
1137 [(QI "general_operand")
1138 (HI "general_operand")
1139 (SI "x86_64_general_operand")
1140 (DI "x86_64_general_operand")
1141 (TI "x86_64_hilo_general_operand")])
1142
1143 ;; General sign extend operand predicate for integer modes,
1144 ;; which disallows VOIDmode operands and thus it is suitable
1145 ;; for use inside sign_extend.
1146 (define_mode_attr general_sext_operand
1147 [(QI "sext_operand")
1148 (HI "sext_operand")
1149 (SI "x86_64_sext_operand")
1150 (DI "x86_64_sext_operand")])
1151
1152 ;; General sign/zero extend operand predicate for integer modes.
1153 (define_mode_attr general_szext_operand
1154 [(QI "general_operand")
1155 (HI "general_operand")
1156 (SI "x86_64_szext_general_operand")
1157 (DI "x86_64_szext_general_operand")])
1158
1159 (define_mode_attr nonmemory_szext_operand
1160 [(QI "nonmemory_operand")
1161 (HI "nonmemory_operand")
1162 (SI "x86_64_szext_nonmemory_operand")
1163 (DI "x86_64_szext_nonmemory_operand")])
1164
1165 ;; Immediate operand predicate for integer modes.
1166 (define_mode_attr immediate_operand
1167 [(QI "immediate_operand")
1168 (HI "immediate_operand")
1169 (SI "x86_64_immediate_operand")
1170 (DI "x86_64_immediate_operand")])
1171
1172 ;; Nonmemory operand predicate for integer modes.
1173 (define_mode_attr nonmemory_operand
1174 [(QI "nonmemory_operand")
1175 (HI "nonmemory_operand")
1176 (SI "x86_64_nonmemory_operand")
1177 (DI "x86_64_nonmemory_operand")])
1178
1179 ;; Operand predicate for shifts.
1180 (define_mode_attr shift_operand
1181 [(QI "nonimmediate_operand")
1182 (HI "nonimmediate_operand")
1183 (SI "nonimmediate_operand")
1184 (DI "shiftdi_operand")
1185 (TI "register_operand")])
1186
1187 ;; Operand predicate for shift argument.
1188 (define_mode_attr shift_immediate_operand
1189 [(QI "const_1_to_31_operand")
1190 (HI "const_1_to_31_operand")
1191 (SI "const_1_to_31_operand")
1192 (DI "const_1_to_63_operand")])
1193
1194 ;; Input operand predicate for arithmetic left shifts.
1195 (define_mode_attr ashl_input_operand
1196 [(QI "nonimmediate_operand")
1197 (HI "nonimmediate_operand")
1198 (SI "nonimmediate_operand")
1199 (DI "ashldi_input_operand")
1200 (TI "reg_or_pm1_operand")])
1201
1202 ;; SSE and x87 SFmode and DFmode floating point modes
1203 (define_mode_iterator MODEF [SF DF])
1204
1205 ;; All x87 floating point modes
1206 (define_mode_iterator X87MODEF [SF DF XF])
1207
1208 ;; All SSE floating point modes
1209 (define_mode_iterator SSEMODEF [SF DF TF])
1210 (define_mode_attr ssevecmodef [(SF "V4SF") (DF "V2DF") (TF "TF")])
1211
1212 ;; SSE instruction suffix for various modes
1213 (define_mode_attr ssemodesuffix
1214 [(SF "ss") (DF "sd")
1215 (V16SF "ps") (V8DF "pd")
1216 (V8SF "ps") (V4DF "pd")
1217 (V4SF "ps") (V2DF "pd")
1218 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1219 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1220 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1221
1222 ;; SSE vector suffix for floating point modes
1223 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1224
1225 ;; SSE vector mode corresponding to a scalar mode
1226 (define_mode_attr ssevecmode
1227 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1228 (define_mode_attr ssevecmodelower
1229 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1230
1231 ;; AVX512F vector mode corresponding to a scalar mode
1232 (define_mode_attr avx512fvecmode
1233 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1234
1235 ;; Instruction suffix for REX 64bit operators.
1236 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1237 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1238
1239 ;; This mode iterator allows :P to be used for patterns that operate on
1240 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1241 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1242
1243 ;; This mode iterator allows :W to be used for patterns that operate on
1244 ;; word_mode sized quantities.
1245 (define_mode_iterator W
1246 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1247
1248 ;; This mode iterator allows :PTR to be used for patterns that operate on
1249 ;; ptr_mode sized quantities.
1250 (define_mode_iterator PTR
1251 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1252 \f
1253 ;; Scheduling descriptions
1254
1255 (include "pentium.md")
1256 (include "ppro.md")
1257 (include "k6.md")
1258 (include "athlon.md")
1259 (include "bdver1.md")
1260 (include "bdver3.md")
1261 (include "btver2.md")
1262 (include "znver1.md")
1263 (include "geode.md")
1264 (include "atom.md")
1265 (include "slm.md")
1266 (include "glm.md")
1267 (include "core2.md")
1268 (include "haswell.md")
1269
1270 \f
1271 ;; Operand and operator predicates and constraints
1272
1273 (include "predicates.md")
1274 (include "constraints.md")
1275
1276 \f
1277 ;; Compare and branch/compare and store instructions.
1278
1279 (define_expand "cbranch<mode>4"
1280 [(set (reg:CC FLAGS_REG)
1281 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1282 (match_operand:SDWIM 2 "<general_operand>")))
1283 (set (pc) (if_then_else
1284 (match_operator 0 "ordered_comparison_operator"
1285 [(reg:CC FLAGS_REG) (const_int 0)])
1286 (label_ref (match_operand 3))
1287 (pc)))]
1288 ""
1289 {
1290 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1291 operands[1] = force_reg (<MODE>mode, operands[1]);
1292 ix86_expand_branch (GET_CODE (operands[0]),
1293 operands[1], operands[2], operands[3]);
1294 DONE;
1295 })
1296
1297 (define_expand "cstore<mode>4"
1298 [(set (reg:CC FLAGS_REG)
1299 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1300 (match_operand:SWIM 3 "<general_operand>")))
1301 (set (match_operand:QI 0 "register_operand")
1302 (match_operator 1 "ordered_comparison_operator"
1303 [(reg:CC FLAGS_REG) (const_int 0)]))]
1304 ""
1305 {
1306 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1307 operands[2] = force_reg (<MODE>mode, operands[2]);
1308 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1309 operands[2], operands[3]);
1310 DONE;
1311 })
1312
1313 (define_expand "@cmp<mode>_1"
1314 [(set (reg:CC FLAGS_REG)
1315 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1316 (match_operand:SWI48 1 "<general_operand>")))])
1317
1318 (define_mode_iterator SWI1248_AVX512BWDQ_64
1319 [(QI "TARGET_AVX512DQ") HI
1320 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1321
1322 (define_insn "*cmp<mode>_ccz_1"
1323 [(set (reg FLAGS_REG)
1324 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1325 "nonimmediate_operand" "<r>,?m<r>,$k")
1326 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1327 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1328 "@
1329 test{<imodesuffix>}\t%0, %0
1330 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1331 kortest<mskmodesuffix>\t%0, %0"
1332 [(set_attr "type" "test,icmp,msklog")
1333 (set_attr "length_immediate" "0,1,*")
1334 (set_attr "prefix" "*,*,vex")
1335 (set_attr "mode" "<MODE>")])
1336
1337 (define_insn "*cmp<mode>_ccno_1"
1338 [(set (reg FLAGS_REG)
1339 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1340 (match_operand:SWI 1 "const0_operand")))]
1341 "ix86_match_ccmode (insn, CCNOmode)"
1342 "@
1343 test{<imodesuffix>}\t%0, %0
1344 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1345 [(set_attr "type" "test,icmp")
1346 (set_attr "length_immediate" "0,1")
1347 (set_attr "mode" "<MODE>")])
1348
1349 (define_insn "*cmp<mode>_1"
1350 [(set (reg FLAGS_REG)
1351 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1352 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1353 "ix86_match_ccmode (insn, CCmode)"
1354 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1355 [(set_attr "type" "icmp")
1356 (set_attr "mode" "<MODE>")])
1357
1358 (define_insn "*cmp<mode>_minus_1"
1359 [(set (reg FLAGS_REG)
1360 (compare
1361 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1362 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1363 (const_int 0)))]
1364 "ix86_match_ccmode (insn, CCGOCmode)"
1365 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1366 [(set_attr "type" "icmp")
1367 (set_attr "mode" "<MODE>")])
1368
1369 (define_insn "*cmpqi_ext<mode>_1"
1370 [(set (reg FLAGS_REG)
1371 (compare
1372 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1373 (subreg:QI
1374 (zero_extract:SWI248
1375 (match_operand:SWI248 1 "register_operand" "Q,Q")
1376 (const_int 8)
1377 (const_int 8)) 0)))]
1378 "ix86_match_ccmode (insn, CCmode)"
1379 "cmp{b}\t{%h1, %0|%0, %h1}"
1380 [(set_attr "isa" "*,nox64")
1381 (set_attr "type" "icmp")
1382 (set_attr "mode" "QI")])
1383
1384 (define_insn "*cmpqi_ext<mode>_2"
1385 [(set (reg FLAGS_REG)
1386 (compare
1387 (subreg:QI
1388 (zero_extract:SWI248
1389 (match_operand:SWI248 0 "register_operand" "Q")
1390 (const_int 8)
1391 (const_int 8)) 0)
1392 (match_operand:QI 1 "const0_operand")))]
1393 "ix86_match_ccmode (insn, CCNOmode)"
1394 "test{b}\t%h0, %h0"
1395 [(set_attr "type" "test")
1396 (set_attr "length_immediate" "0")
1397 (set_attr "mode" "QI")])
1398
1399 (define_expand "cmpqi_ext_3"
1400 [(set (reg:CC FLAGS_REG)
1401 (compare:CC
1402 (subreg:QI
1403 (zero_extract:HI
1404 (match_operand:HI 0 "register_operand")
1405 (const_int 8)
1406 (const_int 8)) 0)
1407 (match_operand:QI 1 "const_int_operand")))])
1408
1409 (define_insn "*cmpqi_ext<mode>_3"
1410 [(set (reg FLAGS_REG)
1411 (compare
1412 (subreg:QI
1413 (zero_extract:SWI248
1414 (match_operand:SWI248 0 "register_operand" "Q,Q")
1415 (const_int 8)
1416 (const_int 8)) 0)
1417 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1418 "ix86_match_ccmode (insn, CCmode)"
1419 "cmp{b}\t{%1, %h0|%h0, %1}"
1420 [(set_attr "isa" "*,nox64")
1421 (set_attr "type" "icmp")
1422 (set_attr "mode" "QI")])
1423
1424 (define_insn "*cmpqi_ext<mode>_4"
1425 [(set (reg FLAGS_REG)
1426 (compare
1427 (subreg:QI
1428 (zero_extract:SWI248
1429 (match_operand:SWI248 0 "register_operand" "Q")
1430 (const_int 8)
1431 (const_int 8)) 0)
1432 (subreg:QI
1433 (zero_extract:SWI248
1434 (match_operand:SWI248 1 "register_operand" "Q")
1435 (const_int 8)
1436 (const_int 8)) 0)))]
1437 "ix86_match_ccmode (insn, CCmode)"
1438 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1439 [(set_attr "type" "icmp")
1440 (set_attr "mode" "QI")])
1441
1442 ;; These implement float point compares.
1443 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1444 ;; which would allow mix and match FP modes on the compares. Which is what
1445 ;; the old patterns did, but with many more of them.
1446
1447 (define_expand "cbranchxf4"
1448 [(set (reg:CC FLAGS_REG)
1449 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1450 (match_operand:XF 2 "nonmemory_operand")))
1451 (set (pc) (if_then_else
1452 (match_operator 0 "ix86_fp_comparison_operator"
1453 [(reg:CC FLAGS_REG)
1454 (const_int 0)])
1455 (label_ref (match_operand 3))
1456 (pc)))]
1457 "TARGET_80387"
1458 {
1459 ix86_expand_branch (GET_CODE (operands[0]),
1460 operands[1], operands[2], operands[3]);
1461 DONE;
1462 })
1463
1464 (define_expand "cstorexf4"
1465 [(set (reg:CC FLAGS_REG)
1466 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1467 (match_operand:XF 3 "nonmemory_operand")))
1468 (set (match_operand:QI 0 "register_operand")
1469 (match_operator 1 "ix86_fp_comparison_operator"
1470 [(reg:CC FLAGS_REG)
1471 (const_int 0)]))]
1472 "TARGET_80387"
1473 {
1474 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1475 operands[2], operands[3]);
1476 DONE;
1477 })
1478
1479 (define_expand "cbranch<mode>4"
1480 [(set (reg:CC FLAGS_REG)
1481 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1482 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1483 (set (pc) (if_then_else
1484 (match_operator 0 "ix86_fp_comparison_operator"
1485 [(reg:CC FLAGS_REG)
1486 (const_int 0)])
1487 (label_ref (match_operand 3))
1488 (pc)))]
1489 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1490 {
1491 ix86_expand_branch (GET_CODE (operands[0]),
1492 operands[1], operands[2], operands[3]);
1493 DONE;
1494 })
1495
1496 (define_expand "cstore<mode>4"
1497 [(set (reg:CC FLAGS_REG)
1498 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1499 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1500 (set (match_operand:QI 0 "register_operand")
1501 (match_operator 1 "ix86_fp_comparison_operator"
1502 [(reg:CC FLAGS_REG)
1503 (const_int 0)]))]
1504 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1505 {
1506 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1507 operands[2], operands[3]);
1508 DONE;
1509 })
1510
1511 (define_expand "cbranchcc4"
1512 [(set (pc) (if_then_else
1513 (match_operator 0 "comparison_operator"
1514 [(match_operand 1 "flags_reg_operand")
1515 (match_operand 2 "const0_operand")])
1516 (label_ref (match_operand 3))
1517 (pc)))]
1518 ""
1519 {
1520 ix86_expand_branch (GET_CODE (operands[0]),
1521 operands[1], operands[2], operands[3]);
1522 DONE;
1523 })
1524
1525 (define_expand "cstorecc4"
1526 [(set (match_operand:QI 0 "register_operand")
1527 (match_operator 1 "comparison_operator"
1528 [(match_operand 2 "flags_reg_operand")
1529 (match_operand 3 "const0_operand")]))]
1530 ""
1531 {
1532 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1533 operands[2], operands[3]);
1534 DONE;
1535 })
1536
1537 ;; FP compares, step 1:
1538 ;; Set the FP condition codes and move fpsr to ax.
1539
1540 ;; We may not use "#" to split and emit these
1541 ;; due to reg-stack pops killing fpsr.
1542
1543 (define_insn "*cmpxf_i387"
1544 [(set (match_operand:HI 0 "register_operand" "=a")
1545 (unspec:HI
1546 [(compare:CCFP
1547 (match_operand:XF 1 "register_operand" "f")
1548 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1549 UNSPEC_FNSTSW))]
1550 "TARGET_80387"
1551 "* return output_fp_compare (insn, operands, false, false);"
1552 [(set_attr "type" "multi")
1553 (set_attr "unit" "i387")
1554 (set_attr "mode" "XF")])
1555
1556 (define_insn "*cmp<mode>_i387"
1557 [(set (match_operand:HI 0 "register_operand" "=a")
1558 (unspec:HI
1559 [(compare:CCFP
1560 (match_operand:MODEF 1 "register_operand" "f")
1561 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1562 UNSPEC_FNSTSW))]
1563 "TARGET_80387"
1564 "* return output_fp_compare (insn, operands, false, false);"
1565 [(set_attr "type" "multi")
1566 (set_attr "unit" "i387")
1567 (set_attr "mode" "<MODE>")])
1568
1569 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1570 [(set (match_operand:HI 0 "register_operand" "=a")
1571 (unspec:HI
1572 [(compare:CCFP
1573 (match_operand:X87MODEF 1 "register_operand" "f")
1574 (float:X87MODEF
1575 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1576 UNSPEC_FNSTSW))]
1577 "TARGET_80387
1578 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1579 || optimize_function_for_size_p (cfun))"
1580 "* return output_fp_compare (insn, operands, false, false);"
1581 [(set_attr "type" "multi")
1582 (set_attr "unit" "i387")
1583 (set_attr "fp_int_src" "true")
1584 (set_attr "mode" "<SWI24:MODE>")])
1585
1586 (define_insn "*cmpu<mode>_i387"
1587 [(set (match_operand:HI 0 "register_operand" "=a")
1588 (unspec:HI
1589 [(unspec:CCFP
1590 [(compare:CCFP
1591 (match_operand:X87MODEF 1 "register_operand" "f")
1592 (match_operand:X87MODEF 2 "register_operand" "f"))]
1593 UNSPEC_NOTRAP)]
1594 UNSPEC_FNSTSW))]
1595 "TARGET_80387"
1596 "* return output_fp_compare (insn, operands, false, true);"
1597 [(set_attr "type" "multi")
1598 (set_attr "unit" "i387")
1599 (set_attr "mode" "<MODE>")])
1600
1601 ;; FP compares, step 2:
1602 ;; Get ax into flags, general case.
1603
1604 (define_insn "x86_sahf_1"
1605 [(set (reg:CC FLAGS_REG)
1606 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1607 UNSPEC_SAHF))]
1608 "TARGET_SAHF"
1609 {
1610 #ifndef HAVE_AS_IX86_SAHF
1611 if (TARGET_64BIT)
1612 return ASM_BYTE "0x9e";
1613 else
1614 #endif
1615 return "sahf";
1616 }
1617 [(set_attr "length" "1")
1618 (set_attr "athlon_decode" "vector")
1619 (set_attr "amdfam10_decode" "direct")
1620 (set_attr "bdver1_decode" "direct")
1621 (set_attr "mode" "SI")])
1622
1623 ;; Pentium Pro can do both steps in one go.
1624 ;; (these instructions set flags directly)
1625
1626 (define_subst_attr "unord" "unord_subst" "" "u")
1627 (define_subst_attr "unordered" "unord_subst" "false" "true")
1628
1629 (define_subst "unord_subst"
1630 [(set (match_operand:CCFP 0)
1631 (match_operand:CCFP 1))]
1632 ""
1633 [(set (match_dup 0)
1634 (unspec:CCFP
1635 [(match_dup 1)]
1636 UNSPEC_NOTRAP))])
1637
1638 (define_insn "*cmpi<unord>xf_i387"
1639 [(set (reg:CCFP FLAGS_REG)
1640 (compare:CCFP
1641 (match_operand:XF 0 "register_operand" "f")
1642 (match_operand:XF 1 "register_operand" "f")))]
1643 "TARGET_80387 && TARGET_CMOVE"
1644 "* return output_fp_compare (insn, operands, true, <unordered>);"
1645 [(set_attr "type" "fcmp")
1646 (set_attr "mode" "XF")
1647 (set_attr "athlon_decode" "vector")
1648 (set_attr "amdfam10_decode" "direct")
1649 (set_attr "bdver1_decode" "double")
1650 (set_attr "znver1_decode" "double")])
1651
1652 (define_insn "*cmpi<unord><MODEF:mode>"
1653 [(set (reg:CCFP FLAGS_REG)
1654 (compare:CCFP
1655 (match_operand:MODEF 0 "register_operand" "f,v")
1656 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1657 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1658 || (TARGET_80387 && TARGET_CMOVE)"
1659 "@
1660 * return output_fp_compare (insn, operands, true, <unordered>);
1661 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1662 [(set_attr "type" "fcmp,ssecomi")
1663 (set_attr "prefix" "orig,maybe_vex")
1664 (set_attr "mode" "<MODEF:MODE>")
1665 (set_attr "prefix_rep" "*,0")
1666 (set (attr "prefix_data16")
1667 (cond [(eq_attr "alternative" "0")
1668 (const_string "*")
1669 (eq_attr "mode" "DF")
1670 (const_string "1")
1671 ]
1672 (const_string "0")))
1673 (set_attr "athlon_decode" "vector")
1674 (set_attr "amdfam10_decode" "direct")
1675 (set_attr "bdver1_decode" "double")
1676 (set_attr "znver1_decode" "double")
1677 (set (attr "enabled")
1678 (if_then_else
1679 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1680 (if_then_else
1681 (eq_attr "alternative" "0")
1682 (symbol_ref "TARGET_MIX_SSE_I387")
1683 (symbol_ref "true"))
1684 (if_then_else
1685 (eq_attr "alternative" "0")
1686 (symbol_ref "true")
1687 (symbol_ref "false"))))])
1688 \f
1689 ;; Push/pop instructions.
1690
1691 (define_insn_and_split "*pushv1ti2"
1692 [(set (match_operand:V1TI 0 "push_operand" "=<")
1693 (match_operand:V1TI 1 "register_operand" "v"))]
1694 "TARGET_64BIT && TARGET_STV"
1695 "#"
1696 "&& reload_completed"
1697 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
1698 (set (match_dup 0) (match_dup 1))]
1699 {
1700 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
1701 /* Preserve memory attributes. */
1702 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
1703 }
1704 [(set_attr "type" "multi")
1705 (set_attr "mode" "TI")])
1706
1707 (define_insn "*push<mode>2"
1708 [(set (match_operand:DWI 0 "push_operand" "=<,<")
1709 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
1710 ""
1711 "#"
1712 [(set_attr "type" "multi")
1713 (set_attr "mode" "<MODE>")])
1714
1715 (define_split
1716 [(set (match_operand:DWI 0 "push_operand")
1717 (match_operand:DWI 1 "general_gr_operand"))]
1718 "reload_completed"
1719 [(const_int 0)]
1720 "ix86_split_long_move (operands); DONE;")
1721
1722 (define_insn "*pushdi2_rex64"
1723 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
1724 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
1725 "TARGET_64BIT"
1726 "@
1727 push{q}\t%1
1728 #
1729 #"
1730 [(set_attr "type" "push,multi,multi")
1731 (set_attr "mode" "DI")])
1732
1733 ;; Convert impossible pushes of immediate to existing instructions.
1734 ;; First try to get scratch register and go through it. In case this
1735 ;; fails, push sign extended lower part first and then overwrite
1736 ;; upper part by 32bit move.
1737
1738 (define_peephole2
1739 [(match_scratch:DI 2 "r")
1740 (set (match_operand:DI 0 "push_operand")
1741 (match_operand:DI 1 "immediate_operand"))]
1742 "TARGET_64BIT
1743 && !symbolic_operand (operands[1], DImode)
1744 && !x86_64_immediate_operand (operands[1], DImode)"
1745 [(set (match_dup 2) (match_dup 1))
1746 (set (match_dup 0) (match_dup 2))])
1747
1748 (define_split
1749 [(set (match_operand:DI 0 "push_operand")
1750 (match_operand:DI 1 "immediate_operand"))]
1751 "TARGET_64BIT && epilogue_completed
1752 && !symbolic_operand (operands[1], DImode)
1753 && !x86_64_immediate_operand (operands[1], DImode)"
1754 [(set (match_dup 0) (match_dup 1))
1755 (set (match_dup 2) (match_dup 3))]
1756 {
1757 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1758
1759 operands[1] = gen_lowpart (DImode, operands[2]);
1760 operands[2] = gen_rtx_MEM (SImode,
1761 plus_constant (Pmode, stack_pointer_rtx, 4));
1762 })
1763
1764 ;; For TARGET_64BIT we always round up to 8 bytes.
1765 (define_insn "*pushsi2_rex64"
1766 [(set (match_operand:SI 0 "push_operand" "=X,X")
1767 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
1768 "TARGET_64BIT"
1769 "@
1770 push{q}\t%q1
1771 #"
1772 [(set_attr "type" "push,multi")
1773 (set_attr "mode" "DI")])
1774
1775 (define_insn "*pushsi2"
1776 [(set (match_operand:SI 0 "push_operand" "=<,<")
1777 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
1778 "!TARGET_64BIT"
1779 "@
1780 push{l}\t%1
1781 #"
1782 [(set_attr "type" "push,multi")
1783 (set_attr "mode" "SI")])
1784
1785 (define_split
1786 [(set (match_operand:SWI48DWI 0 "push_operand")
1787 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
1788 "TARGET_SSE && reload_completed"
1789 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
1790 (set (match_dup 0) (match_dup 1))]
1791 {
1792 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
1793 /* Preserve memory attributes. */
1794 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
1795 })
1796
1797 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1798 ;; "push a byte/word". But actually we use push{l,q}, which has
1799 ;; the effect of rounding the amount pushed up to a word.
1800
1801 (define_insn "*push<mode>2"
1802 [(set (match_operand:SWI12 0 "push_operand" "=X")
1803 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1804 ""
1805 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
1806 [(set_attr "type" "push")
1807 (set (attr "mode")
1808 (if_then_else (match_test "TARGET_64BIT")
1809 (const_string "DI")
1810 (const_string "SI")))])
1811
1812 (define_insn "*push<mode>2_prologue"
1813 [(set (match_operand:W 0 "push_operand" "=<")
1814 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1815 (clobber (mem:BLK (scratch)))]
1816 ""
1817 "push{<imodesuffix>}\t%1"
1818 [(set_attr "type" "push")
1819 (set_attr "mode" "<MODE>")])
1820
1821 (define_insn "*pop<mode>1"
1822 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1823 (match_operand:W 1 "pop_operand" ">"))]
1824 ""
1825 "pop{<imodesuffix>}\t%0"
1826 [(set_attr "type" "pop")
1827 (set_attr "mode" "<MODE>")])
1828
1829 (define_insn "*pop<mode>1_epilogue"
1830 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1831 (match_operand:W 1 "pop_operand" ">"))
1832 (clobber (mem:BLK (scratch)))]
1833 ""
1834 "pop{<imodesuffix>}\t%0"
1835 [(set_attr "type" "pop")
1836 (set_attr "mode" "<MODE>")])
1837
1838 (define_insn "*pushfl<mode>2"
1839 [(set (match_operand:W 0 "push_operand" "=<")
1840 (match_operand:W 1 "flags_reg_operand"))]
1841 ""
1842 "pushf{<imodesuffix>}"
1843 [(set_attr "type" "push")
1844 (set_attr "mode" "<MODE>")])
1845
1846 (define_insn "*popfl<mode>1"
1847 [(set (match_operand:W 0 "flags_reg_operand")
1848 (match_operand:W 1 "pop_operand" ">"))]
1849 ""
1850 "popf{<imodesuffix>}"
1851 [(set_attr "type" "pop")
1852 (set_attr "mode" "<MODE>")])
1853
1854 \f
1855 ;; Reload patterns to support multi-word load/store
1856 ;; with non-offsetable address.
1857 (define_expand "reload_noff_store"
1858 [(parallel [(match_operand 0 "memory_operand" "=m")
1859 (match_operand 1 "register_operand" "r")
1860 (match_operand:DI 2 "register_operand" "=&r")])]
1861 "TARGET_64BIT"
1862 {
1863 rtx mem = operands[0];
1864 rtx addr = XEXP (mem, 0);
1865
1866 emit_move_insn (operands[2], addr);
1867 mem = replace_equiv_address_nv (mem, operands[2]);
1868
1869 emit_insn (gen_rtx_SET (mem, operands[1]));
1870 DONE;
1871 })
1872
1873 (define_expand "reload_noff_load"
1874 [(parallel [(match_operand 0 "register_operand" "=r")
1875 (match_operand 1 "memory_operand" "m")
1876 (match_operand:DI 2 "register_operand" "=r")])]
1877 "TARGET_64BIT"
1878 {
1879 rtx mem = operands[1];
1880 rtx addr = XEXP (mem, 0);
1881
1882 emit_move_insn (operands[2], addr);
1883 mem = replace_equiv_address_nv (mem, operands[2]);
1884
1885 emit_insn (gen_rtx_SET (operands[0], mem));
1886 DONE;
1887 })
1888
1889 ;; Move instructions.
1890
1891 (define_expand "movxi"
1892 [(set (match_operand:XI 0 "nonimmediate_operand")
1893 (match_operand:XI 1 "general_operand"))]
1894 "TARGET_AVX512F"
1895 "ix86_expand_vector_move (XImode, operands); DONE;")
1896
1897 (define_expand "movoi"
1898 [(set (match_operand:OI 0 "nonimmediate_operand")
1899 (match_operand:OI 1 "general_operand"))]
1900 "TARGET_AVX"
1901 "ix86_expand_vector_move (OImode, operands); DONE;")
1902
1903 (define_expand "movti"
1904 [(set (match_operand:TI 0 "nonimmediate_operand")
1905 (match_operand:TI 1 "general_operand"))]
1906 "TARGET_64BIT || TARGET_SSE"
1907 {
1908 if (TARGET_64BIT)
1909 ix86_expand_move (TImode, operands);
1910 else
1911 ix86_expand_vector_move (TImode, operands);
1912 DONE;
1913 })
1914
1915 ;; This expands to what emit_move_complex would generate if we didn't
1916 ;; have a movti pattern. Having this avoids problems with reload on
1917 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1918 ;; to have around all the time.
1919 (define_expand "movcdi"
1920 [(set (match_operand:CDI 0 "nonimmediate_operand")
1921 (match_operand:CDI 1 "general_operand"))]
1922 ""
1923 {
1924 if (push_operand (operands[0], CDImode))
1925 emit_move_complex_push (CDImode, operands[0], operands[1]);
1926 else
1927 emit_move_complex_parts (operands[0], operands[1]);
1928 DONE;
1929 })
1930
1931 (define_expand "mov<mode>"
1932 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1933 (match_operand:SWI1248x 1 "general_operand"))]
1934 ""
1935 "ix86_expand_move (<MODE>mode, operands); DONE;")
1936
1937 (define_insn "*mov<mode>_xor"
1938 [(set (match_operand:SWI48 0 "register_operand" "=r")
1939 (match_operand:SWI48 1 "const0_operand"))
1940 (clobber (reg:CC FLAGS_REG))]
1941 "reload_completed"
1942 "xor{l}\t%k0, %k0"
1943 [(set_attr "type" "alu1")
1944 (set_attr "mode" "SI")
1945 (set_attr "length_immediate" "0")])
1946
1947 (define_insn "*mov<mode>_or"
1948 [(set (match_operand:SWI48 0 "register_operand" "=r")
1949 (match_operand:SWI48 1 "constm1_operand"))
1950 (clobber (reg:CC FLAGS_REG))]
1951 "reload_completed"
1952 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1953 [(set_attr "type" "alu1")
1954 (set_attr "mode" "<MODE>")
1955 (set_attr "length_immediate" "1")])
1956
1957 (define_insn "*movxi_internal_avx512f"
1958 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
1959 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1960 "TARGET_AVX512F
1961 && (register_operand (operands[0], XImode)
1962 || register_operand (operands[1], XImode))"
1963 {
1964 switch (get_attr_type (insn))
1965 {
1966 case TYPE_SSELOG1:
1967 return standard_sse_constant_opcode (insn, operands);
1968
1969 case TYPE_SSEMOV:
1970 return ix86_output_ssemov (insn, operands);
1971
1972 default:
1973 gcc_unreachable ();
1974 }
1975 }
1976 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1977 (set_attr "prefix" "evex")
1978 (set_attr "mode" "XI")])
1979
1980 (define_insn "*movoi_internal_avx"
1981 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
1982 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1983 "TARGET_AVX
1984 && (register_operand (operands[0], OImode)
1985 || register_operand (operands[1], OImode))"
1986 {
1987 switch (get_attr_type (insn))
1988 {
1989 case TYPE_SSELOG1:
1990 return standard_sse_constant_opcode (insn, operands);
1991
1992 case TYPE_SSEMOV:
1993 return ix86_output_ssemov (insn, operands);
1994
1995 default:
1996 gcc_unreachable ();
1997 }
1998 }
1999 [(set_attr "isa" "*,avx2,*,*")
2000 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2001 (set_attr "prefix" "vex")
2002 (set_attr "mode" "OI")])
2003
2004 (define_insn "*movti_internal"
2005 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2006 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
2007 "(TARGET_64BIT
2008 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2009 || (TARGET_SSE
2010 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2011 && (register_operand (operands[0], TImode)
2012 || register_operand (operands[1], TImode)))"
2013 {
2014 switch (get_attr_type (insn))
2015 {
2016 case TYPE_MULTI:
2017 return "#";
2018
2019 case TYPE_SSELOG1:
2020 return standard_sse_constant_opcode (insn, operands);
2021
2022 case TYPE_SSEMOV:
2023 return ix86_output_ssemov (insn, operands);
2024
2025 default:
2026 gcc_unreachable ();
2027 }
2028 }
2029 [(set (attr "isa")
2030 (cond [(eq_attr "alternative" "0,1,6,7")
2031 (const_string "x64")
2032 (eq_attr "alternative" "3")
2033 (const_string "sse2")
2034 ]
2035 (const_string "*")))
2036 (set (attr "type")
2037 (cond [(eq_attr "alternative" "0,1,6,7")
2038 (const_string "multi")
2039 (eq_attr "alternative" "2,3")
2040 (const_string "sselog1")
2041 ]
2042 (const_string "ssemov")))
2043 (set (attr "prefix")
2044 (if_then_else (eq_attr "type" "sselog1,ssemov")
2045 (const_string "maybe_vex")
2046 (const_string "orig")))
2047 (set (attr "mode")
2048 (cond [(eq_attr "alternative" "0,1")
2049 (const_string "DI")
2050 (match_test "TARGET_AVX")
2051 (const_string "TI")
2052 (ior (not (match_test "TARGET_SSE2"))
2053 (match_test "optimize_function_for_size_p (cfun)"))
2054 (const_string "V4SF")
2055 (and (eq_attr "alternative" "5")
2056 (match_test "TARGET_SSE_TYPELESS_STORES"))
2057 (const_string "V4SF")
2058 ]
2059 (const_string "TI")))
2060 (set (attr "preferred_for_speed")
2061 (cond [(eq_attr "alternative" "6")
2062 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2063 (eq_attr "alternative" "7")
2064 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2065 ]
2066 (symbol_ref "true")))])
2067
2068 (define_split
2069 [(set (match_operand:TI 0 "sse_reg_operand")
2070 (match_operand:TI 1 "general_reg_operand"))]
2071 "TARGET_64BIT && TARGET_SSE4_1
2072 && reload_completed"
2073 [(set (match_dup 2)
2074 (vec_merge:V2DI
2075 (vec_duplicate:V2DI (match_dup 3))
2076 (match_dup 2)
2077 (const_int 2)))]
2078 {
2079 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2080 operands[3] = gen_highpart (DImode, operands[1]);
2081
2082 emit_move_insn (gen_lowpart (DImode, operands[0]),
2083 gen_lowpart (DImode, operands[1]));
2084 })
2085
2086 (define_insn "*movdi_internal"
2087 [(set (match_operand:DI 0 "nonimmediate_operand"
2088 "=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")
2089 (match_operand:DI 1 "general_operand"
2090 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,v,*Yd,r ,*v,r ,*x ,*y ,*r,*km,*k,*k,CBC"))]
2091 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2092 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2093 {
2094 switch (get_attr_type (insn))
2095 {
2096 case TYPE_MSKMOV:
2097 return "kmovq\t{%1, %0|%0, %1}";
2098
2099 case TYPE_MSKLOG:
2100 if (operands[1] == const0_rtx)
2101 return "kxorq\t%0, %0, %0";
2102 else if (operands[1] == constm1_rtx)
2103 return "kxnorq\t%0, %0, %0";
2104 gcc_unreachable ();
2105
2106 case TYPE_MULTI:
2107 return "#";
2108
2109 case TYPE_MMX:
2110 return "pxor\t%0, %0";
2111
2112 case TYPE_MMXMOV:
2113 /* Handle broken assemblers that require movd instead of movq. */
2114 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2115 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2116 return "movd\t{%1, %0|%0, %1}";
2117 return "movq\t{%1, %0|%0, %1}";
2118
2119 case TYPE_SSELOG1:
2120 return standard_sse_constant_opcode (insn, operands);
2121
2122 case TYPE_SSEMOV:
2123 return ix86_output_ssemov (insn, operands);
2124
2125 case TYPE_SSECVT:
2126 if (SSE_REG_P (operands[0]))
2127 return "movq2dq\t{%1, %0|%0, %1}";
2128 else
2129 return "movdq2q\t{%1, %0|%0, %1}";
2130
2131 case TYPE_LEA:
2132 return "lea{q}\t{%E1, %0|%0, %E1}";
2133
2134 case TYPE_IMOV:
2135 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2136 if (get_attr_mode (insn) == MODE_SI)
2137 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2138 else if (which_alternative == 4)
2139 return "movabs{q}\t{%1, %0|%0, %1}";
2140 else if (ix86_use_lea_for_mov (insn, operands))
2141 return "lea{q}\t{%E1, %0|%0, %E1}";
2142 else
2143 return "mov{q}\t{%1, %0|%0, %1}";
2144
2145 default:
2146 gcc_unreachable ();
2147 }
2148 }
2149 [(set (attr "isa")
2150 (cond [(eq_attr "alternative" "0,1,17,18")
2151 (const_string "nox64")
2152 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2153 (const_string "x64")
2154 (eq_attr "alternative" "19,20")
2155 (const_string "x64_sse2")
2156 (eq_attr "alternative" "21,22")
2157 (const_string "sse2")
2158 ]
2159 (const_string "*")))
2160 (set (attr "type")
2161 (cond [(eq_attr "alternative" "0,1,17,18")
2162 (const_string "multi")
2163 (eq_attr "alternative" "6")
2164 (const_string "mmx")
2165 (eq_attr "alternative" "7,8,9,10,11")
2166 (const_string "mmxmov")
2167 (eq_attr "alternative" "12")
2168 (const_string "sselog1")
2169 (eq_attr "alternative" "13,14,15,16,19,20")
2170 (const_string "ssemov")
2171 (eq_attr "alternative" "21,22")
2172 (const_string "ssecvt")
2173 (eq_attr "alternative" "23,24,25,26")
2174 (const_string "mskmov")
2175 (eq_attr "alternative" "27")
2176 (const_string "msklog")
2177 (and (match_operand 0 "register_operand")
2178 (match_operand 1 "pic_32bit_operand"))
2179 (const_string "lea")
2180 ]
2181 (const_string "imov")))
2182 (set (attr "modrm")
2183 (if_then_else
2184 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2185 (const_string "0")
2186 (const_string "*")))
2187 (set (attr "length_immediate")
2188 (if_then_else
2189 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2190 (const_string "8")
2191 (const_string "*")))
2192 (set (attr "prefix_rex")
2193 (if_then_else
2194 (eq_attr "alternative" "10,11,19,20")
2195 (const_string "1")
2196 (const_string "*")))
2197 (set (attr "prefix")
2198 (if_then_else (eq_attr "type" "sselog1,ssemov")
2199 (const_string "maybe_vex")
2200 (const_string "orig")))
2201 (set (attr "prefix_data16")
2202 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2203 (const_string "1")
2204 (const_string "*")))
2205 (set (attr "mode")
2206 (cond [(eq_attr "alternative" "2")
2207 (const_string "SI")
2208 (eq_attr "alternative" "12,13")
2209 (cond [(match_test "TARGET_AVX")
2210 (const_string "TI")
2211 (ior (not (match_test "TARGET_SSE2"))
2212 (match_test "optimize_function_for_size_p (cfun)"))
2213 (const_string "V4SF")
2214 ]
2215 (const_string "TI"))
2216
2217 (and (eq_attr "alternative" "14,15,16")
2218 (not (match_test "TARGET_SSE2")))
2219 (const_string "V2SF")
2220 ]
2221 (const_string "DI")))
2222 (set (attr "preferred_for_speed")
2223 (cond [(eq_attr "alternative" "10,17,19")
2224 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2225 (eq_attr "alternative" "11,18,20")
2226 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2227 ]
2228 (symbol_ref "true")))
2229 (set (attr "enabled")
2230 (cond [(eq_attr "alternative" "15")
2231 (if_then_else
2232 (match_test "TARGET_STV && TARGET_SSE2")
2233 (symbol_ref "false")
2234 (const_string "*"))
2235 (eq_attr "alternative" "16")
2236 (if_then_else
2237 (match_test "TARGET_STV && TARGET_SSE2")
2238 (symbol_ref "true")
2239 (symbol_ref "false"))
2240 ]
2241 (const_string "*")))])
2242
2243 (define_split
2244 [(set (match_operand:<DWI> 0 "general_reg_operand")
2245 (match_operand:<DWI> 1 "sse_reg_operand"))]
2246 "TARGET_SSE4_1
2247 && reload_completed"
2248 [(set (match_dup 2)
2249 (vec_select:DWIH
2250 (match_dup 3)
2251 (parallel [(const_int 1)])))]
2252 {
2253 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2254 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2255
2256 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2257 gen_lowpart (<MODE>mode, operands[1]));
2258 })
2259
2260 (define_split
2261 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2262 (match_operand:DWI 1 "general_gr_operand"))]
2263 "reload_completed"
2264 [(const_int 0)]
2265 "ix86_split_long_move (operands); DONE;")
2266
2267 (define_split
2268 [(set (match_operand:DI 0 "sse_reg_operand")
2269 (match_operand:DI 1 "general_reg_operand"))]
2270 "!TARGET_64BIT && TARGET_SSE4_1
2271 && reload_completed"
2272 [(set (match_dup 2)
2273 (vec_merge:V4SI
2274 (vec_duplicate:V4SI (match_dup 3))
2275 (match_dup 2)
2276 (const_int 2)))]
2277 {
2278 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2279 operands[3] = gen_highpart (SImode, operands[1]);
2280
2281 emit_move_insn (gen_lowpart (SImode, operands[0]),
2282 gen_lowpart (SImode, operands[1]));
2283 })
2284
2285 ;; movabsq $0x0012345678000000, %rax is longer
2286 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2287 (define_peephole2
2288 [(set (match_operand:DI 0 "register_operand")
2289 (match_operand:DI 1 "const_int_operand"))]
2290 "TARGET_64BIT
2291 && optimize_insn_for_size_p ()
2292 && LEGACY_INT_REG_P (operands[0])
2293 && !x86_64_immediate_operand (operands[1], DImode)
2294 && !x86_64_zext_immediate_operand (operands[1], DImode)
2295 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2296 & ~(HOST_WIDE_INT) 0xffffffff)
2297 && peep2_regno_dead_p (0, FLAGS_REG)"
2298 [(set (match_dup 0) (match_dup 1))
2299 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2300 (clobber (reg:CC FLAGS_REG))])]
2301 {
2302 int shift = ctz_hwi (UINTVAL (operands[1]));
2303 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2304 operands[2] = gen_int_mode (shift, QImode);
2305 })
2306
2307 (define_insn "*movsi_internal"
2308 [(set (match_operand:SI 0 "nonimmediate_operand"
2309 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k")
2310 (match_operand:SI 1 "general_operand"
2311 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k ,CBC"))]
2312 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2313 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2314 {
2315 switch (get_attr_type (insn))
2316 {
2317 case TYPE_SSELOG1:
2318 return standard_sse_constant_opcode (insn, operands);
2319
2320 case TYPE_MSKMOV:
2321 return "kmovd\t{%1, %0|%0, %1}";
2322
2323 case TYPE_MSKLOG:
2324 if (operands[1] == const0_rtx)
2325 return "kxord\t%0, %0, %0";
2326 else if (operands[1] == constm1_rtx)
2327 return "kxnord\t%0, %0, %0";
2328 gcc_unreachable ();
2329
2330 case TYPE_SSEMOV:
2331 return ix86_output_ssemov (insn, operands);
2332
2333 case TYPE_MMX:
2334 return "pxor\t%0, %0";
2335
2336 case TYPE_MMXMOV:
2337 switch (get_attr_mode (insn))
2338 {
2339 case MODE_DI:
2340 return "movq\t{%1, %0|%0, %1}";
2341 case MODE_SI:
2342 return "movd\t{%1, %0|%0, %1}";
2343
2344 default:
2345 gcc_unreachable ();
2346 }
2347
2348 case TYPE_LEA:
2349 return "lea{l}\t{%E1, %0|%0, %E1}";
2350
2351 case TYPE_IMOV:
2352 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2353 if (ix86_use_lea_for_mov (insn, operands))
2354 return "lea{l}\t{%E1, %0|%0, %E1}";
2355 else
2356 return "mov{l}\t{%1, %0|%0, %1}";
2357
2358 default:
2359 gcc_unreachable ();
2360 }
2361 }
2362 [(set (attr "isa")
2363 (cond [(eq_attr "alternative" "12,13")
2364 (const_string "sse2")
2365 ]
2366 (const_string "*")))
2367 (set (attr "type")
2368 (cond [(eq_attr "alternative" "2")
2369 (const_string "mmx")
2370 (eq_attr "alternative" "3,4,5,6,7")
2371 (const_string "mmxmov")
2372 (eq_attr "alternative" "8")
2373 (const_string "sselog1")
2374 (eq_attr "alternative" "9,10,11,12,13")
2375 (const_string "ssemov")
2376 (eq_attr "alternative" "14,15,16")
2377 (const_string "mskmov")
2378 (eq_attr "alternative" "17")
2379 (const_string "msklog")
2380 (and (match_operand 0 "register_operand")
2381 (match_operand 1 "pic_32bit_operand"))
2382 (const_string "lea")
2383 ]
2384 (const_string "imov")))
2385 (set (attr "prefix")
2386 (if_then_else (eq_attr "type" "sselog1,ssemov")
2387 (const_string "maybe_vex")
2388 (const_string "orig")))
2389 (set (attr "prefix_data16")
2390 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2391 (const_string "1")
2392 (const_string "*")))
2393 (set (attr "mode")
2394 (cond [(eq_attr "alternative" "2,3")
2395 (const_string "DI")
2396 (eq_attr "alternative" "8,9")
2397 (cond [(match_test "TARGET_AVX")
2398 (const_string "TI")
2399 (ior (not (match_test "TARGET_SSE2"))
2400 (match_test "optimize_function_for_size_p (cfun)"))
2401 (const_string "V4SF")
2402 ]
2403 (const_string "TI"))
2404
2405 (and (eq_attr "alternative" "10,11")
2406 (not (match_test "TARGET_SSE2")))
2407 (const_string "SF")
2408 ]
2409 (const_string "SI")))
2410 (set (attr "preferred_for_speed")
2411 (cond [(eq_attr "alternative" "6,12")
2412 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2413 (eq_attr "alternative" "7,13")
2414 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2415 ]
2416 (symbol_ref "true")))])
2417
2418 (define_insn "*movhi_internal"
2419 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,*k,*k ,*r,*m,*k")
2420 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,*r,*km,*k,*k,CBC"))]
2421 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2422 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2423
2424 {
2425 switch (get_attr_type (insn))
2426 {
2427 case TYPE_IMOVX:
2428 /* movzwl is faster than movw on p2 due to partial word stalls,
2429 though not as fast as an aligned movl. */
2430 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2431
2432 case TYPE_MSKMOV:
2433 switch (which_alternative)
2434 {
2435 case 4:
2436 return "kmovw\t{%k1, %0|%0, %k1}";
2437 case 6:
2438 return "kmovw\t{%1, %k0|%k0, %1}";
2439 case 5:
2440 case 7:
2441 return "kmovw\t{%1, %0|%0, %1}";
2442 default:
2443 gcc_unreachable ();
2444 }
2445
2446 case TYPE_MSKLOG:
2447 if (operands[1] == const0_rtx)
2448 return "kxorw\t%0, %0, %0";
2449 else if (operands[1] == constm1_rtx)
2450 return "kxnorw\t%0, %0, %0";
2451 gcc_unreachable ();
2452
2453 default:
2454 if (get_attr_mode (insn) == MODE_SI)
2455 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2456 else
2457 return "mov{w}\t{%1, %0|%0, %1}";
2458 }
2459 }
2460 [(set (attr "type")
2461 (cond [(eq_attr "alternative" "4,5,6,7")
2462 (const_string "mskmov")
2463 (eq_attr "alternative" "8")
2464 (const_string "msklog")
2465 (match_test "optimize_function_for_size_p (cfun)")
2466 (const_string "imov")
2467 (and (eq_attr "alternative" "0")
2468 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2469 (not (match_test "TARGET_HIMODE_MATH"))))
2470 (const_string "imov")
2471 (and (eq_attr "alternative" "1,2")
2472 (match_operand:HI 1 "aligned_operand"))
2473 (const_string "imov")
2474 (and (match_test "TARGET_MOVX")
2475 (eq_attr "alternative" "0,2"))
2476 (const_string "imovx")
2477 ]
2478 (const_string "imov")))
2479 (set (attr "prefix")
2480 (if_then_else (eq_attr "alternative" "4,5,6,7,8")
2481 (const_string "vex")
2482 (const_string "orig")))
2483 (set (attr "mode")
2484 (cond [(eq_attr "type" "imovx")
2485 (const_string "SI")
2486 (and (eq_attr "alternative" "1,2")
2487 (match_operand:HI 1 "aligned_operand"))
2488 (const_string "SI")
2489 (and (eq_attr "alternative" "0")
2490 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2491 (not (match_test "TARGET_HIMODE_MATH"))))
2492 (const_string "SI")
2493 ]
2494 (const_string "HI")))])
2495
2496 ;; Situation is quite tricky about when to choose full sized (SImode) move
2497 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2498 ;; partial register dependency machines (such as AMD Athlon), where QImode
2499 ;; moves issue extra dependency and for partial register stalls machines
2500 ;; that don't use QImode patterns (and QImode move cause stall on the next
2501 ;; instruction).
2502 ;;
2503 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2504 ;; register stall machines with, where we use QImode instructions, since
2505 ;; partial register stall can be caused there. Then we use movzx.
2506
2507 (define_insn "*movqi_internal"
2508 [(set (match_operand:QI 0 "nonimmediate_operand"
2509 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
2510 (match_operand:QI 1 "general_operand"
2511 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
2512 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2513 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2514
2515 {
2516 char buf[128];
2517 const char *ops;
2518 const char *suffix;
2519
2520 switch (get_attr_type (insn))
2521 {
2522 case TYPE_IMOVX:
2523 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2524 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2525
2526 case TYPE_MSKMOV:
2527 switch (which_alternative)
2528 {
2529 case 9:
2530 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2531 break;
2532 case 11:
2533 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2534 break;
2535 case 12:
2536 case 13:
2537 gcc_assert (TARGET_AVX512DQ);
2538 /* FALLTHRU */
2539 case 10:
2540 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2541 break;
2542 default:
2543 gcc_unreachable ();
2544 }
2545
2546 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2547
2548 snprintf (buf, sizeof (buf), ops, suffix);
2549 output_asm_insn (buf, operands);
2550 return "";
2551
2552 case TYPE_MSKLOG:
2553 if (operands[1] == const0_rtx)
2554 {
2555 if (get_attr_mode (insn) == MODE_HI)
2556 return "kxorw\t%0, %0, %0";
2557 else
2558 return "kxorb\t%0, %0, %0";
2559 }
2560 else if (operands[1] == constm1_rtx)
2561 {
2562 gcc_assert (TARGET_AVX512DQ);
2563 return "kxnorb\t%0, %0, %0";
2564 }
2565 gcc_unreachable ();
2566
2567 default:
2568 if (get_attr_mode (insn) == MODE_SI)
2569 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2570 else
2571 return "mov{b}\t{%1, %0|%0, %1}";
2572 }
2573 }
2574 [(set (attr "isa")
2575 (cond [(eq_attr "alternative" "1,2")
2576 (const_string "x64")
2577 (eq_attr "alternative" "12,13,15")
2578 (const_string "avx512dq")
2579 ]
2580 (const_string "*")))
2581 (set (attr "type")
2582 (cond [(eq_attr "alternative" "9,10,11,12,13")
2583 (const_string "mskmov")
2584 (eq_attr "alternative" "14,15")
2585 (const_string "msklog")
2586 (and (eq_attr "alternative" "7")
2587 (not (match_operand:QI 1 "aligned_operand")))
2588 (const_string "imovx")
2589 (match_test "optimize_function_for_size_p (cfun)")
2590 (const_string "imov")
2591 (and (eq_attr "alternative" "5")
2592 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2593 (not (match_test "TARGET_QIMODE_MATH"))))
2594 (const_string "imov")
2595 (eq_attr "alternative" "5,7")
2596 (const_string "imovx")
2597 (and (match_test "TARGET_MOVX")
2598 (eq_attr "alternative" "4"))
2599 (const_string "imovx")
2600 ]
2601 (const_string "imov")))
2602 (set (attr "prefix")
2603 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
2604 (const_string "vex")
2605 (const_string "orig")))
2606 (set (attr "mode")
2607 (cond [(eq_attr "alternative" "5,6,7")
2608 (const_string "SI")
2609 (eq_attr "alternative" "8")
2610 (const_string "QI")
2611 (and (eq_attr "alternative" "9,10,11,14")
2612 (not (match_test "TARGET_AVX512DQ")))
2613 (const_string "HI")
2614 (eq_attr "type" "imovx")
2615 (const_string "SI")
2616 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2617 ;; ones.
2618 (and (eq_attr "type" "imov")
2619 (and (eq_attr "alternative" "3")
2620 (match_test "optimize_function_for_size_p (cfun)")))
2621 (const_string "QI")
2622 ;; For -Os, movl where one or both operands are NON_Q_REGS
2623 ;; and both are LEGACY_REGS is shorter than movb.
2624 ;; Otherwise movb and movl sizes are the same, so decide purely
2625 ;; based on speed factors.
2626 (and (eq_attr "type" "imov")
2627 (and (eq_attr "alternative" "1")
2628 (match_test "optimize_function_for_size_p (cfun)")))
2629 (const_string "SI")
2630 (and (eq_attr "type" "imov")
2631 (and (eq_attr "alternative" "0,1,2,3")
2632 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2633 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2634 (const_string "SI")
2635 ;; Avoid partial register stalls when not using QImode arithmetic
2636 (and (eq_attr "type" "imov")
2637 (and (eq_attr "alternative" "0,1,2,3")
2638 (and (match_test "TARGET_PARTIAL_REG_STALL")
2639 (not (match_test "TARGET_QIMODE_MATH")))))
2640 (const_string "SI")
2641 ]
2642 (const_string "QI")))])
2643
2644 /* Reload dislikes loading 0/-1 directly into mask registers.
2645 Try to tidy things up here. */
2646 (define_peephole2
2647 [(set (match_operand:SWI 0 "general_reg_operand")
2648 (match_operand:SWI 1 "immediate_operand"))
2649 (set (match_operand:SWI 2 "mask_reg_operand")
2650 (match_dup 0))]
2651 "peep2_reg_dead_p (2, operands[0])
2652 && (const0_operand (operands[1], <MODE>mode)
2653 || (constm1_operand (operands[1], <MODE>mode)
2654 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
2655 [(set (match_dup 2) (match_dup 1))])
2656
2657 ;; Stores and loads of ax to arbitrary constant address.
2658 ;; We fake an second form of instruction to force reload to load address
2659 ;; into register when rax is not available
2660 (define_insn "*movabs<mode>_1"
2661 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2662 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2663 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2664 {
2665 /* Recover the full memory rtx. */
2666 operands[0] = SET_DEST (PATTERN (insn));
2667 switch (which_alternative)
2668 {
2669 case 0:
2670 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2671 case 1:
2672 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2673 default:
2674 gcc_unreachable ();
2675 }
2676 }
2677 [(set_attr "type" "imov")
2678 (set_attr "modrm" "0,*")
2679 (set_attr "length_address" "8,0")
2680 (set_attr "length_immediate" "0,*")
2681 (set_attr "memory" "store")
2682 (set_attr "mode" "<MODE>")])
2683
2684 (define_insn "*movabs<mode>_2"
2685 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2686 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2687 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2688 {
2689 /* Recover the full memory rtx. */
2690 operands[1] = SET_SRC (PATTERN (insn));
2691 switch (which_alternative)
2692 {
2693 case 0:
2694 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2695 case 1:
2696 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2697 default:
2698 gcc_unreachable ();
2699 }
2700 }
2701 [(set_attr "type" "imov")
2702 (set_attr "modrm" "0,*")
2703 (set_attr "length_address" "8,0")
2704 (set_attr "length_immediate" "0")
2705 (set_attr "memory" "load")
2706 (set_attr "mode" "<MODE>")])
2707
2708 (define_insn "*swap<mode>"
2709 [(set (match_operand:SWI48 0 "register_operand" "+r")
2710 (match_operand:SWI48 1 "register_operand" "+r"))
2711 (set (match_dup 1)
2712 (match_dup 0))]
2713 ""
2714 "xchg{<imodesuffix>}\t%1, %0"
2715 [(set_attr "type" "imov")
2716 (set_attr "mode" "<MODE>")
2717 (set_attr "pent_pair" "np")
2718 (set_attr "athlon_decode" "vector")
2719 (set_attr "amdfam10_decode" "double")
2720 (set_attr "bdver1_decode" "double")])
2721
2722 (define_insn "*swap<mode>"
2723 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2724 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2725 (set (match_dup 1)
2726 (match_dup 0))]
2727 ""
2728 "@
2729 xchg{<imodesuffix>}\t%1, %0
2730 xchg{l}\t%k1, %k0"
2731 [(set_attr "type" "imov")
2732 (set_attr "mode" "<MODE>,SI")
2733 (set (attr "preferred_for_size")
2734 (cond [(eq_attr "alternative" "0")
2735 (symbol_ref "false")]
2736 (symbol_ref "true")))
2737 ;; Potential partial reg stall on alternative 1.
2738 (set (attr "preferred_for_speed")
2739 (cond [(eq_attr "alternative" "1")
2740 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2741 (symbol_ref "true")))
2742 (set_attr "pent_pair" "np")
2743 (set_attr "athlon_decode" "vector")
2744 (set_attr "amdfam10_decode" "double")
2745 (set_attr "bdver1_decode" "double")])
2746
2747 (define_peephole2
2748 [(set (match_operand:SWI 0 "general_reg_operand")
2749 (match_operand:SWI 1 "general_reg_operand"))
2750 (set (match_dup 1)
2751 (match_operand:SWI 2 "general_reg_operand"))
2752 (set (match_dup 2) (match_dup 0))]
2753 "peep2_reg_dead_p (3, operands[0])
2754 && optimize_insn_for_size_p ()"
2755 [(parallel [(set (match_dup 1) (match_dup 2))
2756 (set (match_dup 2) (match_dup 1))])])
2757
2758 (define_expand "movstrict<mode>"
2759 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
2760 (match_operand:SWI12 1 "general_operand"))]
2761 ""
2762 {
2763 gcc_assert (SUBREG_P (operands[0]));
2764 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2765 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
2766 FAIL;
2767 })
2768
2769 (define_insn "*movstrict<mode>_1"
2770 [(set (strict_low_part
2771 (match_operand:SWI12 0 "register_operand" "+<r>"))
2772 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
2773 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2774 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2775 [(set_attr "type" "imov")
2776 (set_attr "mode" "<MODE>")])
2777
2778 (define_insn "*movstrict<mode>_xor"
2779 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2780 (match_operand:SWI12 1 "const0_operand"))
2781 (clobber (reg:CC FLAGS_REG))]
2782 "reload_completed"
2783 "xor{<imodesuffix>}\t%0, %0"
2784 [(set_attr "type" "alu1")
2785 (set_attr "mode" "<MODE>")
2786 (set_attr "length_immediate" "0")])
2787
2788 (define_expand "extv<mode>"
2789 [(set (match_operand:SWI24 0 "register_operand")
2790 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2791 (match_operand:SI 2 "const_int_operand")
2792 (match_operand:SI 3 "const_int_operand")))]
2793 ""
2794 {
2795 /* Handle extractions from %ah et al. */
2796 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2797 FAIL;
2798
2799 unsigned int regno = reg_or_subregno (operands[1]);
2800
2801 /* Be careful to expand only with registers having upper parts. */
2802 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2803 operands[1] = copy_to_reg (operands[1]);
2804 })
2805
2806 (define_insn "*extv<mode>"
2807 [(set (match_operand:SWI24 0 "register_operand" "=R")
2808 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand" "Q")
2809 (const_int 8)
2810 (const_int 8)))]
2811 ""
2812 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2813 [(set_attr "type" "imovx")
2814 (set_attr "mode" "SI")])
2815
2816 (define_expand "extzv<mode>"
2817 [(set (match_operand:SWI248 0 "register_operand")
2818 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2819 (match_operand:SI 2 "const_int_operand")
2820 (match_operand:SI 3 "const_int_operand")))]
2821 ""
2822 {
2823 if (ix86_expand_pextr (operands))
2824 DONE;
2825
2826 /* Handle extractions from %ah et al. */
2827 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2828 FAIL;
2829
2830 unsigned int regno = reg_or_subregno (operands[1]);
2831
2832 /* Be careful to expand only with registers having upper parts. */
2833 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2834 operands[1] = copy_to_reg (operands[1]);
2835 })
2836
2837 (define_insn "*extzvqi_mem_rex64"
2838 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2839 (subreg:QI
2840 (zero_extract:SWI248
2841 (match_operand:SWI248 1 "register_operand" "Q")
2842 (const_int 8)
2843 (const_int 8)) 0))]
2844 "TARGET_64BIT && reload_completed"
2845 "mov{b}\t{%h1, %0|%0, %h1}"
2846 [(set_attr "type" "imov")
2847 (set_attr "mode" "QI")])
2848
2849 (define_insn "*extzv<mode>"
2850 [(set (match_operand:SWI248 0 "register_operand" "=R")
2851 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand" "Q")
2852 (const_int 8)
2853 (const_int 8)))]
2854 ""
2855 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2856 [(set_attr "type" "imovx")
2857 (set_attr "mode" "SI")])
2858
2859 (define_insn "*extzvqi"
2860 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2861 (subreg:QI
2862 (zero_extract:SWI248
2863 (match_operand:SWI248 1 "register_operand" "Q,Q,Q")
2864 (const_int 8)
2865 (const_int 8)) 0))]
2866 ""
2867 {
2868 switch (get_attr_type (insn))
2869 {
2870 case TYPE_IMOVX:
2871 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2872 default:
2873 return "mov{b}\t{%h1, %0|%0, %h1}";
2874 }
2875 }
2876 [(set_attr "isa" "*,*,nox64")
2877 (set (attr "type")
2878 (if_then_else (and (match_operand:QI 0 "register_operand")
2879 (ior (not (match_operand:QI 0 "QIreg_operand"))
2880 (match_test "TARGET_MOVX")))
2881 (const_string "imovx")
2882 (const_string "imov")))
2883 (set (attr "mode")
2884 (if_then_else (eq_attr "type" "imovx")
2885 (const_string "SI")
2886 (const_string "QI")))])
2887
2888 (define_peephole2
2889 [(set (match_operand:QI 0 "register_operand")
2890 (subreg:QI
2891 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2892 (const_int 8)
2893 (const_int 8)) 0))
2894 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2895 "TARGET_64BIT
2896 && peep2_reg_dead_p (2, operands[0])"
2897 [(set (match_dup 2)
2898 (subreg:QI
2899 (zero_extract:SWI248 (match_dup 1)
2900 (const_int 8)
2901 (const_int 8)) 0))])
2902
2903 (define_expand "insv<mode>"
2904 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2905 (match_operand:SI 1 "const_int_operand")
2906 (match_operand:SI 2 "const_int_operand"))
2907 (match_operand:SWI248 3 "register_operand"))]
2908 ""
2909 {
2910 rtx dst;
2911
2912 if (ix86_expand_pinsr (operands))
2913 DONE;
2914
2915 /* Handle insertions to %ah et al. */
2916 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2917 FAIL;
2918
2919 unsigned int regno = reg_or_subregno (operands[0]);
2920
2921 /* Be careful to expand only with registers having upper parts. */
2922 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2923 dst = copy_to_reg (operands[0]);
2924 else
2925 dst = operands[0];
2926
2927 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
2928
2929 /* Fix up the destination if needed. */
2930 if (dst != operands[0])
2931 emit_move_insn (operands[0], dst);
2932
2933 DONE;
2934 })
2935
2936 (define_insn "*insvqi_1_mem_rex64"
2937 [(set (zero_extract:SWI248
2938 (match_operand:SWI248 0 "register_operand" "+Q")
2939 (const_int 8)
2940 (const_int 8))
2941 (subreg:SWI248
2942 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2943 "TARGET_64BIT && reload_completed"
2944 "mov{b}\t{%1, %h0|%h0, %1}"
2945 [(set_attr "type" "imov")
2946 (set_attr "mode" "QI")])
2947
2948 (define_insn "@insv<mode>_1"
2949 [(set (zero_extract:SWI248
2950 (match_operand:SWI248 0 "register_operand" "+Q,Q")
2951 (const_int 8)
2952 (const_int 8))
2953 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2954 ""
2955 {
2956 if (CONST_INT_P (operands[1]))
2957 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2958 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2959 }
2960 [(set_attr "isa" "*,nox64")
2961 (set_attr "type" "imov")
2962 (set_attr "mode" "QI")])
2963
2964 (define_insn "*insvqi_1"
2965 [(set (zero_extract:SWI248
2966 (match_operand:SWI248 0 "register_operand" "+Q,Q")
2967 (const_int 8)
2968 (const_int 8))
2969 (subreg:SWI248
2970 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
2971 ""
2972 "mov{b}\t{%1, %h0|%h0, %1}"
2973 [(set_attr "isa" "*,nox64")
2974 (set_attr "type" "imov")
2975 (set_attr "mode" "QI")])
2976
2977 (define_peephole2
2978 [(set (match_operand:QI 0 "register_operand")
2979 (match_operand:QI 1 "norex_memory_operand"))
2980 (set (zero_extract:SWI248 (match_operand:SWI248 2 "register_operand")
2981 (const_int 8)
2982 (const_int 8))
2983 (subreg:SWI248 (match_dup 0) 0))]
2984 "TARGET_64BIT
2985 && peep2_reg_dead_p (2, operands[0])"
2986 [(set (zero_extract:SWI248 (match_dup 2)
2987 (const_int 8)
2988 (const_int 8))
2989 (subreg:SWI248 (match_dup 1) 0))])
2990
2991 (define_code_iterator any_extract [sign_extract zero_extract])
2992
2993 (define_insn "*insvqi_2"
2994 [(set (zero_extract:SWI248
2995 (match_operand:SWI248 0 "register_operand" "+Q")
2996 (const_int 8)
2997 (const_int 8))
2998 (any_extract:SWI248
2999 (match_operand:SWI248 1 "register_operand" "Q")
3000 (const_int 8)
3001 (const_int 8)))]
3002 ""
3003 "mov{b}\t{%h1, %h0|%h0, %h1}"
3004 [(set_attr "type" "imov")
3005 (set_attr "mode" "QI")])
3006
3007 (define_insn "*insvqi_3"
3008 [(set (zero_extract:SWI248
3009 (match_operand:SWI248 0 "register_operand" "+Q")
3010 (const_int 8)
3011 (const_int 8))
3012 (any_shiftrt:SWI248
3013 (match_operand:SWI248 1 "register_operand" "Q")
3014 (const_int 8)))]
3015 ""
3016 "mov{b}\t{%h1, %h0|%h0, %h1}"
3017 [(set_attr "type" "imov")
3018 (set_attr "mode" "QI")])
3019 \f
3020 ;; Floating point push instructions.
3021
3022 (define_insn "*pushtf"
3023 [(set (match_operand:TF 0 "push_operand" "=<,<")
3024 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3025 "TARGET_64BIT || TARGET_SSE"
3026 {
3027 /* This insn should be already split before reg-stack. */
3028 return "#";
3029 }
3030 [(set_attr "isa" "*,x64")
3031 (set_attr "type" "multi")
3032 (set_attr "unit" "sse,*")
3033 (set_attr "mode" "TF,DI")])
3034
3035 ;; %%% Kill this when call knows how to work this out.
3036 (define_split
3037 [(set (match_operand:TF 0 "push_operand")
3038 (match_operand:TF 1 "sse_reg_operand"))]
3039 "TARGET_SSE && reload_completed"
3040 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3041 (set (match_dup 0) (match_dup 1))]
3042 {
3043 /* Preserve memory attributes. */
3044 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3045 })
3046
3047 (define_insn_and_split "*pushxf_rounded"
3048 [(set (mem:XF
3049 (pre_modify:P
3050 (reg:P SP_REG)
3051 (plus:P (reg:P SP_REG) (const_int -16))))
3052 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3053 "TARGET_64BIT"
3054 "#"
3055 "&& 1"
3056 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3057 (set (match_dup 1) (match_dup 0))]
3058 {
3059 rtx pat = PATTERN (curr_insn);
3060 operands[1] = SET_DEST (pat);
3061
3062 /* Preserve memory attributes. */
3063 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3064 }
3065 [(set_attr "type" "multi")
3066 (set_attr "unit" "i387,*,*,*")
3067 (set (attr "mode")
3068 (cond [(eq_attr "alternative" "1,2,3")
3069 (const_string "DI")
3070 ]
3071 (const_string "XF")))
3072 (set (attr "preferred_for_size")
3073 (cond [(eq_attr "alternative" "1")
3074 (symbol_ref "false")]
3075 (symbol_ref "true")))])
3076
3077 (define_insn "*pushxf"
3078 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3079 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3080 ""
3081 {
3082 /* This insn should be already split before reg-stack. */
3083 return "#";
3084 }
3085 [(set_attr "isa" "*,*,*,nox64,x64")
3086 (set_attr "type" "multi")
3087 (set_attr "unit" "i387,*,*,*,*")
3088 (set (attr "mode")
3089 (cond [(eq_attr "alternative" "1,2,3,4")
3090 (if_then_else (match_test "TARGET_64BIT")
3091 (const_string "DI")
3092 (const_string "SI"))
3093 ]
3094 (const_string "XF")))
3095 (set (attr "preferred_for_size")
3096 (cond [(eq_attr "alternative" "1")
3097 (symbol_ref "false")]
3098 (symbol_ref "true")))])
3099
3100 ;; %%% Kill this when call knows how to work this out.
3101 (define_split
3102 [(set (match_operand:XF 0 "push_operand")
3103 (match_operand:XF 1 "fp_register_operand"))]
3104 "reload_completed"
3105 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3106 (set (match_dup 0) (match_dup 1))]
3107 {
3108 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3109 /* Preserve memory attributes. */
3110 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3111 })
3112
3113 (define_insn "*pushdf"
3114 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3115 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3116 ""
3117 {
3118 /* This insn should be already split before reg-stack. */
3119 return "#";
3120 }
3121 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3122 (set_attr "type" "multi")
3123 (set_attr "unit" "i387,*,*,*,*,sse")
3124 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3125 (set (attr "preferred_for_size")
3126 (cond [(eq_attr "alternative" "1")
3127 (symbol_ref "false")]
3128 (symbol_ref "true")))
3129 (set (attr "preferred_for_speed")
3130 (cond [(eq_attr "alternative" "1")
3131 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3132 (symbol_ref "true")))])
3133
3134 ;; %%% Kill this when call knows how to work this out.
3135 (define_split
3136 [(set (match_operand:DF 0 "push_operand")
3137 (match_operand:DF 1 "any_fp_register_operand"))]
3138 "reload_completed"
3139 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3140 (set (match_dup 0) (match_dup 1))]
3141 {
3142 /* Preserve memory attributes. */
3143 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3144 })
3145
3146 (define_insn "*pushsf_rex64"
3147 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3148 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3149 "TARGET_64BIT"
3150 {
3151 /* Anything else should be already split before reg-stack. */
3152 if (which_alternative != 1)
3153 return "#";
3154 return "push{q}\t%q1";
3155 }
3156 [(set_attr "type" "multi,push,multi")
3157 (set_attr "unit" "i387,*,*")
3158 (set_attr "mode" "SF,DI,SF")])
3159
3160 (define_insn "*pushsf"
3161 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3162 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3163 "!TARGET_64BIT"
3164 {
3165 /* Anything else should be already split before reg-stack. */
3166 if (which_alternative != 1)
3167 return "#";
3168 return "push{l}\t%1";
3169 }
3170 [(set_attr "type" "multi,push,multi")
3171 (set_attr "unit" "i387,*,*")
3172 (set_attr "mode" "SF,SI,SF")])
3173
3174 ;; %%% Kill this when call knows how to work this out.
3175 (define_split
3176 [(set (match_operand:SF 0 "push_operand")
3177 (match_operand:SF 1 "any_fp_register_operand"))]
3178 "reload_completed"
3179 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3180 (set (match_dup 0) (match_dup 1))]
3181 {
3182 rtx op = XEXP (operands[0], 0);
3183 if (GET_CODE (op) == PRE_DEC)
3184 {
3185 gcc_assert (!TARGET_64BIT);
3186 op = GEN_INT (-4);
3187 }
3188 else
3189 {
3190 op = XEXP (XEXP (op, 1), 1);
3191 gcc_assert (CONST_INT_P (op));
3192 }
3193 operands[2] = op;
3194 /* Preserve memory attributes. */
3195 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3196 })
3197
3198 (define_split
3199 [(set (match_operand:SF 0 "push_operand")
3200 (match_operand:SF 1 "memory_operand"))]
3201 "reload_completed
3202 && find_constant_src (insn)"
3203 [(set (match_dup 0) (match_dup 2))]
3204 "operands[2] = find_constant_src (curr_insn);")
3205
3206 (define_split
3207 [(set (match_operand 0 "push_operand")
3208 (match_operand 1 "general_gr_operand"))]
3209 "reload_completed
3210 && (GET_MODE (operands[0]) == TFmode
3211 || GET_MODE (operands[0]) == XFmode
3212 || GET_MODE (operands[0]) == DFmode)"
3213 [(const_int 0)]
3214 "ix86_split_long_move (operands); DONE;")
3215 \f
3216 ;; Floating point move instructions.
3217
3218 (define_expand "movtf"
3219 [(set (match_operand:TF 0 "nonimmediate_operand")
3220 (match_operand:TF 1 "nonimmediate_operand"))]
3221 "TARGET_64BIT || TARGET_SSE"
3222 "ix86_expand_move (TFmode, operands); DONE;")
3223
3224 (define_expand "mov<mode>"
3225 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3226 (match_operand:X87MODEF 1 "general_operand"))]
3227 ""
3228 "ix86_expand_move (<MODE>mode, operands); DONE;")
3229
3230 (define_insn "*movtf_internal"
3231 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3232 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3233 "(TARGET_64BIT || TARGET_SSE)
3234 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3235 && (lra_in_progress || reload_completed
3236 || !CONST_DOUBLE_P (operands[1])
3237 || ((optimize_function_for_size_p (cfun)
3238 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3239 && standard_sse_constant_p (operands[1], TFmode) == 1
3240 && !memory_operand (operands[0], TFmode))
3241 || (!TARGET_MEMORY_MISMATCH_STALL
3242 && memory_operand (operands[0], TFmode)))"
3243 {
3244 switch (get_attr_type (insn))
3245 {
3246 case TYPE_SSELOG1:
3247 return standard_sse_constant_opcode (insn, operands);
3248
3249 case TYPE_SSEMOV:
3250 return ix86_output_ssemov (insn, operands);
3251
3252 case TYPE_MULTI:
3253 return "#";
3254
3255 default:
3256 gcc_unreachable ();
3257 }
3258 }
3259 [(set_attr "isa" "*,*,*,x64,x64")
3260 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3261 (set (attr "prefix")
3262 (if_then_else (eq_attr "type" "sselog1,ssemov")
3263 (const_string "maybe_vex")
3264 (const_string "orig")))
3265 (set (attr "mode")
3266 (cond [(eq_attr "alternative" "3,4")
3267 (const_string "DI")
3268 (match_test "TARGET_AVX")
3269 (const_string "TI")
3270 (ior (not (match_test "TARGET_SSE2"))
3271 (match_test "optimize_function_for_size_p (cfun)"))
3272 (const_string "V4SF")
3273 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3274 (const_string "V4SF")
3275 (and (eq_attr "alternative" "2")
3276 (match_test "TARGET_SSE_TYPELESS_STORES"))
3277 (const_string "V4SF")
3278 ]
3279 (const_string "TI")))])
3280
3281 (define_split
3282 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3283 (match_operand:TF 1 "general_gr_operand"))]
3284 "reload_completed"
3285 [(const_int 0)]
3286 "ix86_split_long_move (operands); DONE;")
3287
3288 ;; Possible store forwarding (partial memory) stall
3289 ;; in alternatives 4, 6, 7 and 8.
3290 (define_insn "*movxf_internal"
3291 [(set (match_operand:XF 0 "nonimmediate_operand"
3292 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3293 (match_operand:XF 1 "general_operand"
3294 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3295 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3296 && (lra_in_progress || reload_completed
3297 || !CONST_DOUBLE_P (operands[1])
3298 || ((optimize_function_for_size_p (cfun)
3299 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3300 && standard_80387_constant_p (operands[1]) > 0
3301 && !memory_operand (operands[0], XFmode))
3302 || (!TARGET_MEMORY_MISMATCH_STALL
3303 && memory_operand (operands[0], XFmode))
3304 || !TARGET_HARD_XF_REGS)"
3305 {
3306 switch (get_attr_type (insn))
3307 {
3308 case TYPE_FMOV:
3309 if (which_alternative == 2)
3310 return standard_80387_constant_opcode (operands[1]);
3311 return output_387_reg_move (insn, operands);
3312
3313 case TYPE_MULTI:
3314 return "#";
3315
3316 default:
3317 gcc_unreachable ();
3318 }
3319 }
3320 [(set (attr "isa")
3321 (cond [(eq_attr "alternative" "7,10")
3322 (const_string "nox64")
3323 (eq_attr "alternative" "8,11")
3324 (const_string "x64")
3325 ]
3326 (const_string "*")))
3327 (set (attr "type")
3328 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3329 (const_string "multi")
3330 ]
3331 (const_string "fmov")))
3332 (set (attr "mode")
3333 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3334 (if_then_else (match_test "TARGET_64BIT")
3335 (const_string "DI")
3336 (const_string "SI"))
3337 ]
3338 (const_string "XF")))
3339 (set (attr "preferred_for_size")
3340 (cond [(eq_attr "alternative" "3,4")
3341 (symbol_ref "false")]
3342 (symbol_ref "true")))
3343 (set (attr "enabled")
3344 (cond [(eq_attr "alternative" "9,10,11")
3345 (if_then_else
3346 (match_test "TARGET_HARD_XF_REGS")
3347 (symbol_ref "false")
3348 (const_string "*"))
3349 (not (match_test "TARGET_HARD_XF_REGS"))
3350 (symbol_ref "false")
3351 ]
3352 (const_string "*")))])
3353
3354 (define_split
3355 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3356 (match_operand:XF 1 "general_gr_operand"))]
3357 "reload_completed"
3358 [(const_int 0)]
3359 "ix86_split_long_move (operands); DONE;")
3360
3361 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3362 (define_insn "*movdf_internal"
3363 [(set (match_operand:DF 0 "nonimmediate_operand"
3364 "=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")
3365 (match_operand:DF 1 "general_operand"
3366 "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"))]
3367 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3368 && (lra_in_progress || reload_completed
3369 || !CONST_DOUBLE_P (operands[1])
3370 || ((optimize_function_for_size_p (cfun)
3371 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3372 && ((IS_STACK_MODE (DFmode)
3373 && standard_80387_constant_p (operands[1]) > 0)
3374 || (TARGET_SSE2 && TARGET_SSE_MATH
3375 && standard_sse_constant_p (operands[1], DFmode) == 1))
3376 && !memory_operand (operands[0], DFmode))
3377 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3378 && memory_operand (operands[0], DFmode))
3379 || !TARGET_HARD_DF_REGS)"
3380 {
3381 switch (get_attr_type (insn))
3382 {
3383 case TYPE_FMOV:
3384 if (which_alternative == 2)
3385 return standard_80387_constant_opcode (operands[1]);
3386 return output_387_reg_move (insn, operands);
3387
3388 case TYPE_MULTI:
3389 return "#";
3390
3391 case TYPE_IMOV:
3392 if (get_attr_mode (insn) == MODE_SI)
3393 return "mov{l}\t{%1, %k0|%k0, %1}";
3394 else if (which_alternative == 11)
3395 return "movabs{q}\t{%1, %0|%0, %1}";
3396 else
3397 return "mov{q}\t{%1, %0|%0, %1}";
3398
3399 case TYPE_SSELOG1:
3400 return standard_sse_constant_opcode (insn, operands);
3401
3402 case TYPE_SSEMOV:
3403 return ix86_output_ssemov (insn, operands);
3404
3405 default:
3406 gcc_unreachable ();
3407 }
3408 }
3409 [(set (attr "isa")
3410 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3411 (const_string "nox64")
3412 (eq_attr "alternative" "8,9,10,11,24,25")
3413 (const_string "x64")
3414 (eq_attr "alternative" "12,13,14,15")
3415 (const_string "sse2")
3416 (eq_attr "alternative" "20,21")
3417 (const_string "x64_sse2")
3418 ]
3419 (const_string "*")))
3420 (set (attr "type")
3421 (cond [(eq_attr "alternative" "0,1,2")
3422 (const_string "fmov")
3423 (eq_attr "alternative" "3,4,5,6,7,22,23")
3424 (const_string "multi")
3425 (eq_attr "alternative" "8,9,10,11,24,25")
3426 (const_string "imov")
3427 (eq_attr "alternative" "12,16")
3428 (const_string "sselog1")
3429 ]
3430 (const_string "ssemov")))
3431 (set (attr "modrm")
3432 (if_then_else (eq_attr "alternative" "11")
3433 (const_string "0")
3434 (const_string "*")))
3435 (set (attr "length_immediate")
3436 (if_then_else (eq_attr "alternative" "11")
3437 (const_string "8")
3438 (const_string "*")))
3439 (set (attr "prefix")
3440 (if_then_else (eq_attr "type" "sselog1,ssemov")
3441 (const_string "maybe_vex")
3442 (const_string "orig")))
3443 (set (attr "prefix_data16")
3444 (if_then_else
3445 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3446 (eq_attr "mode" "V1DF"))
3447 (const_string "1")
3448 (const_string "*")))
3449 (set (attr "mode")
3450 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3451 (const_string "SI")
3452 (eq_attr "alternative" "8,9,11,20,21,24,25")
3453 (const_string "DI")
3454
3455 /* xorps is one byte shorter for non-AVX targets. */
3456 (eq_attr "alternative" "12,16")
3457 (cond [(match_test "TARGET_AVX")
3458 (const_string "V2DF")
3459 (ior (not (match_test "TARGET_SSE2"))
3460 (match_test "optimize_function_for_size_p (cfun)"))
3461 (const_string "V4SF")
3462 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3463 (const_string "TI")
3464 ]
3465 (const_string "V2DF"))
3466
3467 /* For architectures resolving dependencies on
3468 whole SSE registers use movapd to break dependency
3469 chains, otherwise use short move to avoid extra work. */
3470
3471 /* movaps is one byte shorter for non-AVX targets. */
3472 (eq_attr "alternative" "13,17")
3473 (cond [(match_test "TARGET_AVX")
3474 (const_string "DF")
3475 (ior (not (match_test "TARGET_SSE2"))
3476 (match_test "optimize_function_for_size_p (cfun)"))
3477 (const_string "V4SF")
3478 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3479 (const_string "V4SF")
3480 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3481 (const_string "V2DF")
3482 ]
3483 (const_string "DF"))
3484
3485 /* For architectures resolving dependencies on register
3486 parts we may avoid extra work to zero out upper part
3487 of register. */
3488 (eq_attr "alternative" "14,18")
3489 (cond [(not (match_test "TARGET_SSE2"))
3490 (const_string "V2SF")
3491 (match_test "TARGET_AVX")
3492 (const_string "DF")
3493 (match_test "TARGET_SSE_SPLIT_REGS")
3494 (const_string "V1DF")
3495 ]
3496 (const_string "DF"))
3497
3498 (and (eq_attr "alternative" "15,19")
3499 (not (match_test "TARGET_SSE2")))
3500 (const_string "V2SF")
3501 ]
3502 (const_string "DF")))
3503 (set (attr "preferred_for_size")
3504 (cond [(eq_attr "alternative" "3,4")
3505 (symbol_ref "false")]
3506 (symbol_ref "true")))
3507 (set (attr "preferred_for_speed")
3508 (cond [(eq_attr "alternative" "3,4")
3509 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3510 (eq_attr "alternative" "20")
3511 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3512 (eq_attr "alternative" "21")
3513 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3514 ]
3515 (symbol_ref "true")))
3516 (set (attr "enabled")
3517 (cond [(eq_attr "alternative" "22,23,24,25")
3518 (if_then_else
3519 (match_test "TARGET_HARD_DF_REGS")
3520 (symbol_ref "false")
3521 (const_string "*"))
3522 (not (match_test "TARGET_HARD_DF_REGS"))
3523 (symbol_ref "false")
3524 ]
3525 (const_string "*")))])
3526
3527 (define_split
3528 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3529 (match_operand:DF 1 "general_gr_operand"))]
3530 "!TARGET_64BIT && reload_completed"
3531 [(const_int 0)]
3532 "ix86_split_long_move (operands); DONE;")
3533
3534 (define_insn "*movsf_internal"
3535 [(set (match_operand:SF 0 "nonimmediate_operand"
3536 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3537 (match_operand:SF 1 "general_operand"
3538 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3539 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3540 && (lra_in_progress || reload_completed
3541 || !CONST_DOUBLE_P (operands[1])
3542 || ((optimize_function_for_size_p (cfun)
3543 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3544 && ((IS_STACK_MODE (SFmode)
3545 && standard_80387_constant_p (operands[1]) > 0)
3546 || (TARGET_SSE && TARGET_SSE_MATH
3547 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3548 || memory_operand (operands[0], SFmode)
3549 || !TARGET_HARD_SF_REGS)"
3550 {
3551 switch (get_attr_type (insn))
3552 {
3553 case TYPE_FMOV:
3554 if (which_alternative == 2)
3555 return standard_80387_constant_opcode (operands[1]);
3556 return output_387_reg_move (insn, operands);
3557
3558 case TYPE_IMOV:
3559 return "mov{l}\t{%1, %0|%0, %1}";
3560
3561 case TYPE_SSELOG1:
3562 return standard_sse_constant_opcode (insn, operands);
3563
3564 case TYPE_SSEMOV:
3565 return ix86_output_ssemov (insn, operands);
3566
3567 case TYPE_MMXMOV:
3568 switch (get_attr_mode (insn))
3569 {
3570 case MODE_DI:
3571 return "movq\t{%1, %0|%0, %1}";
3572 case MODE_SI:
3573 return "movd\t{%1, %0|%0, %1}";
3574
3575 default:
3576 gcc_unreachable ();
3577 }
3578
3579 default:
3580 gcc_unreachable ();
3581 }
3582 }
3583 [(set (attr "isa")
3584 (cond [(eq_attr "alternative" "9,10")
3585 (const_string "sse2")
3586 ]
3587 (const_string "*")))
3588 (set (attr "type")
3589 (cond [(eq_attr "alternative" "0,1,2")
3590 (const_string "fmov")
3591 (eq_attr "alternative" "3,4,16,17")
3592 (const_string "imov")
3593 (eq_attr "alternative" "5")
3594 (const_string "sselog1")
3595 (eq_attr "alternative" "11,12,13,14,15")
3596 (const_string "mmxmov")
3597 ]
3598 (const_string "ssemov")))
3599 (set (attr "prefix")
3600 (if_then_else (eq_attr "type" "sselog1,ssemov")
3601 (const_string "maybe_vex")
3602 (const_string "orig")))
3603 (set (attr "prefix_data16")
3604 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3605 (const_string "1")
3606 (const_string "*")))
3607 (set (attr "mode")
3608 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3609 (const_string "SI")
3610 (eq_attr "alternative" "11")
3611 (const_string "DI")
3612 (eq_attr "alternative" "5")
3613 (cond [(and (match_test "TARGET_AVX512F")
3614 (not (match_test "TARGET_PREFER_AVX256")))
3615 (const_string "V16SF")
3616 (match_test "TARGET_AVX")
3617 (const_string "V4SF")
3618 (ior (not (match_test "TARGET_SSE2"))
3619 (match_test "optimize_function_for_size_p (cfun)"))
3620 (const_string "V4SF")
3621 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3622 (const_string "TI")
3623 ]
3624 (const_string "V4SF"))
3625
3626 /* For architectures resolving dependencies on
3627 whole SSE registers use APS move to break dependency
3628 chains, otherwise use short move to avoid extra work.
3629
3630 Do the same for architectures resolving dependencies on
3631 the parts. While in DF mode it is better to always handle
3632 just register parts, the SF mode is different due to lack
3633 of instructions to load just part of the register. It is
3634 better to maintain the whole registers in single format
3635 to avoid problems on using packed logical operations. */
3636 (eq_attr "alternative" "6")
3637 (cond [(ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3638 (match_test "TARGET_SSE_SPLIT_REGS"))
3639 (const_string "V4SF")
3640 ]
3641 (const_string "SF"))
3642 ]
3643 (const_string "SF")))
3644 (set (attr "preferred_for_speed")
3645 (cond [(eq_attr "alternative" "9,14")
3646 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3647 (eq_attr "alternative" "10,15")
3648 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3649 ]
3650 (symbol_ref "true")))
3651 (set (attr "enabled")
3652 (cond [(eq_attr "alternative" "16,17")
3653 (if_then_else
3654 (match_test "TARGET_HARD_SF_REGS")
3655 (symbol_ref "false")
3656 (const_string "*"))
3657 (not (match_test "TARGET_HARD_SF_REGS"))
3658 (symbol_ref "false")
3659 ]
3660 (const_string "*")))])
3661
3662 (define_split
3663 [(set (match_operand 0 "any_fp_register_operand")
3664 (match_operand 1 "memory_operand"))]
3665 "reload_completed
3666 && (GET_MODE (operands[0]) == TFmode
3667 || GET_MODE (operands[0]) == XFmode
3668 || GET_MODE (operands[0]) == DFmode
3669 || GET_MODE (operands[0]) == SFmode)
3670 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3671 [(set (match_dup 0) (match_dup 2))]
3672 "operands[2] = find_constant_src (curr_insn);")
3673
3674 (define_split
3675 [(set (match_operand 0 "any_fp_register_operand")
3676 (float_extend (match_operand 1 "memory_operand")))]
3677 "reload_completed
3678 && (GET_MODE (operands[0]) == TFmode
3679 || GET_MODE (operands[0]) == XFmode
3680 || GET_MODE (operands[0]) == DFmode)
3681 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3682 [(set (match_dup 0) (match_dup 2))]
3683 "operands[2] = find_constant_src (curr_insn);")
3684
3685 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3686 (define_split
3687 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3688 (match_operand:X87MODEF 1 "immediate_operand"))]
3689 "reload_completed
3690 && (standard_80387_constant_p (operands[1]) == 8
3691 || standard_80387_constant_p (operands[1]) == 9)"
3692 [(set (match_dup 0)(match_dup 1))
3693 (set (match_dup 0)
3694 (neg:X87MODEF (match_dup 0)))]
3695 {
3696 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3697 operands[1] = CONST0_RTX (<MODE>mode);
3698 else
3699 operands[1] = CONST1_RTX (<MODE>mode);
3700 })
3701
3702 (define_insn "*swapxf"
3703 [(set (match_operand:XF 0 "register_operand" "+f")
3704 (match_operand:XF 1 "register_operand" "+f"))
3705 (set (match_dup 1)
3706 (match_dup 0))]
3707 "TARGET_80387"
3708 {
3709 if (STACK_TOP_P (operands[0]))
3710 return "fxch\t%1";
3711 else
3712 return "fxch\t%0";
3713 }
3714 [(set_attr "type" "fxch")
3715 (set_attr "mode" "XF")])
3716 \f
3717
3718 ;; Zero extension instructions
3719
3720 (define_expand "zero_extendsidi2"
3721 [(set (match_operand:DI 0 "nonimmediate_operand")
3722 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3723
3724 (define_insn "*zero_extendsidi2"
3725 [(set (match_operand:DI 0 "nonimmediate_operand"
3726 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
3727 (zero_extend:DI
3728 (match_operand:SI 1 "x86_64_zext_operand"
3729 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
3730 ""
3731 {
3732 switch (get_attr_type (insn))
3733 {
3734 case TYPE_IMOVX:
3735 if (ix86_use_lea_for_mov (insn, operands))
3736 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3737 else
3738 return "mov{l}\t{%1, %k0|%k0, %1}";
3739
3740 case TYPE_MULTI:
3741 return "#";
3742
3743 case TYPE_MMXMOV:
3744 return "movd\t{%1, %0|%0, %1}";
3745
3746 case TYPE_SSEMOV:
3747 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3748 {
3749 if (EXT_REX_SSE_REG_P (operands[0])
3750 || EXT_REX_SSE_REG_P (operands[1]))
3751 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3752 else
3753 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3754 }
3755
3756 if (GENERAL_REG_P (operands[0]))
3757 return "%vmovd\t{%1, %k0|%k0, %1}";
3758
3759 return "%vmovd\t{%1, %0|%0, %1}";
3760
3761 case TYPE_MSKMOV:
3762 return "kmovd\t{%1, %k0|%k0, %1}";
3763
3764 default:
3765 gcc_unreachable ();
3766 }
3767 }
3768 [(set (attr "isa")
3769 (cond [(eq_attr "alternative" "0,1,2")
3770 (const_string "nox64")
3771 (eq_attr "alternative" "3")
3772 (const_string "x64")
3773 (eq_attr "alternative" "7,8,9")
3774 (const_string "sse2")
3775 (eq_attr "alternative" "10")
3776 (const_string "sse4")
3777 (eq_attr "alternative" "11")
3778 (const_string "avx512f")
3779 (eq_attr "alternative" "12")
3780 (const_string "x64_avx512bw")
3781 (eq_attr "alternative" "13")
3782 (const_string "avx512bw")
3783 ]
3784 (const_string "*")))
3785 (set (attr "mmx_isa")
3786 (if_then_else (eq_attr "alternative" "5,6")
3787 (const_string "native")
3788 (const_string "*")))
3789 (set (attr "type")
3790 (cond [(eq_attr "alternative" "0,1,2,4")
3791 (const_string "multi")
3792 (eq_attr "alternative" "5,6")
3793 (const_string "mmxmov")
3794 (eq_attr "alternative" "7")
3795 (if_then_else (match_test "TARGET_64BIT")
3796 (const_string "ssemov")
3797 (const_string "multi"))
3798 (eq_attr "alternative" "8,9,10,11")
3799 (const_string "ssemov")
3800 (eq_attr "alternative" "12,13")
3801 (const_string "mskmov")
3802 ]
3803 (const_string "imovx")))
3804 (set (attr "prefix_extra")
3805 (if_then_else (eq_attr "alternative" "10,11")
3806 (const_string "1")
3807 (const_string "*")))
3808 (set (attr "prefix")
3809 (if_then_else (eq_attr "type" "ssemov")
3810 (const_string "maybe_vex")
3811 (const_string "orig")))
3812 (set (attr "prefix_0f")
3813 (if_then_else (eq_attr "type" "imovx")
3814 (const_string "0")
3815 (const_string "*")))
3816 (set (attr "mode")
3817 (cond [(eq_attr "alternative" "5,6")
3818 (const_string "DI")
3819 (and (eq_attr "alternative" "7")
3820 (match_test "TARGET_64BIT"))
3821 (const_string "TI")
3822 (eq_attr "alternative" "8,10,11")
3823 (const_string "TI")
3824 ]
3825 (const_string "SI")))
3826 (set (attr "preferred_for_speed")
3827 (cond [(eq_attr "alternative" "7")
3828 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3829 (eq_attr "alternative" "5,8")
3830 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3831 ]
3832 (symbol_ref "true")))])
3833
3834 (define_split
3835 [(set (match_operand:DI 0 "memory_operand")
3836 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3837 "reload_completed"
3838 [(set (match_dup 4) (const_int 0))]
3839 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3840
3841 (define_split
3842 [(set (match_operand:DI 0 "general_reg_operand")
3843 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3844 "!TARGET_64BIT && reload_completed
3845 && REGNO (operands[0]) == REGNO (operands[1])"
3846 [(set (match_dup 4) (const_int 0))]
3847 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3848
3849 (define_split
3850 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3851 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3852 "!TARGET_64BIT && reload_completed
3853 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3854 [(set (match_dup 3) (match_dup 1))
3855 (set (match_dup 4) (const_int 0))]
3856 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3857
3858 (define_mode_attr kmov_isa
3859 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3860
3861 (define_insn "zero_extend<mode>di2"
3862 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
3863 (zero_extend:DI
3864 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3865 "TARGET_64BIT"
3866 "@
3867 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3868 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
3869 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3870 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3871 (set_attr "type" "imovx,mskmov,mskmov")
3872 (set_attr "mode" "SI,<MODE>,<MODE>")])
3873
3874 (define_expand "zero_extend<mode>si2"
3875 [(set (match_operand:SI 0 "register_operand")
3876 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3877 ""
3878 {
3879 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3880 {
3881 operands[1] = force_reg (<MODE>mode, operands[1]);
3882 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3883 DONE;
3884 }
3885 })
3886
3887 (define_insn_and_split "zero_extend<mode>si2_and"
3888 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3889 (zero_extend:SI
3890 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3891 (clobber (reg:CC FLAGS_REG))]
3892 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3893 "#"
3894 "&& reload_completed"
3895 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3896 (clobber (reg:CC FLAGS_REG))])]
3897 {
3898 if (!REG_P (operands[1])
3899 || REGNO (operands[0]) != REGNO (operands[1]))
3900 {
3901 ix86_expand_clear (operands[0]);
3902
3903 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3904 emit_insn (gen_rtx_SET
3905 (gen_rtx_STRICT_LOW_PART
3906 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
3907 operands[1]));
3908 DONE;
3909 }
3910
3911 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3912 }
3913 [(set_attr "type" "alu1")
3914 (set_attr "mode" "SI")])
3915
3916 (define_insn "*zero_extend<mode>si2"
3917 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
3918 (zero_extend:SI
3919 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3920 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3921 "@
3922 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
3923 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
3924 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
3925 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3926 (set_attr "type" "imovx,mskmov,mskmov")
3927 (set_attr "mode" "SI,<MODE>,<MODE>")])
3928
3929 (define_expand "zero_extendqihi2"
3930 [(set (match_operand:HI 0 "register_operand")
3931 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3932 ""
3933 {
3934 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3935 {
3936 operands[1] = force_reg (QImode, operands[1]);
3937 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3938 DONE;
3939 }
3940 })
3941
3942 (define_insn_and_split "zero_extendqihi2_and"
3943 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3944 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3945 (clobber (reg:CC FLAGS_REG))]
3946 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3947 "#"
3948 "&& reload_completed"
3949 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3950 (clobber (reg:CC FLAGS_REG))])]
3951 {
3952 if (!REG_P (operands[1])
3953 || REGNO (operands[0]) != REGNO (operands[1]))
3954 {
3955 ix86_expand_clear (operands[0]);
3956
3957 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3958 emit_insn (gen_rtx_SET
3959 (gen_rtx_STRICT_LOW_PART
3960 (VOIDmode, gen_lowpart (QImode, operands[0])),
3961 operands[1]));
3962 DONE;
3963 }
3964
3965 operands[0] = gen_lowpart (SImode, operands[0]);
3966 }
3967 [(set_attr "type" "alu1")
3968 (set_attr "mode" "SI")])
3969
3970 ; zero extend to SImode to avoid partial register stalls
3971 (define_insn "*zero_extendqihi2"
3972 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
3973 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
3974 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3975 "@
3976 movz{bl|x}\t{%1, %k0|%k0, %1}
3977 kmovb\t{%1, %k0|%k0, %1}
3978 kmovb\t{%1, %0|%0, %1}"
3979 [(set_attr "isa" "*,avx512dq,avx512dq")
3980 (set_attr "type" "imovx,mskmov,mskmov")
3981 (set_attr "mode" "SI,QI,QI")])
3982 \f
3983 ;; Sign extension instructions
3984
3985 (define_expand "extendsidi2"
3986 [(set (match_operand:DI 0 "register_operand")
3987 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3988 ""
3989 {
3990 if (!TARGET_64BIT)
3991 {
3992 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3993 DONE;
3994 }
3995 })
3996
3997 (define_insn "*extendsidi2_rex64"
3998 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3999 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4000 "TARGET_64BIT"
4001 "@
4002 {cltq|cdqe}
4003 movs{lq|x}\t{%1, %0|%0, %1}"
4004 [(set_attr "type" "imovx")
4005 (set_attr "mode" "DI")
4006 (set_attr "prefix_0f" "0")
4007 (set_attr "modrm" "0,1")])
4008
4009 (define_insn "extendsidi2_1"
4010 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4011 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4012 (clobber (reg:CC FLAGS_REG))
4013 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4014 "!TARGET_64BIT"
4015 "#")
4016
4017 ;; Split the memory case. If the source register doesn't die, it will stay
4018 ;; this way, if it does die, following peephole2s take care of it.
4019 (define_split
4020 [(set (match_operand:DI 0 "memory_operand")
4021 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4022 (clobber (reg:CC FLAGS_REG))
4023 (clobber (match_operand:SI 2 "register_operand"))]
4024 "reload_completed"
4025 [(const_int 0)]
4026 {
4027 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4028
4029 emit_move_insn (operands[3], operands[1]);
4030
4031 /* Generate a cltd if possible and doing so it profitable. */
4032 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4033 && REGNO (operands[1]) == AX_REG
4034 && REGNO (operands[2]) == DX_REG)
4035 {
4036 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4037 }
4038 else
4039 {
4040 emit_move_insn (operands[2], operands[1]);
4041 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4042 }
4043 emit_move_insn (operands[4], operands[2]);
4044 DONE;
4045 })
4046
4047 ;; Peepholes for the case where the source register does die, after
4048 ;; being split with the above splitter.
4049 (define_peephole2
4050 [(set (match_operand:SI 0 "memory_operand")
4051 (match_operand:SI 1 "general_reg_operand"))
4052 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4053 (parallel [(set (match_dup 2)
4054 (ashiftrt:SI (match_dup 2) (const_int 31)))
4055 (clobber (reg:CC FLAGS_REG))])
4056 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4057 "REGNO (operands[1]) != REGNO (operands[2])
4058 && peep2_reg_dead_p (2, operands[1])
4059 && peep2_reg_dead_p (4, operands[2])
4060 && !reg_mentioned_p (operands[2], operands[3])"
4061 [(set (match_dup 0) (match_dup 1))
4062 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4063 (clobber (reg:CC FLAGS_REG))])
4064 (set (match_dup 3) (match_dup 1))])
4065
4066 (define_peephole2
4067 [(set (match_operand:SI 0 "memory_operand")
4068 (match_operand:SI 1 "general_reg_operand"))
4069 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4070 (ashiftrt:SI (match_dup 1) (const_int 31)))
4071 (clobber (reg:CC FLAGS_REG))])
4072 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4073 "/* cltd is shorter than sarl $31, %eax */
4074 !optimize_function_for_size_p (cfun)
4075 && REGNO (operands[1]) == AX_REG
4076 && REGNO (operands[2]) == DX_REG
4077 && peep2_reg_dead_p (2, operands[1])
4078 && peep2_reg_dead_p (3, operands[2])
4079 && !reg_mentioned_p (operands[2], operands[3])"
4080 [(set (match_dup 0) (match_dup 1))
4081 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4082 (clobber (reg:CC FLAGS_REG))])
4083 (set (match_dup 3) (match_dup 1))])
4084
4085 ;; Extend to register case. Optimize case where source and destination
4086 ;; registers match and cases where we can use cltd.
4087 (define_split
4088 [(set (match_operand:DI 0 "register_operand")
4089 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4090 (clobber (reg:CC FLAGS_REG))
4091 (clobber (match_scratch:SI 2))]
4092 "reload_completed"
4093 [(const_int 0)]
4094 {
4095 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4096
4097 if (REGNO (operands[3]) != REGNO (operands[1]))
4098 emit_move_insn (operands[3], operands[1]);
4099
4100 /* Generate a cltd if possible and doing so it profitable. */
4101 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4102 && REGNO (operands[3]) == AX_REG
4103 && REGNO (operands[4]) == DX_REG)
4104 {
4105 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4106 DONE;
4107 }
4108
4109 if (REGNO (operands[4]) != REGNO (operands[1]))
4110 emit_move_insn (operands[4], operands[1]);
4111
4112 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4113 DONE;
4114 })
4115
4116 (define_insn "extend<mode>di2"
4117 [(set (match_operand:DI 0 "register_operand" "=r")
4118 (sign_extend:DI
4119 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4120 "TARGET_64BIT"
4121 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4122 [(set_attr "type" "imovx")
4123 (set_attr "mode" "DI")])
4124
4125 (define_insn "extendhisi2"
4126 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4127 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4128 ""
4129 {
4130 switch (get_attr_prefix_0f (insn))
4131 {
4132 case 0:
4133 return "{cwtl|cwde}";
4134 default:
4135 return "movs{wl|x}\t{%1, %0|%0, %1}";
4136 }
4137 }
4138 [(set_attr "type" "imovx")
4139 (set_attr "mode" "SI")
4140 (set (attr "prefix_0f")
4141 ;; movsx is short decodable while cwtl is vector decoded.
4142 (if_then_else (and (eq_attr "cpu" "!k6")
4143 (eq_attr "alternative" "0"))
4144 (const_string "0")
4145 (const_string "1")))
4146 (set (attr "znver1_decode")
4147 (if_then_else (eq_attr "prefix_0f" "0")
4148 (const_string "double")
4149 (const_string "direct")))
4150 (set (attr "modrm")
4151 (if_then_else (eq_attr "prefix_0f" "0")
4152 (const_string "0")
4153 (const_string "1")))])
4154
4155 (define_insn "*extendhisi2_zext"
4156 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4157 (zero_extend:DI
4158 (sign_extend:SI
4159 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4160 "TARGET_64BIT"
4161 {
4162 switch (get_attr_prefix_0f (insn))
4163 {
4164 case 0:
4165 return "{cwtl|cwde}";
4166 default:
4167 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4168 }
4169 }
4170 [(set_attr "type" "imovx")
4171 (set_attr "mode" "SI")
4172 (set (attr "prefix_0f")
4173 ;; movsx is short decodable while cwtl is vector decoded.
4174 (if_then_else (and (eq_attr "cpu" "!k6")
4175 (eq_attr "alternative" "0"))
4176 (const_string "0")
4177 (const_string "1")))
4178 (set (attr "modrm")
4179 (if_then_else (eq_attr "prefix_0f" "0")
4180 (const_string "0")
4181 (const_string "1")))])
4182
4183 (define_insn "extendqisi2"
4184 [(set (match_operand:SI 0 "register_operand" "=r")
4185 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4186 ""
4187 "movs{bl|x}\t{%1, %0|%0, %1}"
4188 [(set_attr "type" "imovx")
4189 (set_attr "mode" "SI")])
4190
4191 (define_insn "*extendqisi2_zext"
4192 [(set (match_operand:DI 0 "register_operand" "=r")
4193 (zero_extend:DI
4194 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4195 "TARGET_64BIT"
4196 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4197 [(set_attr "type" "imovx")
4198 (set_attr "mode" "SI")])
4199
4200 (define_insn "extendqihi2"
4201 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4202 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4203 ""
4204 {
4205 switch (get_attr_prefix_0f (insn))
4206 {
4207 case 0:
4208 return "{cbtw|cbw}";
4209 default:
4210 return "movs{bw|x}\t{%1, %0|%0, %1}";
4211 }
4212 }
4213 [(set_attr "type" "imovx")
4214 (set_attr "mode" "HI")
4215 (set (attr "prefix_0f")
4216 ;; movsx is short decodable while cwtl is vector decoded.
4217 (if_then_else (and (eq_attr "cpu" "!k6")
4218 (eq_attr "alternative" "0"))
4219 (const_string "0")
4220 (const_string "1")))
4221 (set (attr "modrm")
4222 (if_then_else (eq_attr "prefix_0f" "0")
4223 (const_string "0")
4224 (const_string "1")))])
4225 \f
4226 ;; Conversions between float and double.
4227
4228 ;; These are all no-ops in the model used for the 80387.
4229 ;; So just emit moves.
4230
4231 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4232 (define_split
4233 [(set (match_operand:DF 0 "push_operand")
4234 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4235 "reload_completed"
4236 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4237 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4238
4239 (define_split
4240 [(set (match_operand:XF 0 "push_operand")
4241 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4242 "reload_completed"
4243 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4244 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4245 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4246
4247 (define_expand "extendsfdf2"
4248 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4249 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4250 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4251 {
4252 /* ??? Needed for compress_float_constant since all fp constants
4253 are TARGET_LEGITIMATE_CONSTANT_P. */
4254 if (CONST_DOUBLE_P (operands[1]))
4255 {
4256 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4257 && standard_80387_constant_p (operands[1]) > 0)
4258 {
4259 operands[1] = simplify_const_unary_operation
4260 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4261 emit_move_insn_1 (operands[0], operands[1]);
4262 DONE;
4263 }
4264 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4265 }
4266 })
4267
4268 (define_insn "*extendsfdf2"
4269 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
4270 (float_extend:DF
4271 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
4272 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4273 {
4274 switch (which_alternative)
4275 {
4276 case 0:
4277 case 1:
4278 return output_387_reg_move (insn, operands);
4279
4280 case 2:
4281 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
4282 case 3:
4283 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4284
4285 default:
4286 gcc_unreachable ();
4287 }
4288 }
4289 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4290 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4291 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
4292 (set_attr "mode" "SF,XF,DF,DF")
4293 (set (attr "enabled")
4294 (if_then_else
4295 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4296 (if_then_else
4297 (eq_attr "alternative" "0,1")
4298 (symbol_ref "TARGET_MIX_SSE_I387")
4299 (symbol_ref "true"))
4300 (if_then_else
4301 (eq_attr "alternative" "0,1")
4302 (symbol_ref "true")
4303 (symbol_ref "false"))))])
4304
4305 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4306 cvtss2sd:
4307 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4308 cvtps2pd xmm2,xmm1
4309 We do the conversion post reload to avoid producing of 128bit spills
4310 that might lead to ICE on 32bit target. The sequence unlikely combine
4311 anyway. */
4312 (define_split
4313 [(set (match_operand:DF 0 "sse_reg_operand")
4314 (float_extend:DF
4315 (match_operand:SF 1 "nonimmediate_operand")))]
4316 "TARGET_USE_VECTOR_FP_CONVERTS
4317 && optimize_insn_for_speed_p ()
4318 && reload_completed
4319 && (!EXT_REX_SSE_REG_P (operands[0])
4320 || TARGET_AVX512VL)"
4321 [(set (match_dup 2)
4322 (float_extend:V2DF
4323 (vec_select:V2SF
4324 (match_dup 3)
4325 (parallel [(const_int 0) (const_int 1)]))))]
4326 {
4327 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4328 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4329 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4330 Try to avoid move when unpacking can be done in source. */
4331 if (REG_P (operands[1]))
4332 {
4333 /* If it is unsafe to overwrite upper half of source, we need
4334 to move to destination and unpack there. */
4335 if (REGNO (operands[0]) != REGNO (operands[1])
4336 || (EXT_REX_SSE_REG_P (operands[1])
4337 && !TARGET_AVX512VL))
4338 {
4339 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4340 emit_move_insn (tmp, operands[1]);
4341 }
4342 else
4343 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4344 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4345 =v, v, then vbroadcastss will be only needed for AVX512F without
4346 AVX512VL. */
4347 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4348 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4349 operands[3]));
4350 else
4351 {
4352 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4353 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4354 }
4355 }
4356 else
4357 emit_insn (gen_vec_setv4sf_0 (operands[3],
4358 CONST0_RTX (V4SFmode), operands[1]));
4359 })
4360
4361 ;; It's more profitable to split and then extend in the same register.
4362 (define_peephole2
4363 [(set (match_operand:DF 0 "sse_reg_operand")
4364 (float_extend:DF
4365 (match_operand:SF 1 "memory_operand")))]
4366 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4367 && optimize_insn_for_speed_p ()"
4368 [(set (match_dup 2) (match_dup 1))
4369 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4370 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4371
4372 ;; Break partial SSE register dependency stall. This splitter should split
4373 ;; late in the pass sequence (after register rename pass), so allocated
4374 ;; registers won't change anymore
4375
4376 (define_split
4377 [(set (match_operand:DF 0 "sse_reg_operand")
4378 (float_extend:DF
4379 (match_operand:SF 1 "nonimmediate_operand")))]
4380 "!TARGET_AVX
4381 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4382 && optimize_function_for_speed_p (cfun)
4383 && (!REG_P (operands[1])
4384 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4385 && (!EXT_REX_SSE_REG_P (operands[0])
4386 || TARGET_AVX512VL)"
4387 [(set (match_dup 0)
4388 (vec_merge:V2DF
4389 (vec_duplicate:V2DF
4390 (float_extend:DF
4391 (match_dup 1)))
4392 (match_dup 0)
4393 (const_int 1)))]
4394 {
4395 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4396 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4397 })
4398
4399 (define_expand "extend<mode>xf2"
4400 [(set (match_operand:XF 0 "nonimmediate_operand")
4401 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4402 "TARGET_80387"
4403 {
4404 /* ??? Needed for compress_float_constant since all fp constants
4405 are TARGET_LEGITIMATE_CONSTANT_P. */
4406 if (CONST_DOUBLE_P (operands[1]))
4407 {
4408 if (standard_80387_constant_p (operands[1]) > 0)
4409 {
4410 operands[1] = simplify_const_unary_operation
4411 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4412 emit_move_insn_1 (operands[0], operands[1]);
4413 DONE;
4414 }
4415 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4416 }
4417 })
4418
4419 (define_insn "*extend<mode>xf2_i387"
4420 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4421 (float_extend:XF
4422 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4423 "TARGET_80387"
4424 "* return output_387_reg_move (insn, operands);"
4425 [(set_attr "type" "fmov")
4426 (set_attr "mode" "<MODE>,XF")])
4427
4428 ;; %%% This seems like bad news.
4429 ;; This cannot output into an f-reg because there is no way to be sure
4430 ;; of truncating in that case. Otherwise this is just like a simple move
4431 ;; insn. So we pretend we can output to a reg in order to get better
4432 ;; register preferencing, but we really use a stack slot.
4433
4434 ;; Conversion from DFmode to SFmode.
4435
4436 (define_insn "truncdfsf2"
4437 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
4438 (float_truncate:SF
4439 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
4440 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4441 {
4442 switch (which_alternative)
4443 {
4444 case 0:
4445 case 1:
4446 return output_387_reg_move (insn, operands);
4447
4448 case 2:
4449 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
4450 case 3:
4451 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4452
4453 default:
4454 gcc_unreachable ();
4455 }
4456 }
4457 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4458 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4459 (set_attr "mode" "SF")
4460 (set (attr "enabled")
4461 (if_then_else
4462 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4463 (cond [(eq_attr "alternative" "0")
4464 (symbol_ref "TARGET_MIX_SSE_I387")
4465 (eq_attr "alternative" "1")
4466 (symbol_ref "TARGET_MIX_SSE_I387
4467 && flag_unsafe_math_optimizations")
4468 ]
4469 (symbol_ref "true"))
4470 (cond [(eq_attr "alternative" "0")
4471 (symbol_ref "true")
4472 (eq_attr "alternative" "1")
4473 (symbol_ref "flag_unsafe_math_optimizations")
4474 ]
4475 (symbol_ref "false"))))])
4476
4477 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4478 cvtsd2ss:
4479 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4480 cvtpd2ps xmm2,xmm1
4481 We do the conversion post reload to avoid producing of 128bit spills
4482 that might lead to ICE on 32bit target. The sequence unlikely combine
4483 anyway. */
4484 (define_split
4485 [(set (match_operand:SF 0 "sse_reg_operand")
4486 (float_truncate:SF
4487 (match_operand:DF 1 "nonimmediate_operand")))]
4488 "TARGET_USE_VECTOR_FP_CONVERTS
4489 && optimize_insn_for_speed_p ()
4490 && reload_completed
4491 && (!EXT_REX_SSE_REG_P (operands[0])
4492 || TARGET_AVX512VL)"
4493 [(set (match_dup 2)
4494 (vec_concat:V4SF
4495 (float_truncate:V2SF
4496 (match_dup 4))
4497 (match_dup 3)))]
4498 {
4499 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4500 operands[3] = CONST0_RTX (V2SFmode);
4501 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4502 /* Use movsd for loading from memory, unpcklpd for registers.
4503 Try to avoid move when unpacking can be done in source, or SSE3
4504 movddup is available. */
4505 if (REG_P (operands[1]))
4506 {
4507 if (!TARGET_SSE3
4508 && REGNO (operands[0]) != REGNO (operands[1]))
4509 {
4510 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4511 emit_move_insn (tmp, operands[1]);
4512 operands[1] = tmp;
4513 }
4514 else if (!TARGET_SSE3)
4515 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4516 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4517 }
4518 else
4519 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4520 CONST0_RTX (DFmode)));
4521 })
4522
4523 ;; It's more profitable to split and then truncate in the same register.
4524 (define_peephole2
4525 [(set (match_operand:SF 0 "sse_reg_operand")
4526 (float_truncate:SF
4527 (match_operand:DF 1 "memory_operand")))]
4528 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4529 && optimize_insn_for_speed_p ()"
4530 [(set (match_dup 2) (match_dup 1))
4531 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4532 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4533
4534 ;; Break partial SSE register dependency stall. This splitter should split
4535 ;; late in the pass sequence (after register rename pass), so allocated
4536 ;; registers won't change anymore
4537
4538 (define_split
4539 [(set (match_operand:SF 0 "sse_reg_operand")
4540 (float_truncate:SF
4541 (match_operand:DF 1 "nonimmediate_operand")))]
4542 "!TARGET_AVX
4543 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4544 && optimize_function_for_speed_p (cfun)
4545 && (!REG_P (operands[1])
4546 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4547 && (!EXT_REX_SSE_REG_P (operands[0])
4548 || TARGET_AVX512VL)"
4549 [(set (match_dup 0)
4550 (vec_merge:V4SF
4551 (vec_duplicate:V4SF
4552 (float_truncate:SF
4553 (match_dup 1)))
4554 (match_dup 0)
4555 (const_int 1)))]
4556 {
4557 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4558 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4559 })
4560
4561 ;; Conversion from XFmode to {SF,DF}mode
4562
4563 (define_insn "truncxf<mode>2"
4564 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
4565 (float_truncate:MODEF
4566 (match_operand:XF 1 "register_operand" "f,f")))]
4567 "TARGET_80387"
4568 "* return output_387_reg_move (insn, operands);"
4569 [(set_attr "type" "fmov")
4570 (set_attr "mode" "<MODE>")
4571 (set (attr "enabled")
4572 (cond [(eq_attr "alternative" "1")
4573 (symbol_ref "flag_unsafe_math_optimizations")
4574 ]
4575 (symbol_ref "true")))])
4576 \f
4577 ;; Signed conversion to DImode.
4578
4579 (define_expand "fix_truncxfdi2"
4580 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4581 (fix:DI (match_operand:XF 1 "register_operand")))
4582 (clobber (reg:CC FLAGS_REG))])]
4583 "TARGET_80387"
4584 {
4585 if (TARGET_FISTTP)
4586 {
4587 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4588 DONE;
4589 }
4590 })
4591
4592 (define_expand "fix_trunc<mode>di2"
4593 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4594 (fix:DI (match_operand:MODEF 1 "register_operand")))
4595 (clobber (reg:CC FLAGS_REG))])]
4596 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4597 {
4598 if (TARGET_FISTTP
4599 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4600 {
4601 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4602 DONE;
4603 }
4604 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4605 {
4606 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4607 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4608 if (out != operands[0])
4609 emit_move_insn (operands[0], out);
4610 DONE;
4611 }
4612 })
4613
4614 ;; Signed conversion to SImode.
4615
4616 (define_expand "fix_truncxfsi2"
4617 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4618 (fix:SI (match_operand:XF 1 "register_operand")))
4619 (clobber (reg:CC FLAGS_REG))])]
4620 "TARGET_80387"
4621 {
4622 if (TARGET_FISTTP)
4623 {
4624 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4625 DONE;
4626 }
4627 })
4628
4629 (define_expand "fix_trunc<mode>si2"
4630 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4631 (fix:SI (match_operand:MODEF 1 "register_operand")))
4632 (clobber (reg:CC FLAGS_REG))])]
4633 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4634 {
4635 if (TARGET_FISTTP
4636 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4637 {
4638 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4639 DONE;
4640 }
4641 if (SSE_FLOAT_MODE_P (<MODE>mode))
4642 {
4643 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4644 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4645 if (out != operands[0])
4646 emit_move_insn (operands[0], out);
4647 DONE;
4648 }
4649 })
4650
4651 ;; Signed conversion to HImode.
4652
4653 (define_expand "fix_trunc<mode>hi2"
4654 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4655 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4656 (clobber (reg:CC FLAGS_REG))])]
4657 "TARGET_80387
4658 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4659 {
4660 if (TARGET_FISTTP)
4661 {
4662 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
4663 DONE;
4664 }
4665 })
4666
4667 ;; Unsigned conversion to DImode
4668
4669 (define_insn "fixuns_trunc<mode>di2"
4670 [(set (match_operand:DI 0 "register_operand" "=r")
4671 (unsigned_fix:DI
4672 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4673 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4674 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4675 [(set_attr "type" "sseicvt")
4676 (set_attr "prefix" "evex")
4677 (set_attr "mode" "DI")])
4678
4679 ;; Unsigned conversion to SImode.
4680
4681 (define_expand "fixuns_trunc<mode>si2"
4682 [(parallel
4683 [(set (match_operand:SI 0 "register_operand")
4684 (unsigned_fix:SI
4685 (match_operand:MODEF 1 "nonimmediate_operand")))
4686 (use (match_dup 2))
4687 (clobber (scratch:<ssevecmode>))
4688 (clobber (scratch:<ssevecmode>))])]
4689 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
4690 {
4691 machine_mode mode = <MODE>mode;
4692 machine_mode vecmode = <ssevecmode>mode;
4693 REAL_VALUE_TYPE TWO31r;
4694 rtx two31;
4695
4696 if (TARGET_AVX512F)
4697 {
4698 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
4699 DONE;
4700 }
4701
4702 if (optimize_insn_for_size_p ())
4703 FAIL;
4704
4705 real_ldexp (&TWO31r, &dconst1, 31);
4706 two31 = const_double_from_real_value (TWO31r, mode);
4707 two31 = ix86_build_const_vector (vecmode, true, two31);
4708 operands[2] = force_reg (vecmode, two31);
4709 })
4710
4711 (define_insn "fixuns_trunc<mode>si2_avx512f"
4712 [(set (match_operand:SI 0 "register_operand" "=r")
4713 (unsigned_fix:SI
4714 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4715 "TARGET_AVX512F && TARGET_SSE_MATH"
4716 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4717 [(set_attr "type" "sseicvt")
4718 (set_attr "prefix" "evex")
4719 (set_attr "mode" "SI")])
4720
4721 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
4722 [(set (match_operand:DI 0 "register_operand" "=r")
4723 (zero_extend:DI
4724 (unsigned_fix:SI
4725 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
4726 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4727 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
4728 [(set_attr "type" "sseicvt")
4729 (set_attr "prefix" "evex")
4730 (set_attr "mode" "SI")])
4731
4732 (define_insn_and_split "*fixuns_trunc<mode>_1"
4733 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4734 (unsigned_fix:SI
4735 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4736 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4737 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4738 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4739 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4740 && optimize_function_for_speed_p (cfun)"
4741 "#"
4742 "&& reload_completed"
4743 [(const_int 0)]
4744 {
4745 ix86_split_convert_uns_si_sse (operands);
4746 DONE;
4747 })
4748
4749 ;; Unsigned conversion to HImode.
4750 ;; Without these patterns, we'll try the unsigned SI conversion which
4751 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4752
4753 (define_expand "fixuns_trunc<mode>hi2"
4754 [(set (match_dup 2)
4755 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4756 (set (match_operand:HI 0 "nonimmediate_operand")
4757 (subreg:HI (match_dup 2) 0))]
4758 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4759 "operands[2] = gen_reg_rtx (SImode);")
4760
4761 ;; When SSE is available, it is always faster to use it!
4762 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4763 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4764 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4765 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4766 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4767 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4768 [(set_attr "type" "sseicvt")
4769 (set_attr "prefix" "maybe_vex")
4770 (set (attr "prefix_rex")
4771 (if_then_else
4772 (match_test "<SWI48:MODE>mode == DImode")
4773 (const_string "1")
4774 (const_string "*")))
4775 (set_attr "mode" "<MODEF:MODE>")
4776 (set_attr "athlon_decode" "double,vector")
4777 (set_attr "amdfam10_decode" "double,double")
4778 (set_attr "bdver1_decode" "double,double")])
4779
4780 ;; Avoid vector decoded forms of the instruction.
4781 (define_peephole2
4782 [(match_scratch:MODEF 2 "x")
4783 (set (match_operand:SWI48 0 "register_operand")
4784 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4785 "TARGET_AVOID_VECTOR_DECODE
4786 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4787 && optimize_insn_for_speed_p ()"
4788 [(set (match_dup 2) (match_dup 1))
4789 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4790
4791 (define_insn "fix_trunc<mode>_i387_fisttp"
4792 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
4793 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4794 (clobber (match_scratch:XF 2 "=&f"))]
4795 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4796 && TARGET_FISTTP
4797 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4798 && (TARGET_64BIT || <MODE>mode != DImode))
4799 && TARGET_SSE_MATH)"
4800 "* return output_fix_trunc (insn, operands, true);"
4801 [(set_attr "type" "fisttp")
4802 (set_attr "mode" "<MODE>")])
4803
4804 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4805 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4806 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4807 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4808 ;; function in i386.c.
4809 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4810 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4811 (fix:SWI248x (match_operand 1 "register_operand")))
4812 (clobber (reg:CC FLAGS_REG))]
4813 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4814 && !TARGET_FISTTP
4815 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4816 && (TARGET_64BIT || <MODE>mode != DImode))
4817 && ix86_pre_reload_split ()"
4818 "#"
4819 "&& 1"
4820 [(const_int 0)]
4821 {
4822 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4823
4824 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4825 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4826
4827 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4828 operands[2], operands[3]));
4829 DONE;
4830 }
4831 [(set_attr "type" "fistp")
4832 (set_attr "i387_cw" "trunc")
4833 (set_attr "mode" "<MODE>")])
4834
4835 (define_insn "fix_truncdi_i387"
4836 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
4837 (fix:DI (match_operand 1 "register_operand" "f")))
4838 (use (match_operand:HI 2 "memory_operand" "m"))
4839 (use (match_operand:HI 3 "memory_operand" "m"))
4840 (clobber (match_scratch:XF 4 "=&f"))]
4841 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4842 && !TARGET_FISTTP
4843 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4844 "* return output_fix_trunc (insn, operands, false);"
4845 [(set_attr "type" "fistp")
4846 (set_attr "i387_cw" "trunc")
4847 (set_attr "mode" "DI")])
4848
4849 (define_insn "fix_trunc<mode>_i387"
4850 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
4851 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4852 (use (match_operand:HI 2 "memory_operand" "m"))
4853 (use (match_operand:HI 3 "memory_operand" "m"))]
4854 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4855 && !TARGET_FISTTP
4856 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4857 "* return output_fix_trunc (insn, operands, false);"
4858 [(set_attr "type" "fistp")
4859 (set_attr "i387_cw" "trunc")
4860 (set_attr "mode" "<MODE>")])
4861
4862 (define_insn "x86_fnstcw_1"
4863 [(set (match_operand:HI 0 "memory_operand" "=m")
4864 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
4865 "TARGET_80387"
4866 "fnstcw\t%0"
4867 [(set (attr "length")
4868 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4869 (set_attr "mode" "HI")
4870 (set_attr "unit" "i387")
4871 (set_attr "bdver1_decode" "vector")])
4872 \f
4873 ;; Conversion between fixed point and floating point.
4874
4875 ;; Even though we only accept memory inputs, the backend _really_
4876 ;; wants to be able to do this between registers. Thankfully, LRA
4877 ;; will fix this up for us during register allocation.
4878
4879 (define_insn "floathi<mode>2"
4880 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4881 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4882 "TARGET_80387
4883 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4884 || TARGET_MIX_SSE_I387)"
4885 "fild%Z1\t%1"
4886 [(set_attr "type" "fmov")
4887 (set_attr "mode" "<MODE>")
4888 (set_attr "znver1_decode" "double")
4889 (set_attr "fp_int_src" "true")])
4890
4891 (define_insn "float<SWI48x:mode>xf2"
4892 [(set (match_operand:XF 0 "register_operand" "=f")
4893 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4894 "TARGET_80387"
4895 "fild%Z1\t%1"
4896 [(set_attr "type" "fmov")
4897 (set_attr "mode" "XF")
4898 (set_attr "znver1_decode" "double")
4899 (set_attr "fp_int_src" "true")])
4900
4901 (define_expand "float<SWI48x:mode><MODEF:mode>2"
4902 [(set (match_operand:MODEF 0 "register_operand")
4903 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
4904 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
4905 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4906 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
4907
4908 (define_insn "*float<SWI48:mode><MODEF:mode>2"
4909 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
4910 (float:MODEF
4911 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4912 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4913 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4914 "@
4915 fild%Z1\t%1
4916 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4917 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4918 [(set_attr "type" "fmov,sseicvt,sseicvt")
4919 (set_attr "avx_partial_xmm_update" "false,true,true")
4920 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4921 (set_attr "mode" "<MODEF:MODE>")
4922 (set (attr "prefix_rex")
4923 (if_then_else
4924 (and (eq_attr "prefix" "maybe_vex")
4925 (match_test "<SWI48:MODE>mode == DImode"))
4926 (const_string "1")
4927 (const_string "*")))
4928 (set_attr "unit" "i387,*,*")
4929 (set_attr "athlon_decode" "*,double,direct")
4930 (set_attr "amdfam10_decode" "*,vector,double")
4931 (set_attr "bdver1_decode" "*,double,direct")
4932 (set_attr "znver1_decode" "double,*,*")
4933 (set_attr "fp_int_src" "true")
4934 (set (attr "enabled")
4935 (if_then_else
4936 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
4937 (if_then_else
4938 (eq_attr "alternative" "0")
4939 (symbol_ref "TARGET_MIX_SSE_I387
4940 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4941 <SWI48:MODE>mode)")
4942 (symbol_ref "true"))
4943 (if_then_else
4944 (eq_attr "alternative" "0")
4945 (symbol_ref "true")
4946 (symbol_ref "false"))))
4947 (set (attr "preferred_for_speed")
4948 (cond [(eq_attr "alternative" "1")
4949 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4950 (symbol_ref "true")))])
4951
4952 (define_insn "*floatdi<MODEF:mode>2_i387"
4953 [(set (match_operand:MODEF 0 "register_operand" "=f")
4954 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
4955 "!TARGET_64BIT
4956 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
4957 "fild%Z1\t%1"
4958 [(set_attr "type" "fmov")
4959 (set_attr "mode" "<MODEF:MODE>")
4960 (set_attr "znver1_decode" "double")
4961 (set_attr "fp_int_src" "true")])
4962
4963 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4964 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4965 ;; alternative in sse2_loadld.
4966 (define_split
4967 [(set (match_operand:MODEF 0 "sse_reg_operand")
4968 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4969 "TARGET_SSE2
4970 && TARGET_USE_VECTOR_CONVERTS
4971 && optimize_function_for_speed_p (cfun)
4972 && reload_completed
4973 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
4974 && (!EXT_REX_SSE_REG_P (operands[0])
4975 || TARGET_AVX512VL)"
4976 [(const_int 0)]
4977 {
4978 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
4979 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
4980
4981 emit_insn (gen_sse2_loadld (operands[4],
4982 CONST0_RTX (V4SImode), operands[1]));
4983
4984 if (<ssevecmode>mode == V4SFmode)
4985 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4986 else
4987 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4988 DONE;
4989 })
4990
4991 ;; Avoid store forwarding (partial memory) stall penalty
4992 ;; by passing DImode value through XMM registers. */
4993
4994 (define_split
4995 [(set (match_operand:X87MODEF 0 "register_operand")
4996 (float:X87MODEF
4997 (match_operand:DI 1 "register_operand")))]
4998 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
4999 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5000 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5001 && can_create_pseudo_p ()"
5002 [(const_int 0)]
5003 {
5004 emit_insn (gen_floatdi<mode>2_i387_with_xmm
5005 (operands[0], operands[1],
5006 assign_386_stack_local (DImode, SLOT_TEMP)));
5007 DONE;
5008 })
5009
5010 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5011 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5012 (float:X87MODEF
5013 (match_operand:DI 1 "register_operand" "r,r")))
5014 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5015 (clobber (match_scratch:V4SI 3 "=x,x"))
5016 (clobber (match_scratch:V4SI 4 "=X,x"))]
5017 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5018 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5019 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5020 "#"
5021 "&& reload_completed"
5022 [(set (match_dup 2) (match_dup 3))
5023 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5024 {
5025 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5026 Assemble the 64-bit DImode value in an xmm register. */
5027 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5028 gen_lowpart (SImode, operands[1])));
5029 if (TARGET_SSE4_1)
5030 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5031 gen_highpart (SImode, operands[1]),
5032 GEN_INT (2)));
5033 else
5034 {
5035 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5036 gen_highpart (SImode, operands[1])));
5037 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5038 operands[4]));
5039 }
5040 operands[3] = gen_lowpart (DImode, operands[3]);
5041 }
5042 [(set_attr "isa" "sse4,*")
5043 (set_attr "type" "multi")
5044 (set_attr "mode" "<X87MODEF:MODE>")
5045 (set_attr "unit" "i387")
5046 (set_attr "fp_int_src" "true")])
5047
5048 ;; Break partial SSE register dependency stall. This splitter should split
5049 ;; late in the pass sequence (after register rename pass), so allocated
5050 ;; registers won't change anymore
5051
5052 (define_split
5053 [(set (match_operand:MODEF 0 "sse_reg_operand")
5054 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5055 "!TARGET_AVX
5056 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5057 && optimize_function_for_speed_p (cfun)
5058 && (!EXT_REX_SSE_REG_P (operands[0])
5059 || TARGET_AVX512VL)"
5060 [(set (match_dup 0)
5061 (vec_merge:<MODEF:ssevecmode>
5062 (vec_duplicate:<MODEF:ssevecmode>
5063 (float:MODEF
5064 (match_dup 1)))
5065 (match_dup 0)
5066 (const_int 1)))]
5067 {
5068 const machine_mode vmode = <MODEF:ssevecmode>mode;
5069
5070 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5071 emit_move_insn (operands[0], CONST0_RTX (vmode));
5072 })
5073
5074 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5075 [(set (match_operand:MODEF 0 "register_operand")
5076 (unsigned_float:MODEF
5077 (match_operand:SWI12 1 "nonimmediate_operand")))]
5078 "!TARGET_64BIT
5079 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5080 {
5081 operands[1] = convert_to_mode (SImode, operands[1], 1);
5082 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5083 DONE;
5084 })
5085
5086 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5087 [(set (match_operand:MODEF 0 "register_operand" "=v")
5088 (unsigned_float:MODEF
5089 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5090 "TARGET_AVX512F && TARGET_SSE_MATH"
5091 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5092 [(set_attr "type" "sseicvt")
5093 (set_attr "avx_partial_xmm_update" "true")
5094 (set_attr "prefix" "evex")
5095 (set_attr "mode" "<MODEF:MODE>")])
5096
5097 ;; Avoid store forwarding (partial memory) stall penalty by extending
5098 ;; SImode value to DImode through XMM register instead of pushing two
5099 ;; SImode values to stack. Also note that fild loads from memory only.
5100
5101 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5102 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5103 (unsigned_float:X87MODEF
5104 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5105 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5106 (clobber (match_scratch:DI 3 "=x"))]
5107 "!TARGET_64BIT
5108 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5109 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5110 "#"
5111 "&& reload_completed"
5112 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5113 (set (match_dup 2) (match_dup 3))
5114 (set (match_dup 0)
5115 (float:X87MODEF (match_dup 2)))]
5116 ""
5117 [(set_attr "type" "multi")
5118 (set_attr "mode" "<MODE>")])
5119
5120 (define_expand "floatunssi<mode>2"
5121 [(set (match_operand:X87MODEF 0 "register_operand")
5122 (unsigned_float:X87MODEF
5123 (match_operand:SI 1 "nonimmediate_operand")))]
5124 "(!TARGET_64BIT
5125 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5126 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5127 || ((!TARGET_64BIT || TARGET_AVX512F)
5128 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5129 {
5130 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5131 {
5132 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5133 (operands[0], operands[1],
5134 assign_386_stack_local (DImode, SLOT_TEMP)));
5135 DONE;
5136 }
5137 if (!TARGET_AVX512F)
5138 {
5139 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5140 DONE;
5141 }
5142 })
5143
5144 (define_expand "floatunsdisf2"
5145 [(set (match_operand:SF 0 "register_operand")
5146 (unsigned_float:SF
5147 (match_operand:DI 1 "nonimmediate_operand")))]
5148 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5149 {
5150 if (!TARGET_AVX512F)
5151 {
5152 x86_emit_floatuns (operands);
5153 DONE;
5154 }
5155 })
5156
5157 (define_expand "floatunsdidf2"
5158 [(set (match_operand:DF 0 "register_operand")
5159 (unsigned_float:DF
5160 (match_operand:DI 1 "nonimmediate_operand")))]
5161 "((TARGET_64BIT && TARGET_AVX512F)
5162 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5163 && TARGET_SSE2 && TARGET_SSE_MATH"
5164 {
5165 if (!TARGET_64BIT)
5166 {
5167 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5168 DONE;
5169 }
5170 if (!TARGET_AVX512F)
5171 {
5172 x86_emit_floatuns (operands);
5173 DONE;
5174 }
5175 })
5176 \f
5177 ;; Load effective address instructions
5178
5179 (define_insn_and_split "*lea<mode>"
5180 [(set (match_operand:SWI48 0 "register_operand" "=r")
5181 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5182 "ix86_hardreg_mov_ok (operands[0], operands[1])"
5183 {
5184 if (SImode_address_operand (operands[1], VOIDmode))
5185 {
5186 gcc_assert (TARGET_64BIT);
5187 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5188 }
5189 else
5190 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5191 }
5192 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5193 [(const_int 0)]
5194 {
5195 machine_mode mode = <MODE>mode;
5196 rtx pat;
5197
5198 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5199 change operands[] array behind our back. */
5200 pat = PATTERN (curr_insn);
5201
5202 operands[0] = SET_DEST (pat);
5203 operands[1] = SET_SRC (pat);
5204
5205 /* Emit all operations in SImode for zero-extended addresses. */
5206 if (SImode_address_operand (operands[1], VOIDmode))
5207 mode = SImode;
5208
5209 ix86_split_lea_for_addr (curr_insn, operands, mode);
5210
5211 /* Zero-extend return register to DImode for zero-extended addresses. */
5212 if (mode != <MODE>mode)
5213 emit_insn (gen_zero_extendsidi2
5214 (operands[0], gen_lowpart (mode, operands[0])));
5215
5216 DONE;
5217 }
5218 [(set_attr "type" "lea")
5219 (set (attr "mode")
5220 (if_then_else
5221 (match_operand 1 "SImode_address_operand")
5222 (const_string "SI")
5223 (const_string "<MODE>")))])
5224 \f
5225 ;; Add instructions
5226
5227 (define_expand "add<mode>3"
5228 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5229 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5230 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5231 ""
5232 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5233
5234 (define_insn_and_split "*add<dwi>3_doubleword"
5235 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
5236 (plus:<DWI>
5237 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5238 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
5239 (clobber (reg:CC FLAGS_REG))]
5240 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5241 "#"
5242 "reload_completed"
5243 [(parallel [(set (reg:CCC FLAGS_REG)
5244 (compare:CCC
5245 (plus:DWIH (match_dup 1) (match_dup 2))
5246 (match_dup 1)))
5247 (set (match_dup 0)
5248 (plus:DWIH (match_dup 1) (match_dup 2)))])
5249 (parallel [(set (match_dup 3)
5250 (plus:DWIH
5251 (plus:DWIH
5252 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5253 (match_dup 4))
5254 (match_dup 5)))
5255 (clobber (reg:CC FLAGS_REG))])]
5256 {
5257 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5258 if (operands[2] == const0_rtx)
5259 {
5260 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5261 DONE;
5262 }
5263 })
5264
5265 (define_insn "*add<mode>_1"
5266 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
5267 (plus:SWI48
5268 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5269 (match_operand:SWI48 2 "x86_64_general_operand" "re,m,0,le")))
5270 (clobber (reg:CC FLAGS_REG))]
5271 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5272 {
5273 switch (get_attr_type (insn))
5274 {
5275 case TYPE_LEA:
5276 return "#";
5277
5278 case TYPE_INCDEC:
5279 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5280 if (operands[2] == const1_rtx)
5281 return "inc{<imodesuffix>}\t%0";
5282 else
5283 {
5284 gcc_assert (operands[2] == constm1_rtx);
5285 return "dec{<imodesuffix>}\t%0";
5286 }
5287
5288 default:
5289 /* For most processors, ADD is faster than LEA. This alternative
5290 was added to use ADD as much as possible. */
5291 if (which_alternative == 2)
5292 std::swap (operands[1], operands[2]);
5293
5294 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5295 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5296 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5297
5298 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5299 }
5300 }
5301 [(set (attr "type")
5302 (cond [(eq_attr "alternative" "3")
5303 (const_string "lea")
5304 (match_operand:SWI48 2 "incdec_operand")
5305 (const_string "incdec")
5306 ]
5307 (const_string "alu")))
5308 (set (attr "length_immediate")
5309 (if_then_else
5310 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5311 (const_string "1")
5312 (const_string "*")))
5313 (set_attr "mode" "<MODE>")])
5314
5315 ;; It may seem that nonimmediate operand is proper one for operand 1.
5316 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5317 ;; we take care in ix86_binary_operator_ok to not allow two memory
5318 ;; operands so proper swapping will be done in reload. This allow
5319 ;; patterns constructed from addsi_1 to match.
5320
5321 (define_insn "addsi_1_zext"
5322 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5323 (zero_extend:DI
5324 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5325 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5326 (clobber (reg:CC FLAGS_REG))]
5327 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5328 {
5329 switch (get_attr_type (insn))
5330 {
5331 case TYPE_LEA:
5332 return "#";
5333
5334 case TYPE_INCDEC:
5335 if (operands[2] == const1_rtx)
5336 return "inc{l}\t%k0";
5337 else
5338 {
5339 gcc_assert (operands[2] == constm1_rtx);
5340 return "dec{l}\t%k0";
5341 }
5342
5343 default:
5344 /* For most processors, ADD is faster than LEA. This alternative
5345 was added to use ADD as much as possible. */
5346 if (which_alternative == 1)
5347 std::swap (operands[1], operands[2]);
5348
5349 if (x86_maybe_negate_const_int (&operands[2], SImode))
5350 return "sub{l}\t{%2, %k0|%k0, %2}";
5351
5352 return "add{l}\t{%2, %k0|%k0, %2}";
5353 }
5354 }
5355 [(set (attr "type")
5356 (cond [(eq_attr "alternative" "2")
5357 (const_string "lea")
5358 (match_operand:SI 2 "incdec_operand")
5359 (const_string "incdec")
5360 ]
5361 (const_string "alu")))
5362 (set (attr "length_immediate")
5363 (if_then_else
5364 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5365 (const_string "1")
5366 (const_string "*")))
5367 (set_attr "mode" "SI")])
5368
5369 (define_insn "*addhi_1"
5370 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5371 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5372 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
5373 (clobber (reg:CC FLAGS_REG))]
5374 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5375 {
5376 switch (get_attr_type (insn))
5377 {
5378 case TYPE_LEA:
5379 return "#";
5380
5381 case TYPE_INCDEC:
5382 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5383 if (operands[2] == const1_rtx)
5384 return "inc{w}\t%0";
5385 else
5386 {
5387 gcc_assert (operands[2] == constm1_rtx);
5388 return "dec{w}\t%0";
5389 }
5390
5391 default:
5392 /* For most processors, ADD is faster than LEA. This alternative
5393 was added to use ADD as much as possible. */
5394 if (which_alternative == 2)
5395 std::swap (operands[1], operands[2]);
5396
5397 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5398 if (x86_maybe_negate_const_int (&operands[2], HImode))
5399 return "sub{w}\t{%2, %0|%0, %2}";
5400
5401 return "add{w}\t{%2, %0|%0, %2}";
5402 }
5403 }
5404 [(set (attr "type")
5405 (cond [(eq_attr "alternative" "3")
5406 (const_string "lea")
5407 (match_operand:HI 2 "incdec_operand")
5408 (const_string "incdec")
5409 ]
5410 (const_string "alu")))
5411 (set (attr "length_immediate")
5412 (if_then_else
5413 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5414 (const_string "1")
5415 (const_string "*")))
5416 (set_attr "mode" "HI,HI,HI,SI")])
5417
5418 (define_insn "*addqi_1"
5419 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5420 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5421 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
5422 (clobber (reg:CC FLAGS_REG))]
5423 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5424 {
5425 bool widen = (get_attr_mode (insn) != MODE_QI);
5426
5427 switch (get_attr_type (insn))
5428 {
5429 case TYPE_LEA:
5430 return "#";
5431
5432 case TYPE_INCDEC:
5433 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5434 if (operands[2] == const1_rtx)
5435 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5436 else
5437 {
5438 gcc_assert (operands[2] == constm1_rtx);
5439 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5440 }
5441
5442 default:
5443 /* For most processors, ADD is faster than LEA. These alternatives
5444 were added to use ADD as much as possible. */
5445 if (which_alternative == 2 || which_alternative == 4)
5446 std::swap (operands[1], operands[2]);
5447
5448 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5449 if (x86_maybe_negate_const_int (&operands[2], QImode))
5450 {
5451 if (widen)
5452 return "sub{l}\t{%2, %k0|%k0, %2}";
5453 else
5454 return "sub{b}\t{%2, %0|%0, %2}";
5455 }
5456 if (widen)
5457 return "add{l}\t{%k2, %k0|%k0, %k2}";
5458 else
5459 return "add{b}\t{%2, %0|%0, %2}";
5460 }
5461 }
5462 [(set (attr "type")
5463 (cond [(eq_attr "alternative" "5")
5464 (const_string "lea")
5465 (match_operand:QI 2 "incdec_operand")
5466 (const_string "incdec")
5467 ]
5468 (const_string "alu")))
5469 (set (attr "length_immediate")
5470 (if_then_else
5471 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5472 (const_string "1")
5473 (const_string "*")))
5474 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5475 ;; Potential partial reg stall on alternatives 3 and 4.
5476 (set (attr "preferred_for_speed")
5477 (cond [(eq_attr "alternative" "3,4")
5478 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5479 (symbol_ref "true")))])
5480
5481 (define_insn "*add<mode>_1_slp"
5482 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
5483 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
5484 (match_operand:SWI12 2 "general_operand" "<r>mn")))
5485 (clobber (reg:CC FLAGS_REG))]
5486 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5487 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
5488 && (rtx_equal_p (operands[0], operands[1])
5489 || rtx_equal_p (operands[0], operands[2]))"
5490 {
5491 switch (get_attr_type (insn))
5492 {
5493 case TYPE_INCDEC:
5494 if (operands[2] == const1_rtx)
5495 return "inc{<imodesuffix>}\t%0";
5496 else
5497 {
5498 gcc_assert (operands[2] == constm1_rtx);
5499 return "dec{<imodesuffix>}\t%0";
5500 }
5501
5502 default:
5503 if (x86_maybe_negate_const_int (&operands[2], QImode))
5504 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5505
5506 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5507 }
5508 }
5509 [(set (attr "type")
5510 (if_then_else (match_operand:QI 2 "incdec_operand")
5511 (const_string "incdec")
5512 (const_string "alu")))
5513 (set_attr "mode" "<MODE>")])
5514
5515 ;; Split non destructive adds if we cannot use lea.
5516 (define_split
5517 [(set (match_operand:SWI48 0 "register_operand")
5518 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5519 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5520 (clobber (reg:CC FLAGS_REG))]
5521 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5522 [(set (match_dup 0) (match_dup 1))
5523 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5524 (clobber (reg:CC FLAGS_REG))])])
5525
5526 ;; Split non destructive adds if we cannot use lea.
5527 (define_split
5528 [(set (match_operand:DI 0 "register_operand")
5529 (zero_extend:DI
5530 (plus:SI (match_operand:SI 1 "register_operand")
5531 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5532 (clobber (reg:CC FLAGS_REG))]
5533 "TARGET_64BIT
5534 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5535 [(set (match_dup 3) (match_dup 1))
5536 (parallel [(set (match_dup 0)
5537 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5538 (clobber (reg:CC FLAGS_REG))])]
5539 "operands[3] = gen_lowpart (SImode, operands[0]);")
5540
5541 ;; Convert add to the lea pattern to avoid flags dependency.
5542 (define_split
5543 [(set (match_operand:SWI 0 "register_operand")
5544 (plus:SWI (match_operand:SWI 1 "register_operand")
5545 (match_operand:SWI 2 "<nonmemory_operand>")))
5546 (clobber (reg:CC FLAGS_REG))]
5547 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5548 [(set (match_dup 0)
5549 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5550 {
5551 if (<MODE>mode != <LEAMODE>mode)
5552 {
5553 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5554 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5555 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5556 }
5557 })
5558
5559 ;; Convert add to the lea pattern to avoid flags dependency.
5560 (define_split
5561 [(set (match_operand:DI 0 "register_operand")
5562 (zero_extend:DI
5563 (plus:SI (match_operand:SI 1 "register_operand")
5564 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5565 (clobber (reg:CC FLAGS_REG))]
5566 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5567 [(set (match_dup 0)
5568 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5569
5570 (define_insn "*add<mode>_2"
5571 [(set (reg FLAGS_REG)
5572 (compare
5573 (plus:SWI
5574 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5575 (match_operand:SWI 2 "<general_operand>" "<r><i>,m,0"))
5576 (const_int 0)))
5577 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
5578 (plus:SWI (match_dup 1) (match_dup 2)))]
5579 "ix86_match_ccmode (insn, CCGOCmode)
5580 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5581 {
5582 switch (get_attr_type (insn))
5583 {
5584 case TYPE_INCDEC:
5585 if (operands[2] == const1_rtx)
5586 return "inc{<imodesuffix>}\t%0";
5587 else
5588 {
5589 gcc_assert (operands[2] == constm1_rtx);
5590 return "dec{<imodesuffix>}\t%0";
5591 }
5592
5593 default:
5594 if (which_alternative == 2)
5595 std::swap (operands[1], operands[2]);
5596
5597 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5598 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5599 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5600
5601 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5602 }
5603 }
5604 [(set (attr "type")
5605 (if_then_else (match_operand:SWI 2 "incdec_operand")
5606 (const_string "incdec")
5607 (const_string "alu")))
5608 (set (attr "length_immediate")
5609 (if_then_else
5610 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5611 (const_string "1")
5612 (const_string "*")))
5613 (set_attr "mode" "<MODE>")])
5614
5615 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5616 (define_insn "*addsi_2_zext"
5617 [(set (reg FLAGS_REG)
5618 (compare
5619 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5620 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5621 (const_int 0)))
5622 (set (match_operand:DI 0 "register_operand" "=r,r")
5623 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5624 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5625 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5626 {
5627 switch (get_attr_type (insn))
5628 {
5629 case TYPE_INCDEC:
5630 if (operands[2] == const1_rtx)
5631 return "inc{l}\t%k0";
5632 else
5633 {
5634 gcc_assert (operands[2] == constm1_rtx);
5635 return "dec{l}\t%k0";
5636 }
5637
5638 default:
5639 if (which_alternative == 1)
5640 std::swap (operands[1], operands[2]);
5641
5642 if (x86_maybe_negate_const_int (&operands[2], SImode))
5643 return "sub{l}\t{%2, %k0|%k0, %2}";
5644
5645 return "add{l}\t{%2, %k0|%k0, %2}";
5646 }
5647 }
5648 [(set (attr "type")
5649 (if_then_else (match_operand:SI 2 "incdec_operand")
5650 (const_string "incdec")
5651 (const_string "alu")))
5652 (set (attr "length_immediate")
5653 (if_then_else
5654 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5655 (const_string "1")
5656 (const_string "*")))
5657 (set_attr "mode" "SI")])
5658
5659 (define_insn "*add<mode>_3"
5660 [(set (reg FLAGS_REG)
5661 (compare
5662 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5663 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5664 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5665 "ix86_match_ccmode (insn, CCZmode)
5666 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5667 {
5668 switch (get_attr_type (insn))
5669 {
5670 case TYPE_INCDEC:
5671 if (operands[2] == const1_rtx)
5672 return "inc{<imodesuffix>}\t%0";
5673 else
5674 {
5675 gcc_assert (operands[2] == constm1_rtx);
5676 return "dec{<imodesuffix>}\t%0";
5677 }
5678
5679 default:
5680 if (which_alternative == 1)
5681 std::swap (operands[1], operands[2]);
5682
5683 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5684 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5685 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5686
5687 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5688 }
5689 }
5690 [(set (attr "type")
5691 (if_then_else (match_operand:SWI 2 "incdec_operand")
5692 (const_string "incdec")
5693 (const_string "alu")))
5694 (set (attr "length_immediate")
5695 (if_then_else
5696 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5697 (const_string "1")
5698 (const_string "*")))
5699 (set_attr "mode" "<MODE>")])
5700
5701 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5702 (define_insn "*addsi_3_zext"
5703 [(set (reg FLAGS_REG)
5704 (compare
5705 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5706 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5707 (set (match_operand:DI 0 "register_operand" "=r,r")
5708 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5709 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5710 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5711 {
5712 switch (get_attr_type (insn))
5713 {
5714 case TYPE_INCDEC:
5715 if (operands[2] == const1_rtx)
5716 return "inc{l}\t%k0";
5717 else
5718 {
5719 gcc_assert (operands[2] == constm1_rtx);
5720 return "dec{l}\t%k0";
5721 }
5722
5723 default:
5724 if (which_alternative == 1)
5725 std::swap (operands[1], operands[2]);
5726
5727 if (x86_maybe_negate_const_int (&operands[2], SImode))
5728 return "sub{l}\t{%2, %k0|%k0, %2}";
5729
5730 return "add{l}\t{%2, %k0|%k0, %2}";
5731 }
5732 }
5733 [(set (attr "type")
5734 (if_then_else (match_operand:SI 2 "incdec_operand")
5735 (const_string "incdec")
5736 (const_string "alu")))
5737 (set (attr "length_immediate")
5738 (if_then_else
5739 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5740 (const_string "1")
5741 (const_string "*")))
5742 (set_attr "mode" "SI")])
5743
5744 ; For comparisons against 1, -1 and 128, we may generate better code
5745 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5746 ; is matched then. We can't accept general immediate, because for
5747 ; case of overflows, the result is messed up.
5748 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5749 ; only for comparisons not depending on it.
5750
5751 (define_insn "*adddi_4"
5752 [(set (reg FLAGS_REG)
5753 (compare
5754 (match_operand:DI 1 "nonimmediate_operand" "0")
5755 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5756 (clobber (match_scratch:DI 0 "=r"))]
5757 "TARGET_64BIT
5758 && ix86_match_ccmode (insn, CCGCmode)"
5759 {
5760 switch (get_attr_type (insn))
5761 {
5762 case TYPE_INCDEC:
5763 if (operands[2] == constm1_rtx)
5764 return "inc{q}\t%0";
5765 else
5766 {
5767 gcc_assert (operands[2] == const1_rtx);
5768 return "dec{q}\t%0";
5769 }
5770
5771 default:
5772 if (x86_maybe_negate_const_int (&operands[2], DImode))
5773 return "add{q}\t{%2, %0|%0, %2}";
5774
5775 return "sub{q}\t{%2, %0|%0, %2}";
5776 }
5777 }
5778 [(set (attr "type")
5779 (if_then_else (match_operand:DI 2 "incdec_operand")
5780 (const_string "incdec")
5781 (const_string "alu")))
5782 (set (attr "length_immediate")
5783 (if_then_else
5784 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5785 (const_string "1")
5786 (const_string "*")))
5787 (set_attr "mode" "DI")])
5788
5789 ; For comparisons against 1, -1 and 128, we may generate better code
5790 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5791 ; is matched then. We can't accept general immediate, because for
5792 ; case of overflows, the result is messed up.
5793 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5794 ; only for comparisons not depending on it.
5795
5796 (define_insn "*add<mode>_4"
5797 [(set (reg FLAGS_REG)
5798 (compare
5799 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5800 (match_operand:SWI124 2 "const_int_operand" "n")))
5801 (clobber (match_scratch:SWI124 0 "=<r>"))]
5802 "ix86_match_ccmode (insn, CCGCmode)"
5803 {
5804 switch (get_attr_type (insn))
5805 {
5806 case TYPE_INCDEC:
5807 if (operands[2] == constm1_rtx)
5808 return "inc{<imodesuffix>}\t%0";
5809 else
5810 {
5811 gcc_assert (operands[2] == const1_rtx);
5812 return "dec{<imodesuffix>}\t%0";
5813 }
5814
5815 default:
5816 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5817 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5818
5819 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5820 }
5821 }
5822 [(set (attr "type")
5823 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5824 (const_string "incdec")
5825 (const_string "alu")))
5826 (set (attr "length_immediate")
5827 (if_then_else
5828 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5829 (const_string "1")
5830 (const_string "*")))
5831 (set_attr "mode" "<MODE>")])
5832
5833 (define_insn "*add<mode>_5"
5834 [(set (reg FLAGS_REG)
5835 (compare
5836 (plus:SWI
5837 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5838 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5839 (const_int 0)))
5840 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5841 "ix86_match_ccmode (insn, CCGOCmode)
5842 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5843 {
5844 switch (get_attr_type (insn))
5845 {
5846 case TYPE_INCDEC:
5847 if (operands[2] == const1_rtx)
5848 return "inc{<imodesuffix>}\t%0";
5849 else
5850 {
5851 gcc_assert (operands[2] == constm1_rtx);
5852 return "dec{<imodesuffix>}\t%0";
5853 }
5854
5855 default:
5856 if (which_alternative == 1)
5857 std::swap (operands[1], operands[2]);
5858
5859 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5860 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5861 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5862
5863 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5864 }
5865 }
5866 [(set (attr "type")
5867 (if_then_else (match_operand:SWI 2 "incdec_operand")
5868 (const_string "incdec")
5869 (const_string "alu")))
5870 (set (attr "length_immediate")
5871 (if_then_else
5872 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5873 (const_string "1")
5874 (const_string "*")))
5875 (set_attr "mode" "<MODE>")])
5876
5877 (define_expand "addqi_ext_1"
5878 [(parallel
5879 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
5880 (const_int 8)
5881 (const_int 8))
5882 (subreg:HI
5883 (plus:QI
5884 (subreg:QI
5885 (zero_extract:HI (match_operand:HI 1 "register_operand")
5886 (const_int 8)
5887 (const_int 8)) 0)
5888 (match_operand:QI 2 "const_int_operand")) 0))
5889 (clobber (reg:CC FLAGS_REG))])])
5890
5891 (define_insn "*addqi_ext<mode>_1"
5892 [(set (zero_extract:SWI248
5893 (match_operand:SWI248 0 "register_operand" "+Q,Q")
5894 (const_int 8)
5895 (const_int 8))
5896 (subreg:SWI248
5897 (plus:QI
5898 (subreg:QI
5899 (zero_extract:SWI248
5900 (match_operand:SWI248 1 "register_operand" "0,0")
5901 (const_int 8)
5902 (const_int 8)) 0)
5903 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
5904 (clobber (reg:CC FLAGS_REG))]
5905 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
5906 rtx_equal_p (operands[0], operands[1])"
5907 {
5908 switch (get_attr_type (insn))
5909 {
5910 case TYPE_INCDEC:
5911 if (operands[2] == const1_rtx)
5912 return "inc{b}\t%h0";
5913 else
5914 {
5915 gcc_assert (operands[2] == constm1_rtx);
5916 return "dec{b}\t%h0";
5917 }
5918
5919 default:
5920 return "add{b}\t{%2, %h0|%h0, %2}";
5921 }
5922 }
5923 [(set_attr "isa" "*,nox64")
5924 (set (attr "type")
5925 (if_then_else (match_operand:QI 2 "incdec_operand")
5926 (const_string "incdec")
5927 (const_string "alu")))
5928 (set_attr "mode" "QI")])
5929
5930 (define_insn "*addqi_ext<mode>_2"
5931 [(set (zero_extract:SWI248
5932 (match_operand:SWI248 0 "register_operand" "+Q")
5933 (const_int 8)
5934 (const_int 8))
5935 (subreg:SWI248
5936 (plus:QI
5937 (subreg:QI
5938 (zero_extract:SWI248
5939 (match_operand:SWI248 1 "register_operand" "%0")
5940 (const_int 8)
5941 (const_int 8)) 0)
5942 (subreg:QI
5943 (zero_extract:SWI248
5944 (match_operand:SWI248 2 "register_operand" "Q")
5945 (const_int 8)
5946 (const_int 8)) 0)) 0))
5947 (clobber (reg:CC FLAGS_REG))]
5948 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
5949 rtx_equal_p (operands[0], operands[1])
5950 || rtx_equal_p (operands[0], operands[2])"
5951 "add{b}\t{%h2, %h0|%h0, %h2}"
5952 [(set_attr "type" "alu")
5953 (set_attr "mode" "QI")])
5954
5955 ;; Like DWI, but use POImode instead of OImode.
5956 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
5957
5958 ;; Add with jump on overflow.
5959 (define_expand "addv<mode>4"
5960 [(parallel [(set (reg:CCO FLAGS_REG)
5961 (eq:CCO
5962 (plus:<DPWI>
5963 (sign_extend:<DPWI>
5964 (match_operand:SWIDWI 1 "nonimmediate_operand"))
5965 (match_dup 4))
5966 (sign_extend:<DPWI>
5967 (plus:SWIDWI (match_dup 1)
5968 (match_operand:SWIDWI 2
5969 "<general_hilo_operand>")))))
5970 (set (match_operand:SWIDWI 0 "register_operand")
5971 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
5972 (set (pc) (if_then_else
5973 (eq (reg:CCO FLAGS_REG) (const_int 0))
5974 (label_ref (match_operand 3))
5975 (pc)))]
5976 ""
5977 {
5978 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5979 if (CONST_SCALAR_INT_P (operands[2]))
5980 operands[4] = operands[2];
5981 else
5982 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
5983 })
5984
5985 (define_insn "*addv<mode>4"
5986 [(set (reg:CCO FLAGS_REG)
5987 (eq:CCO (plus:<DWI>
5988 (sign_extend:<DWI>
5989 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5990 (sign_extend:<DWI>
5991 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
5992 (sign_extend:<DWI>
5993 (plus:SWI (match_dup 1) (match_dup 2)))))
5994 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5995 (plus:SWI (match_dup 1) (match_dup 2)))]
5996 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5997 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5998 [(set_attr "type" "alu")
5999 (set_attr "mode" "<MODE>")])
6000
6001 (define_insn "addv<mode>4_1"
6002 [(set (reg:CCO FLAGS_REG)
6003 (eq:CCO (plus:<DWI>
6004 (sign_extend:<DWI>
6005 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6006 (match_operand:<DWI> 3 "const_int_operand" "i"))
6007 (sign_extend:<DWI>
6008 (plus:SWI
6009 (match_dup 1)
6010 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6011 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6012 (plus:SWI (match_dup 1) (match_dup 2)))]
6013 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6014 && CONST_INT_P (operands[2])
6015 && INTVAL (operands[2]) == INTVAL (operands[3])"
6016 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6017 [(set_attr "type" "alu")
6018 (set_attr "mode" "<MODE>")
6019 (set (attr "length_immediate")
6020 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6021 (const_string "1")
6022 (match_test "<MODE_SIZE> == 8")
6023 (const_string "4")]
6024 (const_string "<MODE_SIZE>")))])
6025
6026 ;; Quad word integer modes as mode attribute.
6027 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
6028
6029 (define_insn_and_split "*addv<dwi>4_doubleword"
6030 [(set (reg:CCO FLAGS_REG)
6031 (eq:CCO
6032 (plus:<QPWI>
6033 (sign_extend:<QPWI>
6034 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
6035 (sign_extend:<QPWI>
6036 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
6037 (sign_extend:<QPWI>
6038 (plus:<DWI> (match_dup 1) (match_dup 2)))))
6039 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6040 (plus:<DWI> (match_dup 1) (match_dup 2)))]
6041 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6042 "#"
6043 "reload_completed"
6044 [(parallel [(set (reg:CCC FLAGS_REG)
6045 (compare:CCC
6046 (plus:DWIH (match_dup 1) (match_dup 2))
6047 (match_dup 1)))
6048 (set (match_dup 0)
6049 (plus:DWIH (match_dup 1) (match_dup 2)))])
6050 (parallel [(set (reg:CCO FLAGS_REG)
6051 (eq:CCO
6052 (plus:<DWI>
6053 (plus:<DWI>
6054 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6055 (sign_extend:<DWI> (match_dup 4)))
6056 (sign_extend:<DWI> (match_dup 5)))
6057 (sign_extend:<DWI>
6058 (plus:DWIH
6059 (plus:DWIH
6060 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6061 (match_dup 4))
6062 (match_dup 5)))))
6063 (set (match_dup 3)
6064 (plus:DWIH
6065 (plus:DWIH
6066 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6067 (match_dup 4))
6068 (match_dup 5)))])]
6069 {
6070 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6071 })
6072
6073 (define_insn_and_split "*addv<dwi>4_doubleword_1"
6074 [(set (reg:CCO FLAGS_REG)
6075 (eq:CCO
6076 (plus:<QPWI>
6077 (sign_extend:<QPWI>
6078 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
6079 (match_operand:<QPWI> 3 "const_scalar_int_operand" ""))
6080 (sign_extend:<QPWI>
6081 (plus:<DWI>
6082 (match_dup 1)
6083 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
6084 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
6085 (plus:<DWI> (match_dup 1) (match_dup 2)))]
6086 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
6087 && CONST_SCALAR_INT_P (operands[2])
6088 && rtx_equal_p (operands[2], operands[3])"
6089 "#"
6090 "reload_completed"
6091 [(parallel [(set (reg:CCC FLAGS_REG)
6092 (compare:CCC
6093 (plus:DWIH (match_dup 1) (match_dup 2))
6094 (match_dup 1)))
6095 (set (match_dup 0)
6096 (plus:DWIH (match_dup 1) (match_dup 2)))])
6097 (parallel [(set (reg:CCO FLAGS_REG)
6098 (eq:CCO
6099 (plus:<DWI>
6100 (plus:<DWI>
6101 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6102 (sign_extend:<DWI> (match_dup 4)))
6103 (match_dup 5))
6104 (sign_extend:<DWI>
6105 (plus:DWIH
6106 (plus:DWIH
6107 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6108 (match_dup 4))
6109 (match_dup 5)))))
6110 (set (match_dup 3)
6111 (plus:DWIH
6112 (plus:DWIH
6113 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6114 (match_dup 4))
6115 (match_dup 5)))])]
6116 {
6117 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6118 if (operands[2] == const0_rtx)
6119 {
6120 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
6121 operands[5]));
6122 DONE;
6123 }
6124 })
6125
6126 (define_insn "*addv<mode>4_overflow_1"
6127 [(set (reg:CCO FLAGS_REG)
6128 (eq:CCO
6129 (plus:<DWI>
6130 (plus:<DWI>
6131 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6132 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6133 (sign_extend:<DWI>
6134 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
6135 (sign_extend:<DWI>
6136 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
6137 (sign_extend:<DWI>
6138 (plus:SWI
6139 (plus:SWI
6140 (match_operator:SWI 5 "ix86_carry_flag_operator"
6141 [(match_dup 3) (const_int 0)])
6142 (match_dup 1))
6143 (match_dup 2)))))
6144 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
6145 (plus:SWI
6146 (plus:SWI
6147 (match_op_dup 5 [(match_dup 3) (const_int 0)])
6148 (match_dup 1))
6149 (match_dup 2)))]
6150 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6151 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6152 [(set_attr "type" "alu")
6153 (set_attr "mode" "<MODE>")])
6154
6155 (define_insn "*addv<mode>4_overflow_2"
6156 [(set (reg:CCO FLAGS_REG)
6157 (eq:CCO
6158 (plus:<DWI>
6159 (plus:<DWI>
6160 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6161 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6162 (sign_extend:<DWI>
6163 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6164 (match_operand:<DWI> 6 "const_int_operand" ""))
6165 (sign_extend:<DWI>
6166 (plus:SWI
6167 (plus:SWI
6168 (match_operator:SWI 5 "ix86_carry_flag_operator"
6169 [(match_dup 3) (const_int 0)])
6170 (match_dup 1))
6171 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
6172 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
6173 (plus:SWI
6174 (plus:SWI
6175 (match_op_dup 5 [(match_dup 3) (const_int 0)])
6176 (match_dup 1))
6177 (match_dup 2)))]
6178 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6179 && CONST_INT_P (operands[2])
6180 && INTVAL (operands[2]) == INTVAL (operands[6])"
6181 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6182 [(set_attr "type" "alu")
6183 (set_attr "mode" "<MODE>")
6184 (set (attr "length_immediate")
6185 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6186 (const_string "1")
6187 (const_string "4")))])
6188
6189 (define_expand "uaddv<mode>4"
6190 [(parallel [(set (reg:CCC FLAGS_REG)
6191 (compare:CCC
6192 (plus:SWIDWI
6193 (match_operand:SWIDWI 1 "nonimmediate_operand")
6194 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
6195 (match_dup 1)))
6196 (set (match_operand:SWIDWI 0 "register_operand")
6197 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
6198 (set (pc) (if_then_else
6199 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6200 (label_ref (match_operand 3))
6201 (pc)))]
6202 ""
6203 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6204
6205 ;; The lea patterns for modes less than 32 bits need to be matched by
6206 ;; several insns converted to real lea by splitters.
6207
6208 (define_insn_and_split "*lea<mode>_general_1"
6209 [(set (match_operand:SWI12 0 "register_operand" "=r")
6210 (plus:SWI12
6211 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6212 (match_operand:SWI12 2 "register_operand" "r"))
6213 (match_operand:SWI12 3 "immediate_operand" "i")))]
6214 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6215 "#"
6216 "&& reload_completed"
6217 [(set (match_dup 0)
6218 (plus:SI
6219 (plus:SI (match_dup 1) (match_dup 2))
6220 (match_dup 3)))]
6221 {
6222 operands[0] = gen_lowpart (SImode, operands[0]);
6223 operands[1] = gen_lowpart (SImode, operands[1]);
6224 operands[2] = gen_lowpart (SImode, operands[2]);
6225 operands[3] = gen_lowpart (SImode, operands[3]);
6226 }
6227 [(set_attr "type" "lea")
6228 (set_attr "mode" "SI")])
6229
6230 (define_insn_and_split "*lea<mode>_general_2"
6231 [(set (match_operand:SWI12 0 "register_operand" "=r")
6232 (plus:SWI12
6233 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6234 (match_operand 2 "const248_operand" "n"))
6235 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6236 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6237 "#"
6238 "&& reload_completed"
6239 [(set (match_dup 0)
6240 (plus:SI
6241 (mult:SI (match_dup 1) (match_dup 2))
6242 (match_dup 3)))]
6243 {
6244 operands[0] = gen_lowpart (SImode, operands[0]);
6245 operands[1] = gen_lowpart (SImode, operands[1]);
6246 operands[3] = gen_lowpart (SImode, operands[3]);
6247 }
6248 [(set_attr "type" "lea")
6249 (set_attr "mode" "SI")])
6250
6251 (define_insn_and_split "*lea<mode>_general_2b"
6252 [(set (match_operand:SWI12 0 "register_operand" "=r")
6253 (plus:SWI12
6254 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6255 (match_operand 2 "const123_operand" "n"))
6256 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6257 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6258 "#"
6259 "&& reload_completed"
6260 [(set (match_dup 0)
6261 (plus:SI
6262 (ashift:SI (match_dup 1) (match_dup 2))
6263 (match_dup 3)))]
6264 {
6265 operands[0] = gen_lowpart (SImode, operands[0]);
6266 operands[1] = gen_lowpart (SImode, operands[1]);
6267 operands[3] = gen_lowpart (SImode, operands[3]);
6268 }
6269 [(set_attr "type" "lea")
6270 (set_attr "mode" "SI")])
6271
6272 (define_insn_and_split "*lea<mode>_general_3"
6273 [(set (match_operand:SWI12 0 "register_operand" "=r")
6274 (plus:SWI12
6275 (plus:SWI12
6276 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6277 (match_operand 2 "const248_operand" "n"))
6278 (match_operand:SWI12 3 "register_operand" "r"))
6279 (match_operand:SWI12 4 "immediate_operand" "i")))]
6280 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6281 "#"
6282 "&& reload_completed"
6283 [(set (match_dup 0)
6284 (plus:SI
6285 (plus:SI
6286 (mult:SI (match_dup 1) (match_dup 2))
6287 (match_dup 3))
6288 (match_dup 4)))]
6289 {
6290 operands[0] = gen_lowpart (SImode, operands[0]);
6291 operands[1] = gen_lowpart (SImode, operands[1]);
6292 operands[3] = gen_lowpart (SImode, operands[3]);
6293 operands[4] = gen_lowpart (SImode, operands[4]);
6294 }
6295 [(set_attr "type" "lea")
6296 (set_attr "mode" "SI")])
6297
6298 (define_insn_and_split "*lea<mode>_general_3b"
6299 [(set (match_operand:SWI12 0 "register_operand" "=r")
6300 (plus:SWI12
6301 (plus:SWI12
6302 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6303 (match_operand 2 "const123_operand" "n"))
6304 (match_operand:SWI12 3 "register_operand" "r"))
6305 (match_operand:SWI12 4 "immediate_operand" "i")))]
6306 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6307 "#"
6308 "&& reload_completed"
6309 [(set (match_dup 0)
6310 (plus:SI
6311 (plus:SI
6312 (ashift:SI (match_dup 1) (match_dup 2))
6313 (match_dup 3))
6314 (match_dup 4)))]
6315 {
6316 operands[0] = gen_lowpart (SImode, operands[0]);
6317 operands[1] = gen_lowpart (SImode, operands[1]);
6318 operands[3] = gen_lowpart (SImode, operands[3]);
6319 operands[4] = gen_lowpart (SImode, operands[4]);
6320 }
6321 [(set_attr "type" "lea")
6322 (set_attr "mode" "SI")])
6323
6324 (define_insn_and_split "*lea<mode>_general_4"
6325 [(set (match_operand:SWI12 0 "register_operand" "=r")
6326 (any_or:SWI12
6327 (ashift:SWI12
6328 (match_operand:SWI12 1 "index_register_operand" "l")
6329 (match_operand 2 "const_0_to_3_operand" "n"))
6330 (match_operand 3 "const_int_operand" "n")))]
6331 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6332 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6333 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6334 "#"
6335 "&& reload_completed"
6336 [(set (match_dup 0)
6337 (plus:SI
6338 (mult:SI (match_dup 1) (match_dup 2))
6339 (match_dup 3)))]
6340 {
6341 operands[0] = gen_lowpart (SImode, operands[0]);
6342 operands[1] = gen_lowpart (SImode, operands[1]);
6343 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6344 }
6345 [(set_attr "type" "lea")
6346 (set_attr "mode" "SI")])
6347
6348 (define_insn_and_split "*lea<mode>_general_4"
6349 [(set (match_operand:SWI48 0 "register_operand" "=r")
6350 (any_or:SWI48
6351 (ashift:SWI48
6352 (match_operand:SWI48 1 "index_register_operand" "l")
6353 (match_operand 2 "const_0_to_3_operand" "n"))
6354 (match_operand 3 "const_int_operand" "n")))]
6355 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6356 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6357 "#"
6358 "&& reload_completed"
6359 [(set (match_dup 0)
6360 (plus:SWI48
6361 (mult:SWI48 (match_dup 1) (match_dup 2))
6362 (match_dup 3)))]
6363 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6364 [(set_attr "type" "lea")
6365 (set_attr "mode" "<MODE>")])
6366 \f
6367 ;; Subtract instructions
6368
6369 (define_expand "sub<mode>3"
6370 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6371 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6372 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6373 ""
6374 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6375
6376 (define_insn_and_split "*sub<dwi>3_doubleword"
6377 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6378 (minus:<DWI>
6379 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6380 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6381 (clobber (reg:CC FLAGS_REG))]
6382 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6383 "#"
6384 "reload_completed"
6385 [(parallel [(set (reg:CC FLAGS_REG)
6386 (compare:CC (match_dup 1) (match_dup 2)))
6387 (set (match_dup 0)
6388 (minus:DWIH (match_dup 1) (match_dup 2)))])
6389 (parallel [(set (match_dup 3)
6390 (minus:DWIH
6391 (minus:DWIH
6392 (match_dup 4)
6393 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6394 (match_dup 5)))
6395 (clobber (reg:CC FLAGS_REG))])]
6396 {
6397 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6398 if (operands[2] == const0_rtx)
6399 {
6400 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6401 DONE;
6402 }
6403 })
6404
6405 (define_insn "*sub<mode>_1"
6406 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6407 (minus:SWI
6408 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6409 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6410 (clobber (reg:CC FLAGS_REG))]
6411 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6412 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6413 [(set_attr "type" "alu")
6414 (set_attr "mode" "<MODE>")])
6415
6416 (define_insn "*subsi_1_zext"
6417 [(set (match_operand:DI 0 "register_operand" "=r")
6418 (zero_extend:DI
6419 (minus:SI (match_operand:SI 1 "register_operand" "0")
6420 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6421 (clobber (reg:CC FLAGS_REG))]
6422 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6423 "sub{l}\t{%2, %k0|%k0, %2}"
6424 [(set_attr "type" "alu")
6425 (set_attr "mode" "SI")])
6426
6427 (define_insn "*sub<mode>_1_slp"
6428 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
6429 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0")
6430 (match_operand:SWI12 2 "general_operand" "<r>mn")))
6431 (clobber (reg:CC FLAGS_REG))]
6432 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6433 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
6434 && rtx_equal_p (operands[0], operands[1])"
6435 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6436 [(set_attr "type" "alu")
6437 (set_attr "mode" "<MODE>")])
6438
6439 (define_insn "*sub<mode>_2"
6440 [(set (reg FLAGS_REG)
6441 (compare
6442 (minus:SWI
6443 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6444 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
6445 (const_int 0)))
6446 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6447 (minus:SWI (match_dup 1) (match_dup 2)))]
6448 "ix86_match_ccmode (insn, CCGOCmode)
6449 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6450 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6451 [(set_attr "type" "alu")
6452 (set_attr "mode" "<MODE>")])
6453
6454 (define_insn "*subsi_2_zext"
6455 [(set (reg FLAGS_REG)
6456 (compare
6457 (minus:SI (match_operand:SI 1 "register_operand" "0")
6458 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6459 (const_int 0)))
6460 (set (match_operand:DI 0 "register_operand" "=r")
6461 (zero_extend:DI
6462 (minus:SI (match_dup 1)
6463 (match_dup 2))))]
6464 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6465 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6466 "sub{l}\t{%2, %k0|%k0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "SI")])
6469
6470 ;; Subtract with jump on overflow.
6471 (define_expand "subv<mode>4"
6472 [(parallel [(set (reg:CCO FLAGS_REG)
6473 (eq:CCO
6474 (minus:<DPWI>
6475 (sign_extend:<DPWI>
6476 (match_operand:SWIDWI 1 "nonimmediate_operand"))
6477 (match_dup 4))
6478 (sign_extend:<DPWI>
6479 (minus:SWIDWI (match_dup 1)
6480 (match_operand:SWIDWI 2
6481 "<general_hilo_operand>")))))
6482 (set (match_operand:SWIDWI 0 "register_operand")
6483 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
6484 (set (pc) (if_then_else
6485 (eq (reg:CCO FLAGS_REG) (const_int 0))
6486 (label_ref (match_operand 3))
6487 (pc)))]
6488 ""
6489 {
6490 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6491 if (CONST_SCALAR_INT_P (operands[2]))
6492 operands[4] = operands[2];
6493 else
6494 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
6495 })
6496
6497 (define_insn "*subv<mode>4"
6498 [(set (reg:CCO FLAGS_REG)
6499 (eq:CCO (minus:<DWI>
6500 (sign_extend:<DWI>
6501 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6502 (sign_extend:<DWI>
6503 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
6504 (sign_extend:<DWI>
6505 (minus:SWI (match_dup 1) (match_dup 2)))))
6506 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6507 (minus:SWI (match_dup 1) (match_dup 2)))]
6508 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6509 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6510 [(set_attr "type" "alu")
6511 (set_attr "mode" "<MODE>")])
6512
6513 (define_insn "subv<mode>4_1"
6514 [(set (reg:CCO FLAGS_REG)
6515 (eq:CCO (minus:<DWI>
6516 (sign_extend:<DWI>
6517 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6518 (match_operand:<DWI> 3 "const_int_operand" "i"))
6519 (sign_extend:<DWI>
6520 (minus:SWI
6521 (match_dup 1)
6522 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6523 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6524 (minus:SWI (match_dup 1) (match_dup 2)))]
6525 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6526 && CONST_INT_P (operands[2])
6527 && INTVAL (operands[2]) == INTVAL (operands[3])"
6528 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6529 [(set_attr "type" "alu")
6530 (set_attr "mode" "<MODE>")
6531 (set (attr "length_immediate")
6532 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6533 (const_string "1")
6534 (match_test "<MODE_SIZE> == 8")
6535 (const_string "4")]
6536 (const_string "<MODE_SIZE>")))])
6537
6538 (define_insn_and_split "*subv<dwi>4_doubleword"
6539 [(set (reg:CCO FLAGS_REG)
6540 (eq:CCO
6541 (minus:<QPWI>
6542 (sign_extend:<QPWI>
6543 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
6544 (sign_extend:<QPWI>
6545 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
6546 (sign_extend:<QPWI>
6547 (minus:<DWI> (match_dup 1) (match_dup 2)))))
6548 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6549 (minus:<DWI> (match_dup 1) (match_dup 2)))]
6550 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6551 "#"
6552 "reload_completed"
6553 [(parallel [(set (reg:CC FLAGS_REG)
6554 (compare:CC (match_dup 1) (match_dup 2)))
6555 (set (match_dup 0)
6556 (minus:DWIH (match_dup 1) (match_dup 2)))])
6557 (parallel [(set (reg:CCO FLAGS_REG)
6558 (eq:CCO
6559 (minus:<DWI>
6560 (minus:<DWI>
6561 (sign_extend:<DWI> (match_dup 4))
6562 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
6563 (sign_extend:<DWI> (match_dup 5)))
6564 (sign_extend:<DWI>
6565 (minus:DWIH
6566 (minus:DWIH
6567 (match_dup 4)
6568 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6569 (match_dup 5)))))
6570 (set (match_dup 3)
6571 (minus:DWIH
6572 (minus:DWIH
6573 (match_dup 4)
6574 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6575 (match_dup 5)))])]
6576 {
6577 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6578 })
6579
6580 (define_insn_and_split "*subv<dwi>4_doubleword_1"
6581 [(set (reg:CCO FLAGS_REG)
6582 (eq:CCO
6583 (minus:<QPWI>
6584 (sign_extend:<QPWI>
6585 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
6586 (match_operand:<QPWI> 3 "const_scalar_int_operand" ""))
6587 (sign_extend:<QPWI>
6588 (minus:<DWI>
6589 (match_dup 1)
6590 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
6591 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
6592 (minus:<DWI> (match_dup 1) (match_dup 2)))]
6593 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6594 && CONST_SCALAR_INT_P (operands[2])
6595 && rtx_equal_p (operands[2], operands[3])"
6596 "#"
6597 "reload_completed"
6598 [(parallel [(set (reg:CC FLAGS_REG)
6599 (compare:CC (match_dup 1) (match_dup 2)))
6600 (set (match_dup 0)
6601 (minus:DWIH (match_dup 1) (match_dup 2)))])
6602 (parallel [(set (reg:CCO FLAGS_REG)
6603 (eq:CCO
6604 (minus:<DWI>
6605 (minus:<DWI>
6606 (sign_extend:<DWI> (match_dup 4))
6607 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
6608 (match_dup 5))
6609 (sign_extend:<DWI>
6610 (minus:DWIH
6611 (minus:DWIH
6612 (match_dup 4)
6613 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6614 (match_dup 5)))))
6615 (set (match_dup 3)
6616 (minus:DWIH
6617 (minus:DWIH
6618 (match_dup 4)
6619 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6620 (match_dup 5)))])]
6621 {
6622 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6623 if (operands[2] == const0_rtx)
6624 {
6625 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
6626 operands[5]));
6627 DONE;
6628 }
6629 })
6630
6631 (define_insn "*subv<mode>4_overflow_1"
6632 [(set (reg:CCO FLAGS_REG)
6633 (eq:CCO
6634 (minus:<DWI>
6635 (minus:<DWI>
6636 (sign_extend:<DWI>
6637 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6638 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6639 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6640 (sign_extend:<DWI>
6641 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
6642 (sign_extend:<DWI>
6643 (minus:SWI
6644 (minus:SWI
6645 (match_dup 1)
6646 (match_operator:SWI 5 "ix86_carry_flag_operator"
6647 [(match_dup 3) (const_int 0)]))
6648 (match_dup 2)))))
6649 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
6650 (minus:SWI
6651 (minus:SWI
6652 (match_dup 1)
6653 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
6654 (match_dup 2)))]
6655 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6656 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6657 [(set_attr "type" "alu")
6658 (set_attr "mode" "<MODE>")])
6659
6660 (define_insn "*subv<mode>4_overflow_2"
6661 [(set (reg:CCO FLAGS_REG)
6662 (eq:CCO
6663 (minus:<DWI>
6664 (minus:<DWI>
6665 (sign_extend:<DWI>
6666 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
6667 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6668 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6669 (match_operand:<DWI> 6 "const_int_operand" ""))
6670 (sign_extend:<DWI>
6671 (minus:SWI
6672 (minus:SWI
6673 (match_dup 1)
6674 (match_operator:SWI 5 "ix86_carry_flag_operator"
6675 [(match_dup 3) (const_int 0)]))
6676 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
6677 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
6678 (minus:SWI
6679 (minus:SWI
6680 (match_dup 1)
6681 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
6682 (match_dup 2)))]
6683 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6684 && CONST_INT_P (operands[2])
6685 && INTVAL (operands[2]) == INTVAL (operands[6])"
6686 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6687 [(set_attr "type" "alu")
6688 (set_attr "mode" "<MODE>")
6689 (set (attr "length_immediate")
6690 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6691 (const_string "1")
6692 (const_string "4")))])
6693
6694 (define_expand "usubv<mode>4"
6695 [(parallel [(set (reg:CC FLAGS_REG)
6696 (compare:CC
6697 (match_operand:SWI 1 "nonimmediate_operand")
6698 (match_operand:SWI 2 "<general_operand>")))
6699 (set (match_operand:SWI 0 "register_operand")
6700 (minus:SWI (match_dup 1) (match_dup 2)))])
6701 (set (pc) (if_then_else
6702 (ltu (reg:CC FLAGS_REG) (const_int 0))
6703 (label_ref (match_operand 3))
6704 (pc)))]
6705 ""
6706 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6707
6708 (define_insn "*sub<mode>_3"
6709 [(set (reg FLAGS_REG)
6710 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6711 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6712 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6713 (minus:SWI (match_dup 1) (match_dup 2)))]
6714 "ix86_match_ccmode (insn, CCmode)
6715 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6716 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6717 [(set_attr "type" "alu")
6718 (set_attr "mode" "<MODE>")])
6719
6720 (define_peephole2
6721 [(parallel
6722 [(set (reg:CC FLAGS_REG)
6723 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6724 (match_operand:SWI 1 "general_gr_operand")))
6725 (set (match_dup 0)
6726 (minus:SWI (match_dup 0) (match_dup 1)))])]
6727 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6728 [(set (reg:CC FLAGS_REG)
6729 (compare:CC (match_dup 0) (match_dup 1)))])
6730
6731 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
6732 ;; subl $1, %eax; jnc .Lxx;
6733 (define_peephole2
6734 [(parallel
6735 [(set (match_operand:SWI 0 "general_reg_operand")
6736 (plus:SWI (match_dup 0) (const_int -1)))
6737 (clobber (reg FLAGS_REG))])
6738 (set (reg:CCZ FLAGS_REG)
6739 (compare:CCZ (match_dup 0) (const_int -1)))
6740 (set (pc)
6741 (if_then_else (match_operator 1 "bt_comparison_operator"
6742 [(reg:CCZ FLAGS_REG) (const_int 0)])
6743 (match_operand 2)
6744 (pc)))]
6745 "peep2_regno_dead_p (3, FLAGS_REG)"
6746 [(parallel
6747 [(set (reg:CC FLAGS_REG)
6748 (compare:CC (match_dup 0) (const_int 1)))
6749 (set (match_dup 0)
6750 (minus:SWI (match_dup 0) (const_int 1)))])
6751 (set (pc)
6752 (if_then_else (match_dup 3)
6753 (match_dup 2)
6754 (pc)))]
6755 {
6756 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
6757 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
6758 ? GEU : LTU, VOIDmode, cc, const0_rtx);
6759 })
6760
6761 (define_insn "*subsi_3_zext"
6762 [(set (reg FLAGS_REG)
6763 (compare (match_operand:SI 1 "register_operand" "0")
6764 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6765 (set (match_operand:DI 0 "register_operand" "=r")
6766 (zero_extend:DI
6767 (minus:SI (match_dup 1)
6768 (match_dup 2))))]
6769 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6770 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6771 "sub{l}\t{%2, %1|%1, %2}"
6772 [(set_attr "type" "alu")
6773 (set_attr "mode" "SI")])
6774 \f
6775 ;; Add with carry and subtract with borrow
6776
6777 (define_insn "@add<mode>3_carry"
6778 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6779 (plus:SWI
6780 (plus:SWI
6781 (match_operator:SWI 4 "ix86_carry_flag_operator"
6782 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6783 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6784 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6785 (clobber (reg:CC FLAGS_REG))]
6786 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6787 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6788 [(set_attr "type" "alu")
6789 (set_attr "use_carry" "1")
6790 (set_attr "pent_pair" "pu")
6791 (set_attr "mode" "<MODE>")])
6792
6793 (define_insn "*add<mode>3_carry_0"
6794 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6795 (plus:SWI
6796 (match_operator:SWI 3 "ix86_carry_flag_operator"
6797 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6798 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6799 (clobber (reg:CC FLAGS_REG))]
6800 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6801 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6802 [(set_attr "type" "alu")
6803 (set_attr "use_carry" "1")
6804 (set_attr "pent_pair" "pu")
6805 (set_attr "mode" "<MODE>")])
6806
6807 (define_insn "*addsi3_carry_zext"
6808 [(set (match_operand:DI 0 "register_operand" "=r")
6809 (zero_extend:DI
6810 (plus:SI
6811 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6812 [(reg FLAGS_REG) (const_int 0)])
6813 (match_operand:SI 1 "register_operand" "%0"))
6814 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6815 (clobber (reg:CC FLAGS_REG))]
6816 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6817 "adc{l}\t{%2, %k0|%k0, %2}"
6818 [(set_attr "type" "alu")
6819 (set_attr "use_carry" "1")
6820 (set_attr "pent_pair" "pu")
6821 (set_attr "mode" "SI")])
6822
6823 (define_insn "*addsi3_carry_zext_0"
6824 [(set (match_operand:DI 0 "register_operand" "=r")
6825 (zero_extend:DI
6826 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6827 [(reg FLAGS_REG) (const_int 0)])
6828 (match_operand:SI 1 "register_operand" "0"))))
6829 (clobber (reg:CC FLAGS_REG))]
6830 "TARGET_64BIT"
6831 "adc{l}\t{$0, %k0|%k0, 0}"
6832 [(set_attr "type" "alu")
6833 (set_attr "use_carry" "1")
6834 (set_attr "pent_pair" "pu")
6835 (set_attr "mode" "SI")])
6836
6837 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6838
6839 (define_insn "addcarry<mode>"
6840 [(set (reg:CCC FLAGS_REG)
6841 (compare:CCC
6842 (zero_extend:<DWI>
6843 (plus:SWI48
6844 (plus:SWI48
6845 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6846 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6847 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
6848 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
6849 (plus:<DWI>
6850 (zero_extend:<DWI> (match_dup 2))
6851 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6852 [(match_dup 3) (const_int 0)]))))
6853 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6854 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6855 [(match_dup 3) (const_int 0)])
6856 (match_dup 1))
6857 (match_dup 2)))]
6858 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6859 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6860 [(set_attr "type" "alu")
6861 (set_attr "use_carry" "1")
6862 (set_attr "pent_pair" "pu")
6863 (set_attr "mode" "<MODE>")])
6864
6865 (define_expand "addcarry<mode>_0"
6866 [(parallel
6867 [(set (reg:CCC FLAGS_REG)
6868 (compare:CCC
6869 (plus:SWI48
6870 (match_operand:SWI48 1 "nonimmediate_operand")
6871 (match_operand:SWI48 2 "x86_64_general_operand"))
6872 (match_dup 1)))
6873 (set (match_operand:SWI48 0 "nonimmediate_operand")
6874 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6875 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6876
6877 (define_insn "*addcarry<mode>_1"
6878 [(set (reg:CCC FLAGS_REG)
6879 (compare:CCC
6880 (zero_extend:<DWI>
6881 (plus:SWI48
6882 (plus:SWI48
6883 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6884 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6885 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6886 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
6887 (plus:<DWI>
6888 (match_operand:<DWI> 6 "const_scalar_int_operand" "")
6889 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6890 [(match_dup 3) (const_int 0)]))))
6891 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
6892 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6893 [(match_dup 3) (const_int 0)])
6894 (match_dup 1))
6895 (match_dup 2)))]
6896 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6897 && CONST_INT_P (operands[2])
6898 /* Check that operands[6] is operands[2] zero extended from
6899 <MODE>mode to <DWI>mode. */
6900 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
6901 ? (CONST_INT_P (operands[6])
6902 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
6903 & GET_MODE_MASK (<MODE>mode)))
6904 : (CONST_WIDE_INT_P (operands[6])
6905 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
6906 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
6907 == UINTVAL (operands[2]))
6908 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
6909 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6910 [(set_attr "type" "alu")
6911 (set_attr "use_carry" "1")
6912 (set_attr "pent_pair" "pu")
6913 (set_attr "mode" "<MODE>")
6914 (set (attr "length_immediate")
6915 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6916 (const_string "1")
6917 (const_string "4")))])
6918
6919 (define_insn "@sub<mode>3_carry"
6920 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6921 (minus:SWI
6922 (minus:SWI
6923 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6924 (match_operator:SWI 4 "ix86_carry_flag_operator"
6925 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6926 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6927 (clobber (reg:CC FLAGS_REG))]
6928 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6929 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6930 [(set_attr "type" "alu")
6931 (set_attr "use_carry" "1")
6932 (set_attr "pent_pair" "pu")
6933 (set_attr "mode" "<MODE>")])
6934
6935 (define_insn "*sub<mode>3_carry_0"
6936 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6937 (minus:SWI
6938 (match_operand:SWI 1 "nonimmediate_operand" "0")
6939 (match_operator:SWI 3 "ix86_carry_flag_operator"
6940 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6941 (clobber (reg:CC FLAGS_REG))]
6942 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6943 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6944 [(set_attr "type" "alu")
6945 (set_attr "use_carry" "1")
6946 (set_attr "pent_pair" "pu")
6947 (set_attr "mode" "<MODE>")])
6948
6949 (define_insn "*subsi3_carry_zext"
6950 [(set (match_operand:DI 0 "register_operand" "=r")
6951 (zero_extend:DI
6952 (minus:SI
6953 (minus:SI
6954 (match_operand:SI 1 "register_operand" "0")
6955 (match_operator:SI 3 "ix86_carry_flag_operator"
6956 [(reg FLAGS_REG) (const_int 0)]))
6957 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6958 (clobber (reg:CC FLAGS_REG))]
6959 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6960 "sbb{l}\t{%2, %k0|%k0, %2}"
6961 [(set_attr "type" "alu")
6962 (set_attr "use_carry" "1")
6963 (set_attr "pent_pair" "pu")
6964 (set_attr "mode" "SI")])
6965
6966 (define_insn "*subsi3_carry_zext_0"
6967 [(set (match_operand:DI 0 "register_operand" "=r")
6968 (zero_extend:DI
6969 (minus:SI
6970 (match_operand:SI 1 "register_operand" "0")
6971 (match_operator:SI 2 "ix86_carry_flag_operator"
6972 [(reg FLAGS_REG) (const_int 0)]))))
6973 (clobber (reg:CC FLAGS_REG))]
6974 "TARGET_64BIT"
6975 "sbb{l}\t{$0, %k0|%k0, 0}"
6976 [(set_attr "type" "alu")
6977 (set_attr "use_carry" "1")
6978 (set_attr "pent_pair" "pu")
6979 (set_attr "mode" "SI")])
6980
6981 (define_insn "@sub<mode>3_carry_ccc"
6982 [(set (reg:CCC FLAGS_REG)
6983 (compare:CCC
6984 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6985 (plus:<DWI>
6986 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6987 (zero_extend:<DWI>
6988 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6989 (clobber (match_scratch:DWIH 0 "=r"))]
6990 ""
6991 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6992 [(set_attr "type" "alu")
6993 (set_attr "mode" "<MODE>")])
6994
6995 (define_insn "*sub<mode>3_carry_ccc_1"
6996 [(set (reg:CCC FLAGS_REG)
6997 (compare:CCC
6998 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6999 (plus:<DWI>
7000 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7001 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
7002 (clobber (match_scratch:DWIH 0 "=r"))]
7003 ""
7004 {
7005 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
7006 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
7007 }
7008 [(set_attr "type" "alu")
7009 (set_attr "mode" "<MODE>")])
7010
7011 ;; The sign flag is set from the
7012 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
7013 ;; result, the overflow flag likewise, but the overflow flag is also
7014 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
7015 (define_insn "@sub<mode>3_carry_ccgz"
7016 [(set (reg:CCGZ FLAGS_REG)
7017 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
7018 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
7019 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
7020 UNSPEC_SBB))
7021 (clobber (match_scratch:DWIH 0 "=r"))]
7022 ""
7023 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7024 [(set_attr "type" "alu")
7025 (set_attr "mode" "<MODE>")])
7026
7027 (define_insn "subborrow<mode>"
7028 [(set (reg:CCC FLAGS_REG)
7029 (compare:CCC
7030 (zero_extend:<DWI>
7031 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
7032 (plus:<DWI>
7033 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7034 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7035 (zero_extend:<DWI>
7036 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
7037 (set (match_operand:SWI48 0 "register_operand" "=r")
7038 (minus:SWI48 (minus:SWI48
7039 (match_dup 1)
7040 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7041 [(match_dup 3) (const_int 0)]))
7042 (match_dup 2)))]
7043 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7044 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7045 [(set_attr "type" "alu")
7046 (set_attr "use_carry" "1")
7047 (set_attr "pent_pair" "pu")
7048 (set_attr "mode" "<MODE>")])
7049
7050 (define_expand "subborrow<mode>_0"
7051 [(parallel
7052 [(set (reg:CC FLAGS_REG)
7053 (compare:CC
7054 (match_operand:SWI48 1 "nonimmediate_operand")
7055 (match_operand:SWI48 2 "<general_operand>")))
7056 (set (match_operand:SWI48 0 "register_operand")
7057 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7058 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7059
7060 (define_mode_iterator CC_CCC [CC CCC])
7061
7062 ;; Pre-reload splitter to optimize
7063 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
7064 ;; operand and no intervening flags modifications into nothing.
7065 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
7066 [(set (reg:CCC FLAGS_REG)
7067 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
7068 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
7069 "ix86_pre_reload_split ()"
7070 "#"
7071 "&& 1"
7072 [(const_int 0)])
7073 \f
7074 ;; Overflow setting add instructions
7075
7076 (define_expand "addqi3_cconly_overflow"
7077 [(parallel
7078 [(set (reg:CCC FLAGS_REG)
7079 (compare:CCC
7080 (plus:QI
7081 (match_operand:QI 0 "nonimmediate_operand")
7082 (match_operand:QI 1 "general_operand"))
7083 (match_dup 0)))
7084 (clobber (scratch:QI))])]
7085 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7086
7087 (define_insn "*add<mode>3_cconly_overflow_1"
7088 [(set (reg:CCC FLAGS_REG)
7089 (compare:CCC
7090 (plus:SWI
7091 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7092 (match_operand:SWI 2 "<general_operand>" "<g>"))
7093 (match_dup 1)))
7094 (clobber (match_scratch:SWI 0 "=<r>"))]
7095 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7096 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7097 [(set_attr "type" "alu")
7098 (set_attr "mode" "<MODE>")])
7099
7100 (define_insn "*add<mode>3_cc_overflow_1"
7101 [(set (reg:CCC FLAGS_REG)
7102 (compare:CCC
7103 (plus:SWI
7104 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7105 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
7106 (match_dup 1)))
7107 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7108 (plus:SWI (match_dup 1) (match_dup 2)))]
7109 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7110 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7111 [(set_attr "type" "alu")
7112 (set_attr "mode" "<MODE>")])
7113
7114 (define_peephole2
7115 [(parallel [(set (reg:CCC FLAGS_REG)
7116 (compare:CCC
7117 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
7118 (match_operand:SWI 1 "memory_operand"))
7119 (match_dup 0)))
7120 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
7121 (set (match_dup 1) (match_dup 0))]
7122 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7123 && peep2_reg_dead_p (2, operands[0])
7124 && !reg_overlap_mentioned_p (operands[0], operands[1])"
7125 [(parallel [(set (reg:CCC FLAGS_REG)
7126 (compare:CCC
7127 (plus:SWI (match_dup 1) (match_dup 0))
7128 (match_dup 1)))
7129 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
7130
7131 (define_insn "*addsi3_zext_cc_overflow_1"
7132 [(set (reg:CCC FLAGS_REG)
7133 (compare:CCC
7134 (plus:SI
7135 (match_operand:SI 1 "nonimmediate_operand" "%0")
7136 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7137 (match_dup 1)))
7138 (set (match_operand:DI 0 "register_operand" "=r")
7139 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7140 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7141 "add{l}\t{%2, %k0|%k0, %2}"
7142 [(set_attr "type" "alu")
7143 (set_attr "mode" "SI")])
7144
7145 (define_insn "*add<mode>3_cconly_overflow_2"
7146 [(set (reg:CCC FLAGS_REG)
7147 (compare:CCC
7148 (plus:SWI
7149 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7150 (match_operand:SWI 2 "<general_operand>" "<g>"))
7151 (match_dup 2)))
7152 (clobber (match_scratch:SWI 0 "=<r>"))]
7153 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7154 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7155 [(set_attr "type" "alu")
7156 (set_attr "mode" "<MODE>")])
7157
7158 (define_insn "*add<mode>3_cc_overflow_2"
7159 [(set (reg:CCC FLAGS_REG)
7160 (compare:CCC
7161 (plus:SWI
7162 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7163 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
7164 (match_dup 2)))
7165 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7166 (plus:SWI (match_dup 1) (match_dup 2)))]
7167 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7168 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7169 [(set_attr "type" "alu")
7170 (set_attr "mode" "<MODE>")])
7171
7172 (define_insn "*addsi3_zext_cc_overflow_2"
7173 [(set (reg:CCC FLAGS_REG)
7174 (compare:CCC
7175 (plus:SI
7176 (match_operand:SI 1 "nonimmediate_operand" "%0")
7177 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7178 (match_dup 2)))
7179 (set (match_operand:DI 0 "register_operand" "=r")
7180 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7181 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7182 "add{l}\t{%2, %k0|%k0, %2}"
7183 [(set_attr "type" "alu")
7184 (set_attr "mode" "SI")])
7185
7186 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
7187 [(set (reg:CCC FLAGS_REG)
7188 (compare:CCC
7189 (plus:<DWI>
7190 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
7191 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
7192 (match_dup 1)))
7193 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7194 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7195 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7196 "#"
7197 "reload_completed"
7198 [(parallel [(set (reg:CCC FLAGS_REG)
7199 (compare:CCC
7200 (plus:DWIH (match_dup 1) (match_dup 2))
7201 (match_dup 1)))
7202 (set (match_dup 0)
7203 (plus:DWIH (match_dup 1) (match_dup 2)))])
7204 (parallel [(set (reg:CCC FLAGS_REG)
7205 (compare:CCC
7206 (zero_extend:<DWI>
7207 (plus:DWIH
7208 (plus:DWIH
7209 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7210 (match_dup 4))
7211 (match_dup 5)))
7212 (plus:<DWI>
7213 (match_dup 6)
7214 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
7215 (set (match_dup 3)
7216 (plus:DWIH
7217 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7218 (match_dup 4))
7219 (match_dup 5)))])]
7220 {
7221 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7222 if (operands[2] == const0_rtx)
7223 {
7224 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
7225 DONE;
7226 }
7227 if (CONST_INT_P (operands[5]))
7228 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
7229 operands[5], <MODE>mode);
7230 else
7231 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
7232 })
7233
7234 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
7235 ;; test, where the latter is preferrable if we have some carry consuming
7236 ;; instruction.
7237 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
7238 ;; + (1 - CF).
7239 (define_insn_and_split "*add<mode>3_eq"
7240 [(set (match_operand:SWI 0 "nonimmediate_operand")
7241 (plus:SWI
7242 (plus:SWI
7243 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
7244 (match_operand:SWI 1 "nonimmediate_operand"))
7245 (match_operand:SWI 2 "<general_operand>")))
7246 (clobber (reg:CC FLAGS_REG))]
7247 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7248 && ix86_pre_reload_split ()"
7249 "#"
7250 "&& 1"
7251 [(set (reg:CC FLAGS_REG)
7252 (compare:CC (match_dup 3) (const_int 1)))
7253 (parallel [(set (match_dup 0)
7254 (plus:SWI
7255 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7256 (match_dup 1))
7257 (match_dup 2)))
7258 (clobber (reg:CC FLAGS_REG))])])
7259
7260 (define_insn_and_split "*add<mode>3_ne"
7261 [(set (match_operand:SWI 0 "nonimmediate_operand")
7262 (plus:SWI
7263 (plus:SWI
7264 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
7265 (match_operand:SWI 1 "nonimmediate_operand"))
7266 (match_operand:SWI 2 "<immediate_operand>")))
7267 (clobber (reg:CC FLAGS_REG))]
7268 "CONST_INT_P (operands[2])
7269 && (<MODE>mode != DImode
7270 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7271 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7272 && ix86_pre_reload_split ()"
7273 "#"
7274 "&& 1"
7275 [(set (reg:CC FLAGS_REG)
7276 (compare:CC (match_dup 3) (const_int 1)))
7277 (parallel [(set (match_dup 0)
7278 (minus:SWI
7279 (minus:SWI (match_dup 1)
7280 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7281 (match_dup 2)))
7282 (clobber (reg:CC FLAGS_REG))])]
7283 {
7284 operands[2] = gen_int_mode (~INTVAL (operands[2]),
7285 <MODE>mode == DImode ? SImode : <MODE>mode);
7286 })
7287
7288 (define_insn_and_split "*add<mode>3_eq_0"
7289 [(set (match_operand:SWI 0 "nonimmediate_operand")
7290 (plus:SWI
7291 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
7292 (match_operand:SWI 1 "<general_operand>")))
7293 (clobber (reg:CC FLAGS_REG))]
7294 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
7295 && ix86_pre_reload_split ()"
7296 "#"
7297 "&& 1"
7298 [(set (reg:CC FLAGS_REG)
7299 (compare:CC (match_dup 2) (const_int 1)))
7300 (parallel [(set (match_dup 0)
7301 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7302 (match_dup 1)))
7303 (clobber (reg:CC FLAGS_REG))])]
7304 {
7305 if (!nonimmediate_operand (operands[1], <MODE>mode))
7306 operands[1] = force_reg (<MODE>mode, operands[1]);
7307 })
7308
7309 (define_insn_and_split "*add<mode>3_ne_0"
7310 [(set (match_operand:SWI 0 "nonimmediate_operand")
7311 (plus:SWI
7312 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
7313 (match_operand:SWI 1 "<general_operand>")))
7314 (clobber (reg:CC FLAGS_REG))]
7315 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
7316 && ix86_pre_reload_split ()"
7317 "#"
7318 "&& 1"
7319 [(set (reg:CC FLAGS_REG)
7320 (compare:CC (match_dup 2) (const_int 1)))
7321 (parallel [(set (match_dup 0)
7322 (minus:SWI (minus:SWI
7323 (match_dup 1)
7324 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7325 (const_int -1)))
7326 (clobber (reg:CC FLAGS_REG))])]
7327 {
7328 if (!nonimmediate_operand (operands[1], <MODE>mode))
7329 operands[1] = force_reg (<MODE>mode, operands[1]);
7330 })
7331
7332 (define_insn_and_split "*sub<mode>3_eq"
7333 [(set (match_operand:SWI 0 "nonimmediate_operand")
7334 (minus:SWI
7335 (minus:SWI
7336 (match_operand:SWI 1 "nonimmediate_operand")
7337 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
7338 (const_int 0)))
7339 (match_operand:SWI 2 "<general_operand>")))
7340 (clobber (reg:CC FLAGS_REG))]
7341 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7342 && ix86_pre_reload_split ()"
7343 "#"
7344 "&& 1"
7345 [(set (reg:CC FLAGS_REG)
7346 (compare:CC (match_dup 3) (const_int 1)))
7347 (parallel [(set (match_dup 0)
7348 (minus:SWI
7349 (minus:SWI (match_dup 1)
7350 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7351 (match_dup 2)))
7352 (clobber (reg:CC FLAGS_REG))])])
7353
7354 (define_insn_and_split "*sub<mode>3_ne"
7355 [(set (match_operand:SWI 0 "nonimmediate_operand")
7356 (plus:SWI
7357 (minus:SWI
7358 (match_operand:SWI 1 "nonimmediate_operand")
7359 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
7360 (const_int 0)))
7361 (match_operand:SWI 2 "<immediate_operand>")))
7362 (clobber (reg:CC FLAGS_REG))]
7363 "CONST_INT_P (operands[2])
7364 && (<MODE>mode != DImode
7365 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7366 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7367 && ix86_pre_reload_split ()"
7368 "#"
7369 "&& 1"
7370 [(set (reg:CC FLAGS_REG)
7371 (compare:CC (match_dup 3) (const_int 1)))
7372 (parallel [(set (match_dup 0)
7373 (plus:SWI
7374 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7375 (match_dup 1))
7376 (match_dup 2)))
7377 (clobber (reg:CC FLAGS_REG))])]
7378 {
7379 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
7380 <MODE>mode == DImode ? SImode : <MODE>mode);
7381 })
7382
7383 (define_insn_and_split "*sub<mode>3_eq_1"
7384 [(set (match_operand:SWI 0 "nonimmediate_operand")
7385 (plus:SWI
7386 (minus:SWI
7387 (match_operand:SWI 1 "nonimmediate_operand")
7388 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
7389 (const_int 0)))
7390 (match_operand:SWI 2 "<immediate_operand>")))
7391 (clobber (reg:CC FLAGS_REG))]
7392 "CONST_INT_P (operands[2])
7393 && (<MODE>mode != DImode
7394 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7395 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7396 && ix86_pre_reload_split ()"
7397 "#"
7398 "&& 1"
7399 [(set (reg:CC FLAGS_REG)
7400 (compare:CC (match_dup 3) (const_int 1)))
7401 (parallel [(set (match_dup 0)
7402 (minus:SWI
7403 (minus:SWI (match_dup 1)
7404 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7405 (match_dup 2)))
7406 (clobber (reg:CC FLAGS_REG))])]
7407 {
7408 operands[2] = gen_int_mode (-INTVAL (operands[2]),
7409 <MODE>mode == DImode ? SImode : <MODE>mode);
7410 })
7411
7412 (define_insn_and_split "*sub<mode>3_eq_0"
7413 [(set (match_operand:SWI 0 "nonimmediate_operand")
7414 (minus:SWI
7415 (match_operand:SWI 1 "<general_operand>")
7416 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
7417 (clobber (reg:CC FLAGS_REG))]
7418 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
7419 && ix86_pre_reload_split ()"
7420 "#"
7421 "&& 1"
7422 [(set (reg:CC FLAGS_REG)
7423 (compare:CC (match_dup 2) (const_int 1)))
7424 (parallel [(set (match_dup 0)
7425 (minus:SWI (match_dup 1)
7426 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
7427 (clobber (reg:CC FLAGS_REG))])]
7428 {
7429 if (!nonimmediate_operand (operands[1], <MODE>mode))
7430 operands[1] = force_reg (<MODE>mode, operands[1]);
7431 })
7432
7433 (define_insn_and_split "*sub<mode>3_ne_0"
7434 [(set (match_operand:SWI 0 "nonimmediate_operand")
7435 (minus:SWI
7436 (match_operand:SWI 1 "<general_operand>")
7437 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
7438 (clobber (reg:CC FLAGS_REG))]
7439 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
7440 && ix86_pre_reload_split ()"
7441 "#"
7442 "&& 1"
7443 [(set (reg:CC FLAGS_REG)
7444 (compare:CC (match_dup 2) (const_int 1)))
7445 (parallel [(set (match_dup 0)
7446 (plus:SWI (plus:SWI
7447 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7448 (match_dup 1))
7449 (const_int -1)))
7450 (clobber (reg:CC FLAGS_REG))])]
7451 {
7452 if (!nonimmediate_operand (operands[1], <MODE>mode))
7453 operands[1] = force_reg (<MODE>mode, operands[1]);
7454 })
7455
7456 ;; The patterns that match these are at the end of this file.
7457
7458 (define_expand "<insn>xf3"
7459 [(set (match_operand:XF 0 "register_operand")
7460 (plusminus:XF
7461 (match_operand:XF 1 "register_operand")
7462 (match_operand:XF 2 "register_operand")))]
7463 "TARGET_80387")
7464
7465 (define_expand "<insn><mode>3"
7466 [(set (match_operand:MODEF 0 "register_operand")
7467 (plusminus:MODEF
7468 (match_operand:MODEF 1 "register_operand")
7469 (match_operand:MODEF 2 "nonimmediate_operand")))]
7470 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7471 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7472 \f
7473 ;; Multiply instructions
7474
7475 (define_expand "mul<mode>3"
7476 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7477 (mult:SWIM248
7478 (match_operand:SWIM248 1 "register_operand")
7479 (match_operand:SWIM248 2 "<general_operand>")))
7480 (clobber (reg:CC FLAGS_REG))])])
7481
7482 (define_expand "mulqi3"
7483 [(parallel [(set (match_operand:QI 0 "register_operand")
7484 (mult:QI
7485 (match_operand:QI 1 "register_operand")
7486 (match_operand:QI 2 "nonimmediate_operand")))
7487 (clobber (reg:CC FLAGS_REG))])]
7488 "TARGET_QIMODE_MATH")
7489
7490 ;; On AMDFAM10
7491 ;; IMUL reg32/64, reg32/64, imm8 Direct
7492 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7493 ;; IMUL reg32/64, reg32/64, imm32 Direct
7494 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7495 ;; IMUL reg32/64, reg32/64 Direct
7496 ;; IMUL reg32/64, mem32/64 Direct
7497 ;;
7498 ;; On BDVER1, all above IMULs use DirectPath
7499 ;;
7500 ;; On AMDFAM10
7501 ;; IMUL reg16, reg16, imm8 VectorPath
7502 ;; IMUL reg16, mem16, imm8 VectorPath
7503 ;; IMUL reg16, reg16, imm16 VectorPath
7504 ;; IMUL reg16, mem16, imm16 VectorPath
7505 ;; IMUL reg16, reg16 Direct
7506 ;; IMUL reg16, mem16 Direct
7507 ;;
7508 ;; On BDVER1, all HI MULs use DoublePath
7509
7510 (define_insn "*mul<mode>3_1"
7511 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7512 (mult:SWIM248
7513 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7514 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7515 (clobber (reg:CC FLAGS_REG))]
7516 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7517 "@
7518 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7519 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7520 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7521 [(set_attr "type" "imul")
7522 (set_attr "prefix_0f" "0,0,1")
7523 (set (attr "athlon_decode")
7524 (cond [(eq_attr "cpu" "athlon")
7525 (const_string "vector")
7526 (eq_attr "alternative" "1")
7527 (const_string "vector")
7528 (and (eq_attr "alternative" "2")
7529 (ior (match_test "<MODE>mode == HImode")
7530 (match_operand 1 "memory_operand")))
7531 (const_string "vector")]
7532 (const_string "direct")))
7533 (set (attr "amdfam10_decode")
7534 (cond [(and (eq_attr "alternative" "0,1")
7535 (ior (match_test "<MODE>mode == HImode")
7536 (match_operand 1 "memory_operand")))
7537 (const_string "vector")]
7538 (const_string "direct")))
7539 (set (attr "bdver1_decode")
7540 (if_then_else
7541 (match_test "<MODE>mode == HImode")
7542 (const_string "double")
7543 (const_string "direct")))
7544 (set_attr "mode" "<MODE>")])
7545
7546 (define_insn "*mulsi3_1_zext"
7547 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7548 (zero_extend:DI
7549 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7550 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7551 (clobber (reg:CC FLAGS_REG))]
7552 "TARGET_64BIT
7553 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7554 "@
7555 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7556 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7557 imul{l}\t{%2, %k0|%k0, %2}"
7558 [(set_attr "type" "imul")
7559 (set_attr "prefix_0f" "0,0,1")
7560 (set (attr "athlon_decode")
7561 (cond [(eq_attr "cpu" "athlon")
7562 (const_string "vector")
7563 (eq_attr "alternative" "1")
7564 (const_string "vector")
7565 (and (eq_attr "alternative" "2")
7566 (match_operand 1 "memory_operand"))
7567 (const_string "vector")]
7568 (const_string "direct")))
7569 (set (attr "amdfam10_decode")
7570 (cond [(and (eq_attr "alternative" "0,1")
7571 (match_operand 1 "memory_operand"))
7572 (const_string "vector")]
7573 (const_string "direct")))
7574 (set_attr "bdver1_decode" "direct")
7575 (set_attr "mode" "SI")])
7576
7577 ;;On AMDFAM10 and BDVER1
7578 ;; MUL reg8 Direct
7579 ;; MUL mem8 Direct
7580
7581 (define_insn "*mulqi3_1"
7582 [(set (match_operand:QI 0 "register_operand" "=a")
7583 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7584 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7585 (clobber (reg:CC FLAGS_REG))]
7586 "TARGET_QIMODE_MATH
7587 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7588 "mul{b}\t%2"
7589 [(set_attr "type" "imul")
7590 (set_attr "length_immediate" "0")
7591 (set (attr "athlon_decode")
7592 (if_then_else (eq_attr "cpu" "athlon")
7593 (const_string "vector")
7594 (const_string "direct")))
7595 (set_attr "amdfam10_decode" "direct")
7596 (set_attr "bdver1_decode" "direct")
7597 (set_attr "mode" "QI")])
7598
7599 ;; Multiply with jump on overflow.
7600 (define_expand "mulv<mode>4"
7601 [(parallel [(set (reg:CCO FLAGS_REG)
7602 (eq:CCO (mult:<DWI>
7603 (sign_extend:<DWI>
7604 (match_operand:SWI248 1 "register_operand"))
7605 (match_dup 4))
7606 (sign_extend:<DWI>
7607 (mult:SWI248 (match_dup 1)
7608 (match_operand:SWI248 2
7609 "<general_operand>")))))
7610 (set (match_operand:SWI248 0 "register_operand")
7611 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7612 (set (pc) (if_then_else
7613 (eq (reg:CCO FLAGS_REG) (const_int 0))
7614 (label_ref (match_operand 3))
7615 (pc)))]
7616 ""
7617 {
7618 if (CONST_INT_P (operands[2]))
7619 operands[4] = operands[2];
7620 else
7621 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7622 })
7623
7624 (define_insn "*mulv<mode>4"
7625 [(set (reg:CCO FLAGS_REG)
7626 (eq:CCO (mult:<DWI>
7627 (sign_extend:<DWI>
7628 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7629 (sign_extend:<DWI>
7630 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7631 (sign_extend:<DWI>
7632 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7633 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7634 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7635 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7636 "@
7637 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7638 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7639 [(set_attr "type" "imul")
7640 (set_attr "prefix_0f" "0,1")
7641 (set (attr "athlon_decode")
7642 (cond [(eq_attr "cpu" "athlon")
7643 (const_string "vector")
7644 (eq_attr "alternative" "0")
7645 (const_string "vector")
7646 (and (eq_attr "alternative" "1")
7647 (match_operand 1 "memory_operand"))
7648 (const_string "vector")]
7649 (const_string "direct")))
7650 (set (attr "amdfam10_decode")
7651 (cond [(and (eq_attr "alternative" "1")
7652 (match_operand 1 "memory_operand"))
7653 (const_string "vector")]
7654 (const_string "direct")))
7655 (set_attr "bdver1_decode" "direct")
7656 (set_attr "mode" "<MODE>")])
7657
7658 (define_insn "*mulvhi4"
7659 [(set (reg:CCO FLAGS_REG)
7660 (eq:CCO (mult:SI
7661 (sign_extend:SI
7662 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7663 (sign_extend:SI
7664 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7665 (sign_extend:SI
7666 (mult:HI (match_dup 1) (match_dup 2)))))
7667 (set (match_operand:HI 0 "register_operand" "=r")
7668 (mult:HI (match_dup 1) (match_dup 2)))]
7669 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7670 "imul{w}\t{%2, %0|%0, %2}"
7671 [(set_attr "type" "imul")
7672 (set_attr "prefix_0f" "1")
7673 (set_attr "athlon_decode" "vector")
7674 (set_attr "amdfam10_decode" "direct")
7675 (set_attr "bdver1_decode" "double")
7676 (set_attr "mode" "HI")])
7677
7678 (define_insn "*mulv<mode>4_1"
7679 [(set (reg:CCO FLAGS_REG)
7680 (eq:CCO (mult:<DWI>
7681 (sign_extend:<DWI>
7682 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7683 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7684 (sign_extend:<DWI>
7685 (mult:SWI248 (match_dup 1)
7686 (match_operand:SWI248 2
7687 "<immediate_operand>" "K,<i>")))))
7688 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7689 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7690 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7691 && CONST_INT_P (operands[2])
7692 && INTVAL (operands[2]) == INTVAL (operands[3])"
7693 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7694 [(set_attr "type" "imul")
7695 (set (attr "prefix_0f")
7696 (if_then_else
7697 (match_test "<MODE>mode == HImode")
7698 (const_string "0")
7699 (const_string "*")))
7700 (set (attr "athlon_decode")
7701 (cond [(eq_attr "cpu" "athlon")
7702 (const_string "vector")
7703 (eq_attr "alternative" "1")
7704 (const_string "vector")]
7705 (const_string "direct")))
7706 (set (attr "amdfam10_decode")
7707 (cond [(ior (match_test "<MODE>mode == HImode")
7708 (match_operand 1 "memory_operand"))
7709 (const_string "vector")]
7710 (const_string "direct")))
7711 (set (attr "bdver1_decode")
7712 (if_then_else
7713 (match_test "<MODE>mode == HImode")
7714 (const_string "double")
7715 (const_string "direct")))
7716 (set_attr "mode" "<MODE>")
7717 (set (attr "length_immediate")
7718 (cond [(eq_attr "alternative" "0")
7719 (const_string "1")
7720 (match_test "<MODE_SIZE> == 8")
7721 (const_string "4")]
7722 (const_string "<MODE_SIZE>")))])
7723
7724 (define_expand "umulv<mode>4"
7725 [(parallel [(set (reg:CCO FLAGS_REG)
7726 (eq:CCO (mult:<DWI>
7727 (zero_extend:<DWI>
7728 (match_operand:SWI248 1
7729 "nonimmediate_operand"))
7730 (zero_extend:<DWI>
7731 (match_operand:SWI248 2
7732 "nonimmediate_operand")))
7733 (zero_extend:<DWI>
7734 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7735 (set (match_operand:SWI248 0 "register_operand")
7736 (mult:SWI248 (match_dup 1) (match_dup 2)))
7737 (clobber (scratch:SWI248))])
7738 (set (pc) (if_then_else
7739 (eq (reg:CCO FLAGS_REG) (const_int 0))
7740 (label_ref (match_operand 3))
7741 (pc)))]
7742 ""
7743 {
7744 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7745 operands[1] = force_reg (<MODE>mode, operands[1]);
7746 })
7747
7748 (define_insn "*umulv<mode>4"
7749 [(set (reg:CCO FLAGS_REG)
7750 (eq:CCO (mult:<DWI>
7751 (zero_extend:<DWI>
7752 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7753 (zero_extend:<DWI>
7754 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7755 (zero_extend:<DWI>
7756 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7757 (set (match_operand:SWI248 0 "register_operand" "=a")
7758 (mult:SWI248 (match_dup 1) (match_dup 2)))
7759 (clobber (match_scratch:SWI248 3 "=d"))]
7760 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7761 "mul{<imodesuffix>}\t%2"
7762 [(set_attr "type" "imul")
7763 (set_attr "length_immediate" "0")
7764 (set (attr "athlon_decode")
7765 (if_then_else (eq_attr "cpu" "athlon")
7766 (const_string "vector")
7767 (const_string "double")))
7768 (set_attr "amdfam10_decode" "double")
7769 (set_attr "bdver1_decode" "direct")
7770 (set_attr "mode" "<MODE>")])
7771
7772 (define_expand "<u>mulvqi4"
7773 [(parallel [(set (reg:CCO FLAGS_REG)
7774 (eq:CCO (mult:HI
7775 (any_extend:HI
7776 (match_operand:QI 1 "nonimmediate_operand"))
7777 (any_extend:HI
7778 (match_operand:QI 2 "nonimmediate_operand")))
7779 (any_extend:HI
7780 (mult:QI (match_dup 1) (match_dup 2)))))
7781 (set (match_operand:QI 0 "register_operand")
7782 (mult:QI (match_dup 1) (match_dup 2)))])
7783 (set (pc) (if_then_else
7784 (eq (reg:CCO FLAGS_REG) (const_int 0))
7785 (label_ref (match_operand 3))
7786 (pc)))]
7787 "TARGET_QIMODE_MATH"
7788 {
7789 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7790 operands[1] = force_reg (QImode, operands[1]);
7791 })
7792
7793 (define_insn "*<u>mulvqi4"
7794 [(set (reg:CCO FLAGS_REG)
7795 (eq:CCO (mult:HI
7796 (any_extend:HI
7797 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7798 (any_extend:HI
7799 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7800 (any_extend:HI
7801 (mult:QI (match_dup 1) (match_dup 2)))))
7802 (set (match_operand:QI 0 "register_operand" "=a")
7803 (mult:QI (match_dup 1) (match_dup 2)))]
7804 "TARGET_QIMODE_MATH
7805 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7806 "<sgnprefix>mul{b}\t%2"
7807 [(set_attr "type" "imul")
7808 (set_attr "length_immediate" "0")
7809 (set (attr "athlon_decode")
7810 (if_then_else (eq_attr "cpu" "athlon")
7811 (const_string "vector")
7812 (const_string "direct")))
7813 (set_attr "amdfam10_decode" "direct")
7814 (set_attr "bdver1_decode" "direct")
7815 (set_attr "mode" "QI")])
7816
7817 (define_expand "<u>mul<mode><dwi>3"
7818 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7819 (mult:<DWI>
7820 (any_extend:<DWI>
7821 (match_operand:DWIH 1 "nonimmediate_operand"))
7822 (any_extend:<DWI>
7823 (match_operand:DWIH 2 "register_operand"))))
7824 (clobber (reg:CC FLAGS_REG))])])
7825
7826 (define_expand "<u>mulqihi3"
7827 [(parallel [(set (match_operand:HI 0 "register_operand")
7828 (mult:HI
7829 (any_extend:HI
7830 (match_operand:QI 1 "nonimmediate_operand"))
7831 (any_extend:HI
7832 (match_operand:QI 2 "register_operand"))))
7833 (clobber (reg:CC FLAGS_REG))])]
7834 "TARGET_QIMODE_MATH")
7835
7836 (define_insn "*bmi2_umul<mode><dwi>3_1"
7837 [(set (match_operand:DWIH 0 "register_operand" "=r")
7838 (mult:DWIH
7839 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7840 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7841 (set (match_operand:DWIH 1 "register_operand" "=r")
7842 (truncate:DWIH
7843 (lshiftrt:<DWI>
7844 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7845 (zero_extend:<DWI> (match_dup 3)))
7846 (match_operand:QI 4 "const_int_operand" "n"))))]
7847 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7848 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7849 "mulx\t{%3, %0, %1|%1, %0, %3}"
7850 [(set_attr "type" "imulx")
7851 (set_attr "prefix" "vex")
7852 (set_attr "mode" "<MODE>")])
7853
7854 (define_insn "*umul<mode><dwi>3_1"
7855 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7856 (mult:<DWI>
7857 (zero_extend:<DWI>
7858 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7859 (zero_extend:<DWI>
7860 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7861 (clobber (reg:CC FLAGS_REG))]
7862 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7863 "@
7864 #
7865 mul{<imodesuffix>}\t%2"
7866 [(set_attr "isa" "bmi2,*")
7867 (set_attr "type" "imulx,imul")
7868 (set_attr "length_immediate" "*,0")
7869 (set (attr "athlon_decode")
7870 (cond [(eq_attr "alternative" "1")
7871 (if_then_else (eq_attr "cpu" "athlon")
7872 (const_string "vector")
7873 (const_string "double"))]
7874 (const_string "*")))
7875 (set_attr "amdfam10_decode" "*,double")
7876 (set_attr "bdver1_decode" "*,direct")
7877 (set_attr "prefix" "vex,orig")
7878 (set_attr "mode" "<MODE>")])
7879
7880 ;; Convert mul to the mulx pattern to avoid flags dependency.
7881 (define_split
7882 [(set (match_operand:<DWI> 0 "register_operand")
7883 (mult:<DWI>
7884 (zero_extend:<DWI>
7885 (match_operand:DWIH 1 "register_operand"))
7886 (zero_extend:<DWI>
7887 (match_operand:DWIH 2 "nonimmediate_operand"))))
7888 (clobber (reg:CC FLAGS_REG))]
7889 "TARGET_BMI2 && reload_completed
7890 && REGNO (operands[1]) == DX_REG"
7891 [(parallel [(set (match_dup 3)
7892 (mult:DWIH (match_dup 1) (match_dup 2)))
7893 (set (match_dup 4)
7894 (truncate:DWIH
7895 (lshiftrt:<DWI>
7896 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7897 (zero_extend:<DWI> (match_dup 2)))
7898 (match_dup 5))))])]
7899 {
7900 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7901
7902 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7903 })
7904
7905 (define_insn "*mul<mode><dwi>3_1"
7906 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7907 (mult:<DWI>
7908 (sign_extend:<DWI>
7909 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7910 (sign_extend:<DWI>
7911 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7912 (clobber (reg:CC FLAGS_REG))]
7913 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7914 "imul{<imodesuffix>}\t%2"
7915 [(set_attr "type" "imul")
7916 (set_attr "length_immediate" "0")
7917 (set (attr "athlon_decode")
7918 (if_then_else (eq_attr "cpu" "athlon")
7919 (const_string "vector")
7920 (const_string "double")))
7921 (set_attr "amdfam10_decode" "double")
7922 (set_attr "bdver1_decode" "direct")
7923 (set_attr "mode" "<MODE>")])
7924
7925 (define_insn "*<u>mulqihi3_1"
7926 [(set (match_operand:HI 0 "register_operand" "=a")
7927 (mult:HI
7928 (any_extend:HI
7929 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7930 (any_extend:HI
7931 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7932 (clobber (reg:CC FLAGS_REG))]
7933 "TARGET_QIMODE_MATH
7934 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7935 "<sgnprefix>mul{b}\t%2"
7936 [(set_attr "type" "imul")
7937 (set_attr "length_immediate" "0")
7938 (set (attr "athlon_decode")
7939 (if_then_else (eq_attr "cpu" "athlon")
7940 (const_string "vector")
7941 (const_string "direct")))
7942 (set_attr "amdfam10_decode" "direct")
7943 (set_attr "bdver1_decode" "direct")
7944 (set_attr "mode" "QI")])
7945
7946 (define_expand "<s>mul<mode>3_highpart"
7947 [(parallel [(set (match_operand:DWIH 0 "register_operand")
7948 (truncate:DWIH
7949 (lshiftrt:<DWI>
7950 (mult:<DWI>
7951 (any_extend:<DWI>
7952 (match_operand:DWIH 1 "nonimmediate_operand"))
7953 (any_extend:<DWI>
7954 (match_operand:DWIH 2 "register_operand")))
7955 (match_dup 3))))
7956 (clobber (scratch:DWIH))
7957 (clobber (reg:CC FLAGS_REG))])]
7958 ""
7959 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7960
7961 (define_insn "*<s>muldi3_highpart_1"
7962 [(set (match_operand:DI 0 "register_operand" "=d")
7963 (truncate:DI
7964 (lshiftrt:TI
7965 (mult:TI
7966 (any_extend:TI
7967 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7968 (any_extend:TI
7969 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7970 (const_int 64))))
7971 (clobber (match_scratch:DI 3 "=1"))
7972 (clobber (reg:CC FLAGS_REG))]
7973 "TARGET_64BIT
7974 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7975 "<sgnprefix>mul{q}\t%2"
7976 [(set_attr "type" "imul")
7977 (set_attr "length_immediate" "0")
7978 (set (attr "athlon_decode")
7979 (if_then_else (eq_attr "cpu" "athlon")
7980 (const_string "vector")
7981 (const_string "double")))
7982 (set_attr "amdfam10_decode" "double")
7983 (set_attr "bdver1_decode" "direct")
7984 (set_attr "mode" "DI")])
7985
7986 (define_insn "*<s>mulsi3_highpart_zext"
7987 [(set (match_operand:DI 0 "register_operand" "=d")
7988 (zero_extend:DI (truncate:SI
7989 (lshiftrt:DI
7990 (mult:DI (any_extend:DI
7991 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7992 (any_extend:DI
7993 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7994 (const_int 32)))))
7995 (clobber (match_scratch:SI 3 "=1"))
7996 (clobber (reg:CC FLAGS_REG))]
7997 "TARGET_64BIT
7998 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7999 "<sgnprefix>mul{l}\t%2"
8000 [(set_attr "type" "imul")
8001 (set_attr "length_immediate" "0")
8002 (set (attr "athlon_decode")
8003 (if_then_else (eq_attr "cpu" "athlon")
8004 (const_string "vector")
8005 (const_string "double")))
8006 (set_attr "amdfam10_decode" "double")
8007 (set_attr "bdver1_decode" "direct")
8008 (set_attr "mode" "SI")])
8009
8010 (define_insn "*<s>mulsi3_highpart_1"
8011 [(set (match_operand:SI 0 "register_operand" "=d")
8012 (truncate:SI
8013 (lshiftrt:DI
8014 (mult:DI
8015 (any_extend:DI
8016 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8017 (any_extend:DI
8018 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8019 (const_int 32))))
8020 (clobber (match_scratch:SI 3 "=1"))
8021 (clobber (reg:CC FLAGS_REG))]
8022 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8023 "<sgnprefix>mul{l}\t%2"
8024 [(set_attr "type" "imul")
8025 (set_attr "length_immediate" "0")
8026 (set (attr "athlon_decode")
8027 (if_then_else (eq_attr "cpu" "athlon")
8028 (const_string "vector")
8029 (const_string "double")))
8030 (set_attr "amdfam10_decode" "double")
8031 (set_attr "bdver1_decode" "direct")
8032 (set_attr "mode" "SI")])
8033
8034 ;; The patterns that match these are at the end of this file.
8035
8036 (define_expand "mulxf3"
8037 [(set (match_operand:XF 0 "register_operand")
8038 (mult:XF (match_operand:XF 1 "register_operand")
8039 (match_operand:XF 2 "register_operand")))]
8040 "TARGET_80387")
8041
8042 (define_expand "mul<mode>3"
8043 [(set (match_operand:MODEF 0 "register_operand")
8044 (mult:MODEF (match_operand:MODEF 1 "register_operand")
8045 (match_operand:MODEF 2 "nonimmediate_operand")))]
8046 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8047 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
8048 \f
8049 ;; Divide instructions
8050
8051 ;; The patterns that match these are at the end of this file.
8052
8053 (define_expand "divxf3"
8054 [(set (match_operand:XF 0 "register_operand")
8055 (div:XF (match_operand:XF 1 "register_operand")
8056 (match_operand:XF 2 "register_operand")))]
8057 "TARGET_80387")
8058
8059 (define_expand "div<mode>3"
8060 [(set (match_operand:MODEF 0 "register_operand")
8061 (div:MODEF (match_operand:MODEF 1 "register_operand")
8062 (match_operand:MODEF 2 "nonimmediate_operand")))]
8063 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8064 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8065 {
8066 if (<MODE>mode == SFmode
8067 && TARGET_SSE && TARGET_SSE_MATH
8068 && TARGET_RECIP_DIV
8069 && optimize_insn_for_speed_p ()
8070 && flag_finite_math_only && !flag_trapping_math
8071 && flag_unsafe_math_optimizations)
8072 {
8073 ix86_emit_swdivsf (operands[0], operands[1],
8074 operands[2], SFmode);
8075 DONE;
8076 }
8077 })
8078 \f
8079 ;; Divmod instructions.
8080
8081 (define_code_iterator any_div [div udiv])
8082 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
8083
8084 (define_expand "<u>divmod<mode>4"
8085 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8086 (any_div:SWIM248
8087 (match_operand:SWIM248 1 "register_operand")
8088 (match_operand:SWIM248 2 "nonimmediate_operand")))
8089 (set (match_operand:SWIM248 3 "register_operand")
8090 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
8091 (clobber (reg:CC FLAGS_REG))])])
8092
8093 ;; Split with 8bit unsigned divide:
8094 ;; if (dividend an divisor are in [0-255])
8095 ;; use 8bit unsigned integer divide
8096 ;; else
8097 ;; use original integer divide
8098 (define_split
8099 [(set (match_operand:SWI48 0 "register_operand")
8100 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
8101 (match_operand:SWI48 3 "nonimmediate_operand")))
8102 (set (match_operand:SWI48 1 "register_operand")
8103 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
8104 (clobber (reg:CC FLAGS_REG))]
8105 "TARGET_USE_8BIT_IDIV
8106 && TARGET_QIMODE_MATH
8107 && can_create_pseudo_p ()
8108 && !optimize_insn_for_size_p ()"
8109 [(const_int 0)]
8110 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
8111
8112 (define_split
8113 [(set (match_operand:DI 0 "register_operand")
8114 (zero_extend:DI
8115 (any_div:SI (match_operand:SI 2 "register_operand")
8116 (match_operand:SI 3 "nonimmediate_operand"))))
8117 (set (match_operand:SI 1 "register_operand")
8118 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
8119 (clobber (reg:CC FLAGS_REG))]
8120 "TARGET_64BIT
8121 && TARGET_USE_8BIT_IDIV
8122 && TARGET_QIMODE_MATH
8123 && can_create_pseudo_p ()
8124 && !optimize_insn_for_size_p ()"
8125 [(const_int 0)]
8126 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
8127
8128 (define_split
8129 [(set (match_operand:DI 1 "register_operand")
8130 (zero_extend:DI
8131 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
8132 (match_operand:SI 3 "nonimmediate_operand"))))
8133 (set (match_operand:SI 0 "register_operand")
8134 (any_div:SI (match_dup 2) (match_dup 3)))
8135 (clobber (reg:CC FLAGS_REG))]
8136 "TARGET_64BIT
8137 && TARGET_USE_8BIT_IDIV
8138 && TARGET_QIMODE_MATH
8139 && can_create_pseudo_p ()
8140 && !optimize_insn_for_size_p ()"
8141 [(const_int 0)]
8142 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
8143
8144 (define_insn_and_split "divmod<mode>4_1"
8145 [(set (match_operand:SWI48 0 "register_operand" "=a")
8146 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8147 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8148 (set (match_operand:SWI48 1 "register_operand" "=&d")
8149 (mod:SWI48 (match_dup 2) (match_dup 3)))
8150 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8151 (clobber (reg:CC FLAGS_REG))]
8152 ""
8153 "#"
8154 "reload_completed"
8155 [(parallel [(set (match_dup 1)
8156 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
8157 (clobber (reg:CC FLAGS_REG))])
8158 (parallel [(set (match_dup 0)
8159 (div:SWI48 (match_dup 2) (match_dup 3)))
8160 (set (match_dup 1)
8161 (mod:SWI48 (match_dup 2) (match_dup 3)))
8162 (use (match_dup 1))
8163 (clobber (reg:CC FLAGS_REG))])]
8164 {
8165 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8166
8167 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8168 operands[4] = operands[2];
8169 else
8170 {
8171 /* Avoid use of cltd in favor of a mov+shift. */
8172 emit_move_insn (operands[1], operands[2]);
8173 operands[4] = operands[1];
8174 }
8175 }
8176 [(set_attr "type" "multi")
8177 (set_attr "mode" "<MODE>")])
8178
8179 (define_insn_and_split "udivmod<mode>4_1"
8180 [(set (match_operand:SWI48 0 "register_operand" "=a")
8181 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8182 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8183 (set (match_operand:SWI48 1 "register_operand" "=&d")
8184 (umod:SWI48 (match_dup 2) (match_dup 3)))
8185 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8186 (clobber (reg:CC FLAGS_REG))]
8187 ""
8188 "#"
8189 "reload_completed"
8190 [(set (match_dup 1) (const_int 0))
8191 (parallel [(set (match_dup 0)
8192 (udiv:SWI48 (match_dup 2) (match_dup 3)))
8193 (set (match_dup 1)
8194 (umod:SWI48 (match_dup 2) (match_dup 3)))
8195 (use (match_dup 1))
8196 (clobber (reg:CC FLAGS_REG))])]
8197 ""
8198 [(set_attr "type" "multi")
8199 (set_attr "mode" "<MODE>")])
8200
8201 (define_insn_and_split "divmodsi4_zext_1"
8202 [(set (match_operand:DI 0 "register_operand" "=a")
8203 (zero_extend:DI
8204 (div:SI (match_operand:SI 2 "register_operand" "0")
8205 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8206 (set (match_operand:SI 1 "register_operand" "=&d")
8207 (mod:SI (match_dup 2) (match_dup 3)))
8208 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8209 (clobber (reg:CC FLAGS_REG))]
8210 "TARGET_64BIT"
8211 "#"
8212 "&& reload_completed"
8213 [(parallel [(set (match_dup 1)
8214 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8215 (clobber (reg:CC FLAGS_REG))])
8216 (parallel [(set (match_dup 0)
8217 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8218 (set (match_dup 1)
8219 (mod:SI (match_dup 2) (match_dup 3)))
8220 (use (match_dup 1))
8221 (clobber (reg:CC FLAGS_REG))])]
8222 {
8223 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8224
8225 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8226 operands[4] = operands[2];
8227 else
8228 {
8229 /* Avoid use of cltd in favor of a mov+shift. */
8230 emit_move_insn (operands[1], operands[2]);
8231 operands[4] = operands[1];
8232 }
8233 }
8234 [(set_attr "type" "multi")
8235 (set_attr "mode" "SI")])
8236
8237 (define_insn_and_split "udivmodsi4_zext_1"
8238 [(set (match_operand:DI 0 "register_operand" "=a")
8239 (zero_extend:DI
8240 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8241 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8242 (set (match_operand:SI 1 "register_operand" "=&d")
8243 (umod:SI (match_dup 2) (match_dup 3)))
8244 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8245 (clobber (reg:CC FLAGS_REG))]
8246 "TARGET_64BIT"
8247 "#"
8248 "&& reload_completed"
8249 [(set (match_dup 1) (const_int 0))
8250 (parallel [(set (match_dup 0)
8251 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8252 (set (match_dup 1)
8253 (umod:SI (match_dup 2) (match_dup 3)))
8254 (use (match_dup 1))
8255 (clobber (reg:CC FLAGS_REG))])]
8256 ""
8257 [(set_attr "type" "multi")
8258 (set_attr "mode" "SI")])
8259
8260 (define_insn_and_split "divmodsi4_zext_2"
8261 [(set (match_operand:DI 1 "register_operand" "=&d")
8262 (zero_extend:DI
8263 (mod:SI (match_operand:SI 2 "register_operand" "0")
8264 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8265 (set (match_operand:SI 0 "register_operand" "=a")
8266 (div:SI (match_dup 2) (match_dup 3)))
8267 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8268 (clobber (reg:CC FLAGS_REG))]
8269 "TARGET_64BIT"
8270 "#"
8271 "&& reload_completed"
8272 [(parallel [(set (match_dup 6)
8273 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8274 (clobber (reg:CC FLAGS_REG))])
8275 (parallel [(set (match_dup 1)
8276 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8277 (set (match_dup 0)
8278 (div:SI (match_dup 2) (match_dup 3)))
8279 (use (match_dup 6))
8280 (clobber (reg:CC FLAGS_REG))])]
8281 {
8282 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8283 operands[6] = gen_lowpart (SImode, operands[1]);
8284
8285 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8286 operands[4] = operands[2];
8287 else
8288 {
8289 /* Avoid use of cltd in favor of a mov+shift. */
8290 emit_move_insn (operands[6], operands[2]);
8291 operands[4] = operands[6];
8292 }
8293 }
8294 [(set_attr "type" "multi")
8295 (set_attr "mode" "SI")])
8296
8297 (define_insn_and_split "udivmodsi4_zext_2"
8298 [(set (match_operand:DI 1 "register_operand" "=&d")
8299 (zero_extend:DI
8300 (umod:SI (match_operand:SI 2 "register_operand" "0")
8301 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8302 (set (match_operand:SI 0 "register_operand" "=a")
8303 (udiv:SI (match_dup 2) (match_dup 3)))
8304 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8305 (clobber (reg:CC FLAGS_REG))]
8306 "TARGET_64BIT"
8307 "#"
8308 "&& reload_completed"
8309 [(set (match_dup 4) (const_int 0))
8310 (parallel [(set (match_dup 1)
8311 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8312 (set (match_dup 0)
8313 (udiv:SI (match_dup 2) (match_dup 3)))
8314 (use (match_dup 4))
8315 (clobber (reg:CC FLAGS_REG))])]
8316 "operands[4] = gen_lowpart (SImode, operands[1]);"
8317 [(set_attr "type" "multi")
8318 (set_attr "mode" "SI")])
8319
8320 (define_insn_and_split "*divmod<mode>4"
8321 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8322 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8323 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8324 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8325 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8326 (clobber (reg:CC FLAGS_REG))]
8327 ""
8328 "#"
8329 "reload_completed"
8330 [(parallel [(set (match_dup 1)
8331 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8332 (clobber (reg:CC FLAGS_REG))])
8333 (parallel [(set (match_dup 0)
8334 (div:SWIM248 (match_dup 2) (match_dup 3)))
8335 (set (match_dup 1)
8336 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8337 (use (match_dup 1))
8338 (clobber (reg:CC FLAGS_REG))])]
8339 {
8340 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8341
8342 if (<MODE>mode != HImode
8343 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8344 operands[4] = operands[2];
8345 else
8346 {
8347 /* Avoid use of cltd in favor of a mov+shift. */
8348 emit_move_insn (operands[1], operands[2]);
8349 operands[4] = operands[1];
8350 }
8351 }
8352 [(set_attr "type" "multi")
8353 (set_attr "mode" "<MODE>")])
8354
8355 (define_insn_and_split "*udivmod<mode>4"
8356 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8357 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8358 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8359 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8360 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8361 (clobber (reg:CC FLAGS_REG))]
8362 ""
8363 "#"
8364 "reload_completed"
8365 [(set (match_dup 1) (const_int 0))
8366 (parallel [(set (match_dup 0)
8367 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8368 (set (match_dup 1)
8369 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8370 (use (match_dup 1))
8371 (clobber (reg:CC FLAGS_REG))])]
8372 ""
8373 [(set_attr "type" "multi")
8374 (set_attr "mode" "<MODE>")])
8375
8376 ;; Optimize division or modulo by constant power of 2, if the constant
8377 ;; materializes only after expansion.
8378 (define_insn_and_split "*udivmod<mode>4_pow2"
8379 [(set (match_operand:SWI48 0 "register_operand" "=r")
8380 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8381 (match_operand:SWI48 3 "const_int_operand" "n")))
8382 (set (match_operand:SWI48 1 "register_operand" "=r")
8383 (umod:SWI48 (match_dup 2) (match_dup 3)))
8384 (clobber (reg:CC FLAGS_REG))]
8385 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
8386 "#"
8387 "&& reload_completed"
8388 [(set (match_dup 1) (match_dup 2))
8389 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8390 (clobber (reg:CC FLAGS_REG))])
8391 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8392 (clobber (reg:CC FLAGS_REG))])]
8393 {
8394 int v = exact_log2 (UINTVAL (operands[3]));
8395 operands[4] = GEN_INT (v);
8396 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8397 }
8398 [(set_attr "type" "multi")
8399 (set_attr "mode" "<MODE>")])
8400
8401 (define_insn_and_split "*divmodsi4_zext_1"
8402 [(set (match_operand:DI 0 "register_operand" "=a")
8403 (zero_extend:DI
8404 (div:SI (match_operand:SI 2 "register_operand" "0")
8405 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8406 (set (match_operand:SI 1 "register_operand" "=&d")
8407 (mod:SI (match_dup 2) (match_dup 3)))
8408 (clobber (reg:CC FLAGS_REG))]
8409 "TARGET_64BIT"
8410 "#"
8411 "&& reload_completed"
8412 [(parallel [(set (match_dup 1)
8413 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8414 (clobber (reg:CC FLAGS_REG))])
8415 (parallel [(set (match_dup 0)
8416 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8417 (set (match_dup 1)
8418 (mod:SI (match_dup 2) (match_dup 3)))
8419 (use (match_dup 1))
8420 (clobber (reg:CC FLAGS_REG))])]
8421 {
8422 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8423
8424 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8425 operands[4] = operands[2];
8426 else
8427 {
8428 /* Avoid use of cltd in favor of a mov+shift. */
8429 emit_move_insn (operands[1], operands[2]);
8430 operands[4] = operands[1];
8431 }
8432 }
8433 [(set_attr "type" "multi")
8434 (set_attr "mode" "SI")])
8435
8436 (define_insn_and_split "*udivmodsi4_zext_1"
8437 [(set (match_operand:DI 0 "register_operand" "=a")
8438 (zero_extend:DI
8439 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8440 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8441 (set (match_operand:SI 1 "register_operand" "=&d")
8442 (umod:SI (match_dup 2) (match_dup 3)))
8443 (clobber (reg:CC FLAGS_REG))]
8444 "TARGET_64BIT"
8445 "#"
8446 "&& reload_completed"
8447 [(set (match_dup 1) (const_int 0))
8448 (parallel [(set (match_dup 0)
8449 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8450 (set (match_dup 1)
8451 (umod:SI (match_dup 2) (match_dup 3)))
8452 (use (match_dup 1))
8453 (clobber (reg:CC FLAGS_REG))])]
8454 ""
8455 [(set_attr "type" "multi")
8456 (set_attr "mode" "SI")])
8457
8458 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8459 [(set (match_operand:DI 0 "register_operand" "=r")
8460 (zero_extend:DI
8461 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8462 (match_operand:SI 3 "const_int_operand" "n"))))
8463 (set (match_operand:SI 1 "register_operand" "=r")
8464 (umod:SI (match_dup 2) (match_dup 3)))
8465 (clobber (reg:CC FLAGS_REG))]
8466 "TARGET_64BIT
8467 && exact_log2 (UINTVAL (operands[3])) > 0"
8468 "#"
8469 "&& reload_completed"
8470 [(set (match_dup 1) (match_dup 2))
8471 (parallel [(set (match_dup 0)
8472 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8473 (clobber (reg:CC FLAGS_REG))])
8474 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8475 (clobber (reg:CC FLAGS_REG))])]
8476 {
8477 int v = exact_log2 (UINTVAL (operands[3]));
8478 operands[4] = GEN_INT (v);
8479 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8480 }
8481 [(set_attr "type" "multi")
8482 (set_attr "mode" "SI")])
8483
8484 (define_insn_and_split "*divmodsi4_zext_2"
8485 [(set (match_operand:DI 1 "register_operand" "=&d")
8486 (zero_extend:DI
8487 (mod:SI (match_operand:SI 2 "register_operand" "0")
8488 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8489 (set (match_operand:SI 0 "register_operand" "=a")
8490 (div:SI (match_dup 2) (match_dup 3)))
8491 (clobber (reg:CC FLAGS_REG))]
8492 "TARGET_64BIT"
8493 "#"
8494 "&& reload_completed"
8495 [(parallel [(set (match_dup 6)
8496 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8497 (clobber (reg:CC FLAGS_REG))])
8498 (parallel [(set (match_dup 1)
8499 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8500 (set (match_dup 0)
8501 (div:SI (match_dup 2) (match_dup 3)))
8502 (use (match_dup 6))
8503 (clobber (reg:CC FLAGS_REG))])]
8504 {
8505 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8506 operands[6] = gen_lowpart (SImode, operands[1]);
8507
8508 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8509 operands[4] = operands[2];
8510 else
8511 {
8512 /* Avoid use of cltd in favor of a mov+shift. */
8513 emit_move_insn (operands[6], operands[2]);
8514 operands[4] = operands[6];
8515 }
8516 }
8517 [(set_attr "type" "multi")
8518 (set_attr "mode" "SI")])
8519
8520 (define_insn_and_split "*udivmodsi4_zext_2"
8521 [(set (match_operand:DI 1 "register_operand" "=&d")
8522 (zero_extend:DI
8523 (umod:SI (match_operand:SI 2 "register_operand" "0")
8524 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8525 (set (match_operand:SI 0 "register_operand" "=a")
8526 (udiv:SI (match_dup 2) (match_dup 3)))
8527 (clobber (reg:CC FLAGS_REG))]
8528 "TARGET_64BIT"
8529 "#"
8530 "&& reload_completed"
8531 [(set (match_dup 4) (const_int 0))
8532 (parallel [(set (match_dup 1)
8533 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8534 (set (match_dup 0)
8535 (udiv:SI (match_dup 2) (match_dup 3)))
8536 (use (match_dup 4))
8537 (clobber (reg:CC FLAGS_REG))])]
8538 "operands[4] = gen_lowpart (SImode, operands[1]);"
8539 [(set_attr "type" "multi")
8540 (set_attr "mode" "SI")])
8541
8542 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8543 [(set (match_operand:DI 1 "register_operand" "=r")
8544 (zero_extend:DI
8545 (umod:SI (match_operand:SI 2 "register_operand" "0")
8546 (match_operand:SI 3 "const_int_operand" "n"))))
8547 (set (match_operand:SI 0 "register_operand" "=r")
8548 (umod:SI (match_dup 2) (match_dup 3)))
8549 (clobber (reg:CC FLAGS_REG))]
8550 "TARGET_64BIT
8551 && exact_log2 (UINTVAL (operands[3])) > 0"
8552 "#"
8553 "&& reload_completed"
8554 [(set (match_dup 1) (match_dup 2))
8555 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8556 (clobber (reg:CC FLAGS_REG))])
8557 (parallel [(set (match_dup 1)
8558 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8559 (clobber (reg:CC FLAGS_REG))])]
8560 {
8561 int v = exact_log2 (UINTVAL (operands[3]));
8562 operands[4] = GEN_INT (v);
8563 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8564 }
8565 [(set_attr "type" "multi")
8566 (set_attr "mode" "SI")])
8567
8568 (define_insn "*<u>divmod<mode>4_noext"
8569 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8570 (any_div:SWIM248
8571 (match_operand:SWIM248 2 "register_operand" "0")
8572 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8573 (set (match_operand:SWIM248 1 "register_operand" "=d")
8574 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
8575 (use (match_operand:SWIM248 4 "register_operand" "1"))
8576 (clobber (reg:CC FLAGS_REG))]
8577 ""
8578 "<sgnprefix>div{<imodesuffix>}\t%3"
8579 [(set_attr "type" "idiv")
8580 (set_attr "mode" "<MODE>")])
8581
8582 (define_insn "*<u>divmodsi4_noext_zext_1"
8583 [(set (match_operand:DI 0 "register_operand" "=a")
8584 (zero_extend:DI
8585 (any_div:SI (match_operand:SI 2 "register_operand" "0")
8586 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8587 (set (match_operand:SI 1 "register_operand" "=d")
8588 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
8589 (use (match_operand:SI 4 "register_operand" "1"))
8590 (clobber (reg:CC FLAGS_REG))]
8591 "TARGET_64BIT"
8592 "<sgnprefix>div{l}\t%3"
8593 [(set_attr "type" "idiv")
8594 (set_attr "mode" "SI")])
8595
8596 (define_insn "*<u>divmodsi4_noext_zext_2"
8597 [(set (match_operand:DI 1 "register_operand" "=d")
8598 (zero_extend:DI
8599 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
8600 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8601 (set (match_operand:SI 0 "register_operand" "=a")
8602 (any_div:SI (match_dup 2) (match_dup 3)))
8603 (use (match_operand:SI 4 "register_operand" "1"))
8604 (clobber (reg:CC FLAGS_REG))]
8605 "TARGET_64BIT"
8606 "<sgnprefix>div{l}\t%3"
8607 [(set_attr "type" "idiv")
8608 (set_attr "mode" "SI")])
8609
8610 (define_expand "divmodqi4"
8611 [(parallel [(set (match_operand:QI 0 "register_operand")
8612 (div:QI
8613 (match_operand:QI 1 "register_operand")
8614 (match_operand:QI 2 "nonimmediate_operand")))
8615 (set (match_operand:QI 3 "register_operand")
8616 (mod:QI (match_dup 1) (match_dup 2)))
8617 (clobber (reg:CC FLAGS_REG))])]
8618 "TARGET_QIMODE_MATH"
8619 {
8620 rtx div, mod;
8621 rtx tmp0, tmp1;
8622
8623 tmp0 = gen_reg_rtx (HImode);
8624 tmp1 = gen_reg_rtx (HImode);
8625
8626 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8627 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8628 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8629
8630 /* Extract remainder from AH. */
8631 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
8632 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
8633 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8634
8635 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8636 set_unique_reg_note (insn, REG_EQUAL, mod);
8637
8638 /* Extract quotient from AL. */
8639 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8640
8641 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8642 set_unique_reg_note (insn, REG_EQUAL, div);
8643
8644 DONE;
8645 })
8646
8647 (define_expand "udivmodqi4"
8648 [(parallel [(set (match_operand:QI 0 "register_operand")
8649 (udiv:QI
8650 (match_operand:QI 1 "register_operand")
8651 (match_operand:QI 2 "nonimmediate_operand")))
8652 (set (match_operand:QI 3 "register_operand")
8653 (umod:QI (match_dup 1) (match_dup 2)))
8654 (clobber (reg:CC FLAGS_REG))])]
8655 "TARGET_QIMODE_MATH"
8656 {
8657 rtx div, mod;
8658 rtx tmp0, tmp1;
8659
8660 tmp0 = gen_reg_rtx (HImode);
8661 tmp1 = gen_reg_rtx (HImode);
8662
8663 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8664 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8665 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8666
8667 /* Extract remainder from AH. */
8668 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
8669 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
8670 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8671
8672 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8673 set_unique_reg_note (insn, REG_EQUAL, mod);
8674
8675 /* Extract quotient from AL. */
8676 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8677
8678 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8679 set_unique_reg_note (insn, REG_EQUAL, div);
8680
8681 DONE;
8682 })
8683
8684 ;; Divide AX by r/m8, with result stored in
8685 ;; AL <- Quotient
8686 ;; AH <- Remainder
8687 ;; Change div/mod to HImode and extend the second argument to HImode
8688 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8689 ;; combine may fail.
8690 (define_insn "<u>divmodhiqi3"
8691 [(set (match_operand:HI 0 "register_operand" "=a")
8692 (ior:HI
8693 (ashift:HI
8694 (zero_extend:HI
8695 (truncate:QI
8696 (mod:HI (match_operand:HI 1 "register_operand" "0")
8697 (any_extend:HI
8698 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8699 (const_int 8))
8700 (zero_extend:HI
8701 (truncate:QI
8702 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
8703 (clobber (reg:CC FLAGS_REG))]
8704 "TARGET_QIMODE_MATH"
8705 "<sgnprefix>div{b}\t%2"
8706 [(set_attr "type" "idiv")
8707 (set_attr "mode" "QI")])
8708
8709 ;; We cannot use div/idiv for double division, because it causes
8710 ;; "division by zero" on the overflow and that's not what we expect
8711 ;; from truncate. Because true (non truncating) double division is
8712 ;; never generated, we can't create this insn anyway.
8713 ;
8714 ;(define_insn ""
8715 ; [(set (match_operand:SI 0 "register_operand" "=a")
8716 ; (truncate:SI
8717 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8718 ; (zero_extend:DI
8719 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8720 ; (set (match_operand:SI 3 "register_operand" "=d")
8721 ; (truncate:SI
8722 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8723 ; (clobber (reg:CC FLAGS_REG))]
8724 ; ""
8725 ; "div{l}\t{%2, %0|%0, %2}"
8726 ; [(set_attr "type" "idiv")])
8727 \f
8728 ;;- Logical AND instructions
8729
8730 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8731 ;; Note that this excludes ah.
8732
8733 (define_expand "@test<mode>_ccno_1"
8734 [(set (reg:CCNO FLAGS_REG)
8735 (compare:CCNO
8736 (and:SWI48
8737 (match_operand:SWI48 0 "nonimmediate_operand")
8738 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
8739 (const_int 0)))])
8740
8741 (define_expand "testqi_ccz_1"
8742 [(set (reg:CCZ FLAGS_REG)
8743 (compare:CCZ
8744 (and:QI
8745 (match_operand:QI 0 "nonimmediate_operand")
8746 (match_operand:QI 1 "nonmemory_operand"))
8747 (const_int 0)))])
8748
8749 (define_insn "*testdi_1"
8750 [(set (reg FLAGS_REG)
8751 (compare
8752 (and:DI
8753 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
8754 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
8755 (const_int 0)))]
8756 "TARGET_64BIT
8757 && ix86_match_ccmode
8758 (insn,
8759 /* If we are going to emit testl instead of testq, and the operands[1]
8760 constant might have the SImode sign bit set, make sure the sign
8761 flag isn't tested, because the instruction will set the sign flag
8762 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8763 conservatively assume it might have bit 31 set. */
8764 (satisfies_constraint_Z (operands[1])
8765 && (!CONST_INT_P (operands[1])
8766 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
8767 ? CCZmode : CCNOmode)"
8768 "@
8769 test{l}\t{%k1, %k0|%k0, %k1}
8770 test{q}\t{%1, %0|%0, %1}"
8771 [(set_attr "type" "test")
8772 (set_attr "mode" "SI,DI")])
8773
8774 (define_insn "*testqi_1_maybe_si"
8775 [(set (reg FLAGS_REG)
8776 (compare
8777 (and:QI
8778 (match_operand:QI 0 "nonimmediate_operand" "%qm,*a,qm,r")
8779 (match_operand:QI 1 "nonmemory_operand" "q,n,n,n"))
8780 (const_int 0)))]
8781 "ix86_match_ccmode (insn,
8782 CONST_INT_P (operands[1])
8783 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8784 {
8785 if (which_alternative == 3)
8786 {
8787 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8788 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8789 return "test{l}\t{%1, %k0|%k0, %1}";
8790 }
8791 return "test{b}\t{%1, %0|%0, %1}";
8792 }
8793 [(set_attr "type" "test")
8794 (set_attr "mode" "QI,QI,QI,SI")
8795 (set_attr "pent_pair" "uv,uv,np,np")])
8796
8797 (define_insn "*test<mode>_1"
8798 [(set (reg FLAGS_REG)
8799 (compare
8800 (and:SWI124
8801 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
8802 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
8803 (const_int 0)))]
8804 "ix86_match_ccmode (insn, CCNOmode)"
8805 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8806 [(set_attr "type" "test")
8807 (set_attr "mode" "<MODE>")
8808 (set_attr "pent_pair" "uv,uv,np")])
8809
8810 (define_expand "testqi_ext_1_ccno"
8811 [(set (reg:CCNO FLAGS_REG)
8812 (compare:CCNO
8813 (and:QI
8814 (subreg:QI
8815 (zero_extract:HI
8816 (match_operand:HI 0 "register_operand")
8817 (const_int 8)
8818 (const_int 8)) 0)
8819 (match_operand:QI 1 "const_int_operand"))
8820 (const_int 0)))])
8821
8822 (define_insn "*testqi_ext<mode>_1"
8823 [(set (reg FLAGS_REG)
8824 (compare
8825 (and:QI
8826 (subreg:QI
8827 (zero_extract:SWI248
8828 (match_operand:SWI248 0 "register_operand" "Q,Q")
8829 (const_int 8)
8830 (const_int 8)) 0)
8831 (match_operand:QI 1 "general_operand" "QnBc,m"))
8832 (const_int 0)))]
8833 "ix86_match_ccmode (insn, CCNOmode)"
8834 "test{b}\t{%1, %h0|%h0, %1}"
8835 [(set_attr "isa" "*,nox64")
8836 (set_attr "type" "test")
8837 (set_attr "mode" "QI")])
8838
8839 (define_insn "*testqi_ext<mode>_2"
8840 [(set (reg FLAGS_REG)
8841 (compare
8842 (and:QI
8843 (subreg:QI
8844 (zero_extract:SWI248
8845 (match_operand:SWI248 0 "register_operand" "Q")
8846 (const_int 8)
8847 (const_int 8)) 0)
8848 (subreg:QI
8849 (zero_extract:SWI248
8850 (match_operand:SWI248 1 "register_operand" "Q")
8851 (const_int 8)
8852 (const_int 8)) 0))
8853 (const_int 0)))]
8854 "ix86_match_ccmode (insn, CCNOmode)"
8855 "test{b}\t{%h1, %h0|%h0, %h1}"
8856 [(set_attr "type" "test")
8857 (set_attr "mode" "QI")])
8858
8859 ;; Combine likes to form bit extractions for some tests. Humor it.
8860 (define_insn_and_split "*testqi_ext_3"
8861 [(set (match_operand 0 "flags_reg_operand")
8862 (match_operator 1 "compare_operator"
8863 [(zero_extract:SWI248
8864 (match_operand 2 "int_nonimmediate_operand" "rm")
8865 (match_operand 3 "const_int_operand" "n")
8866 (match_operand 4 "const_int_operand" "n"))
8867 (const_int 0)]))]
8868 "/* Ensure that resulting mask is zero or sign extended operand. */
8869 INTVAL (operands[4]) >= 0
8870 && ((INTVAL (operands[3]) > 0
8871 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8872 || (<MODE>mode == DImode
8873 && INTVAL (operands[3]) > 32
8874 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
8875 && ix86_match_ccmode (insn,
8876 /* If zero_extract mode precision is the same
8877 as len, the SF of the zero_extract
8878 comparison will be the most significant
8879 extracted bit, but this could be matched
8880 after splitting only for pos 0 len all bits
8881 trivial extractions. Require CCZmode. */
8882 (GET_MODE_PRECISION (<MODE>mode)
8883 == INTVAL (operands[3]))
8884 /* Otherwise, require CCZmode if we'd use a mask
8885 with the most significant bit set and can't
8886 widen it to wider mode. *testdi_1 also
8887 requires CCZmode if the mask has bit
8888 31 set and all bits above it clear. */
8889 || (INTVAL (operands[3]) + INTVAL (operands[4])
8890 >= 32)
8891 /* We can't widen also if val is not a REG. */
8892 || (INTVAL (operands[3]) + INTVAL (operands[4])
8893 == GET_MODE_PRECISION (GET_MODE (operands[2]))
8894 && !register_operand (operands[2],
8895 GET_MODE (operands[2])))
8896 /* And we shouldn't widen if
8897 TARGET_PARTIAL_REG_STALL. */
8898 || (TARGET_PARTIAL_REG_STALL
8899 && (INTVAL (operands[3]) + INTVAL (operands[4])
8900 >= (paradoxical_subreg_p (operands[2])
8901 && (GET_MODE_CLASS
8902 (GET_MODE (SUBREG_REG (operands[2])))
8903 == MODE_INT)
8904 ? GET_MODE_PRECISION
8905 (GET_MODE (SUBREG_REG (operands[2])))
8906 : GET_MODE_PRECISION
8907 (GET_MODE (operands[2])))))
8908 ? CCZmode : CCNOmode)"
8909 "#"
8910 "&& 1"
8911 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8912 {
8913 rtx val = operands[2];
8914 HOST_WIDE_INT len = INTVAL (operands[3]);
8915 HOST_WIDE_INT pos = INTVAL (operands[4]);
8916 machine_mode mode = GET_MODE (val);
8917
8918 if (SUBREG_P (val))
8919 {
8920 machine_mode submode = GET_MODE (SUBREG_REG (val));
8921
8922 /* Narrow paradoxical subregs to prevent partial register stalls. */
8923 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8924 && GET_MODE_CLASS (submode) == MODE_INT
8925 && (GET_MODE (operands[0]) == CCZmode
8926 || pos + len < GET_MODE_PRECISION (submode)
8927 || REG_P (SUBREG_REG (val))))
8928 {
8929 val = SUBREG_REG (val);
8930 mode = submode;
8931 }
8932 }
8933
8934 /* Small HImode tests can be converted to QImode. */
8935 if (pos + len <= 8
8936 && register_operand (val, HImode))
8937 {
8938 rtx nval = gen_lowpart (QImode, val);
8939 if (!MEM_P (nval)
8940 || GET_MODE (operands[0]) == CCZmode
8941 || pos + len < 8)
8942 {
8943 val = nval;
8944 mode = QImode;
8945 }
8946 }
8947
8948 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8949
8950 /* If the mask is going to have the sign bit set in the mode
8951 we want to do the comparison in and user isn't interested just
8952 in the zero flag, then we must widen the target mode. */
8953 if (pos + len == GET_MODE_PRECISION (mode)
8954 && GET_MODE (operands[0]) != CCZmode)
8955 {
8956 gcc_assert (pos + len < 32 && !MEM_P (val));
8957 mode = SImode;
8958 val = gen_lowpart (mode, val);
8959 }
8960
8961 wide_int mask
8962 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8963
8964 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8965 })
8966
8967 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8968 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8969 ;; this is relatively important trick.
8970 ;; Do the conversion only post-reload to avoid limiting of the register class
8971 ;; to QI regs.
8972 (define_split
8973 [(set (match_operand 0 "flags_reg_operand")
8974 (match_operator 1 "compare_operator"
8975 [(and (match_operand 2 "QIreg_operand")
8976 (match_operand 3 "const_int_operand"))
8977 (const_int 0)]))]
8978 "reload_completed
8979 && GET_MODE (operands[2]) != QImode
8980 && ((ix86_match_ccmode (insn, CCZmode)
8981 && !(INTVAL (operands[3]) & ~(255 << 8)))
8982 || (ix86_match_ccmode (insn, CCNOmode)
8983 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8984 [(set (match_dup 0)
8985 (match_op_dup 1
8986 [(and:QI
8987 (subreg:QI
8988 (zero_extract:SI (match_dup 2)
8989 (const_int 8)
8990 (const_int 8)) 0)
8991 (match_dup 3))
8992 (const_int 0)]))]
8993 {
8994 operands[2] = gen_lowpart (SImode, operands[2]);
8995 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8996 })
8997
8998 (define_split
8999 [(set (match_operand 0 "flags_reg_operand")
9000 (match_operator 1 "compare_operator"
9001 [(and (match_operand 2 "nonimmediate_operand")
9002 (match_operand 3 "const_int_operand"))
9003 (const_int 0)]))]
9004 "reload_completed
9005 && GET_MODE (operands[2]) != QImode
9006 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9007 && ((ix86_match_ccmode (insn, CCZmode)
9008 && !(INTVAL (operands[3]) & ~255))
9009 || (ix86_match_ccmode (insn, CCNOmode)
9010 && !(INTVAL (operands[3]) & ~127)))"
9011 [(set (match_dup 0)
9012 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9013 (const_int 0)]))]
9014 {
9015 operands[2] = gen_lowpart (QImode, operands[2]);
9016 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
9017 })
9018
9019 ;; %%% This used to optimize known byte-wide and operations to memory,
9020 ;; and sometimes to QImode registers. If this is considered useful,
9021 ;; it should be done with splitters.
9022
9023 (define_expand "and<mode>3"
9024 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9025 (and:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
9026 (match_operand:SWIM1248s 2 "<general_szext_operand>")))]
9027 ""
9028 {
9029 machine_mode mode = <MODE>mode;
9030
9031 if (<MODE>mode == DImode && !TARGET_64BIT)
9032 ;
9033 else if (const_int_operand (operands[2], <MODE>mode)
9034 && register_operand (operands[0], <MODE>mode)
9035 && !(TARGET_ZERO_EXTEND_WITH_AND
9036 && optimize_function_for_speed_p (cfun)))
9037 {
9038 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
9039
9040 if (ival == GET_MODE_MASK (SImode))
9041 mode = SImode;
9042 else if (ival == GET_MODE_MASK (HImode))
9043 mode = HImode;
9044 else if (ival == GET_MODE_MASK (QImode))
9045 mode = QImode;
9046 }
9047
9048 if (mode != <MODE>mode)
9049 emit_insn (gen_extend_insn
9050 (operands[0], gen_lowpart (mode, operands[1]),
9051 <MODE>mode, mode, 1));
9052 else
9053 ix86_expand_binary_operator (AND, <MODE>mode, operands);
9054
9055 DONE;
9056 })
9057
9058 (define_insn_and_split "*anddi3_doubleword"
9059 [(set (match_operand:DI 0 "nonimmediate_operand")
9060 (and:DI
9061 (match_operand:DI 1 "nonimmediate_operand")
9062 (match_operand:DI 2 "x86_64_szext_general_operand")))
9063 (clobber (reg:CC FLAGS_REG))]
9064 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9065 && ix86_binary_operator_ok (AND, DImode, operands)
9066 && ix86_pre_reload_split ()"
9067 "#"
9068 "&& 1"
9069 [(const_int 0)]
9070 {
9071 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9072
9073 if (operands[2] == const0_rtx)
9074 emit_move_insn (operands[0], const0_rtx);
9075 else if (operands[2] == constm1_rtx)
9076 emit_move_insn (operands[0], operands[1]);
9077 else
9078 emit_insn (gen_andsi3 (operands[0], operands[1], operands[2]));
9079
9080 if (operands[5] == const0_rtx)
9081 emit_move_insn (operands[3], const0_rtx);
9082 else if (operands[5] == constm1_rtx)
9083 emit_move_insn (operands[3], operands[4]);
9084 else
9085 emit_insn (gen_andsi3 (operands[3], operands[4], operands[5]));
9086
9087 DONE;
9088 })
9089
9090 (define_insn "*anddi_1"
9091 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,k")
9092 (and:DI
9093 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
9094 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9097 "@
9098 and{l}\t{%k2, %k0|%k0, %k2}
9099 and{q}\t{%2, %0|%0, %2}
9100 and{q}\t{%2, %0|%0, %2}
9101 #
9102 #"
9103 [(set_attr "isa" "x64,x64,x64,x64,avx512bw")
9104 (set_attr "type" "alu,alu,alu,imovx,msklog")
9105 (set_attr "length_immediate" "*,*,*,0,*")
9106 (set (attr "prefix_rex")
9107 (if_then_else
9108 (and (eq_attr "type" "imovx")
9109 (and (match_test "INTVAL (operands[2]) == 0xff")
9110 (match_operand 1 "ext_QIreg_operand")))
9111 (const_string "1")
9112 (const_string "*")))
9113 (set_attr "mode" "SI,DI,DI,SI,DI")])
9114
9115 (define_insn_and_split "*anddi_1_btr"
9116 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9117 (and:DI
9118 (match_operand:DI 1 "nonimmediate_operand" "%0")
9119 (match_operand:DI 2 "const_int_operand" "n")))
9120 (clobber (reg:CC FLAGS_REG))]
9121 "TARGET_64BIT && TARGET_USE_BT
9122 && ix86_binary_operator_ok (AND, DImode, operands)
9123 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
9124 "#"
9125 "&& reload_completed"
9126 [(parallel [(set (zero_extract:DI (match_dup 0)
9127 (const_int 1)
9128 (match_dup 3))
9129 (const_int 0))
9130 (clobber (reg:CC FLAGS_REG))])]
9131 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
9132 [(set_attr "type" "alu1")
9133 (set_attr "prefix_0f" "1")
9134 (set_attr "znver1_decode" "double")
9135 (set_attr "mode" "DI")])
9136
9137 ;; Turn *anddi_1 into *andsi_1_zext if possible.
9138 (define_split
9139 [(set (match_operand:DI 0 "register_operand")
9140 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
9141 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
9142 (clobber (reg:CC FLAGS_REG))]
9143 "TARGET_64BIT"
9144 [(parallel [(set (match_dup 0)
9145 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
9146 (clobber (reg:CC FLAGS_REG))])]
9147 {
9148 if (GET_CODE (operands[2]) == SYMBOL_REF
9149 || GET_CODE (operands[2]) == LABEL_REF)
9150 {
9151 operands[2] = shallow_copy_rtx (operands[2]);
9152 PUT_MODE (operands[2], SImode);
9153 }
9154 else if (GET_CODE (operands[2]) == CONST)
9155 {
9156 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
9157 operands[2] = copy_rtx (operands[2]);
9158 PUT_MODE (operands[2], SImode);
9159 PUT_MODE (XEXP (operands[2], 0), SImode);
9160 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
9161 }
9162 else
9163 operands[2] = gen_lowpart (SImode, operands[2]);
9164 })
9165
9166 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9167 (define_insn "*andsi_1_zext"
9168 [(set (match_operand:DI 0 "register_operand" "=r")
9169 (zero_extend:DI
9170 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9171 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9172 (clobber (reg:CC FLAGS_REG))]
9173 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9174 "and{l}\t{%2, %k0|%k0, %2}"
9175 [(set_attr "type" "alu")
9176 (set_attr "mode" "SI")])
9177
9178 (define_insn "*and<mode>_1"
9179 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,k")
9180 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
9181 (match_operand:SWI24 2 "<general_operand>" "r<i>,m,L,k")))
9182 (clobber (reg:CC FLAGS_REG))]
9183 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9184 "@
9185 and{<imodesuffix>}\t{%2, %0|%0, %2}
9186 and{<imodesuffix>}\t{%2, %0|%0, %2}
9187 #
9188 #"
9189 [(set (attr "isa")
9190 (cond [(eq_attr "alternative" "3")
9191 (if_then_else (eq_attr "mode" "SI")
9192 (const_string "avx512bw")
9193 (const_string "avx512f"))
9194 ]
9195 (const_string "*")))
9196 (set_attr "type" "alu,alu,imovx,msklog")
9197 (set_attr "length_immediate" "*,*,0,*")
9198 (set (attr "prefix_rex")
9199 (if_then_else
9200 (and (eq_attr "type" "imovx")
9201 (and (match_test "INTVAL (operands[2]) == 0xff")
9202 (match_operand 1 "ext_QIreg_operand")))
9203 (const_string "1")
9204 (const_string "*")))
9205 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
9206
9207 (define_insn "*andqi_1"
9208 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,k")
9209 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
9210 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
9211 (clobber (reg:CC FLAGS_REG))]
9212 "ix86_binary_operator_ok (AND, QImode, operands)"
9213 "@
9214 and{b}\t{%2, %0|%0, %2}
9215 and{b}\t{%2, %0|%0, %2}
9216 and{l}\t{%k2, %k0|%k0, %k2}
9217 #"
9218 [(set_attr "type" "alu,alu,alu,msklog")
9219 (set (attr "mode")
9220 (cond [(eq_attr "alternative" "2")
9221 (const_string "SI")
9222 (and (eq_attr "alternative" "3")
9223 (match_test "!TARGET_AVX512DQ"))
9224 (const_string "HI")
9225 ]
9226 (const_string "QI")))
9227 ;; Potential partial reg stall on alternative 2.
9228 (set (attr "preferred_for_speed")
9229 (cond [(eq_attr "alternative" "2")
9230 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9231 (symbol_ref "true")))])
9232
9233 (define_insn "*and<mode>_1_slp"
9234 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
9235 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
9236 (match_operand:SWI12 2 "general_operand" "<r>mn")))
9237 (clobber (reg:CC FLAGS_REG))]
9238 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9239 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9240 && (rtx_equal_p (operands[0], operands[1])
9241 || rtx_equal_p (operands[0], operands[2]))"
9242 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9243 [(set_attr "type" "alu")
9244 (set_attr "mode" "<MODE>")])
9245
9246 (define_split
9247 [(set (match_operand:SWI248 0 "register_operand")
9248 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9249 (match_operand:SWI248 2 "const_int_operand")))
9250 (clobber (reg:CC FLAGS_REG))]
9251 "reload_completed
9252 && (!REG_P (operands[1])
9253 || REGNO (operands[0]) != REGNO (operands[1]))"
9254 [(const_int 0)]
9255 {
9256 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
9257 machine_mode mode;
9258
9259 if (ival == GET_MODE_MASK (SImode))
9260 mode = SImode;
9261 else if (ival == GET_MODE_MASK (HImode))
9262 mode = HImode;
9263 else if (ival == GET_MODE_MASK (QImode))
9264 mode = QImode;
9265 else
9266 gcc_unreachable ();
9267
9268 /* Zero extend to SImode to avoid partial register stalls. */
9269 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
9270 operands[0] = gen_lowpart (SImode, operands[0]);
9271
9272 emit_insn (gen_extend_insn
9273 (operands[0], gen_lowpart (mode, operands[1]),
9274 GET_MODE (operands[0]), mode, 1));
9275 DONE;
9276 })
9277
9278 (define_split
9279 [(set (match_operand:SWI48 0 "register_operand")
9280 (and:SWI48 (match_dup 0)
9281 (const_int -65536)))
9282 (clobber (reg:CC FLAGS_REG))]
9283 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9284 || optimize_function_for_size_p (cfun)"
9285 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9286 "operands[1] = gen_lowpart (HImode, operands[0]);")
9287
9288 (define_split
9289 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9290 (and:SWI248 (match_dup 0)
9291 (const_int -256)))
9292 (clobber (reg:CC FLAGS_REG))]
9293 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9294 && reload_completed"
9295 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9296 "operands[1] = gen_lowpart (QImode, operands[0]);")
9297
9298 (define_split
9299 [(set (match_operand:SWI248 0 "QIreg_operand")
9300 (and:SWI248 (match_dup 0)
9301 (const_int -65281)))
9302 (clobber (reg:CC FLAGS_REG))]
9303 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9304 && reload_completed"
9305 [(parallel
9306 [(set (zero_extract:SI (match_dup 0)
9307 (const_int 8)
9308 (const_int 8))
9309 (subreg:SI
9310 (xor:QI
9311 (subreg:QI
9312 (zero_extract:SI (match_dup 0)
9313 (const_int 8)
9314 (const_int 8)) 0)
9315 (subreg:QI
9316 (zero_extract:SI (match_dup 0)
9317 (const_int 8)
9318 (const_int 8)) 0)) 0))
9319 (clobber (reg:CC FLAGS_REG))])]
9320 "operands[0] = gen_lowpart (SImode, operands[0]);")
9321
9322 (define_insn "*anddi_2"
9323 [(set (reg FLAGS_REG)
9324 (compare
9325 (and:DI
9326 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9327 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
9328 (const_int 0)))
9329 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9330 (and:DI (match_dup 1) (match_dup 2)))]
9331 "TARGET_64BIT
9332 && ix86_match_ccmode
9333 (insn,
9334 /* If we are going to emit andl instead of andq, and the operands[2]
9335 constant might have the SImode sign bit set, make sure the sign
9336 flag isn't tested, because the instruction will set the sign flag
9337 based on bit 31 rather than bit 63. If it isn't CONST_INT,
9338 conservatively assume it might have bit 31 set. */
9339 (satisfies_constraint_Z (operands[2])
9340 && (!CONST_INT_P (operands[2])
9341 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9342 ? CCZmode : CCNOmode)
9343 && ix86_binary_operator_ok (AND, DImode, operands)"
9344 "@
9345 and{l}\t{%k2, %k0|%k0, %k2}
9346 and{q}\t{%2, %0|%0, %2}
9347 and{q}\t{%2, %0|%0, %2}"
9348 [(set_attr "type" "alu")
9349 (set_attr "mode" "SI,DI,DI")])
9350
9351 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9352 (define_insn "*andsi_2_zext"
9353 [(set (reg FLAGS_REG)
9354 (compare (and:SI
9355 (match_operand:SI 1 "nonimmediate_operand" "%0")
9356 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9357 (const_int 0)))
9358 (set (match_operand:DI 0 "register_operand" "=r")
9359 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9360 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9361 && ix86_binary_operator_ok (AND, SImode, operands)"
9362 "and{l}\t{%2, %k0|%k0, %2}"
9363 [(set_attr "type" "alu")
9364 (set_attr "mode" "SI")])
9365
9366 (define_insn "*andqi_2_maybe_si"
9367 [(set (reg FLAGS_REG)
9368 (compare (and:QI
9369 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9370 (match_operand:QI 2 "general_operand" "qn,m,n"))
9371 (const_int 0)))
9372 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9373 (and:QI (match_dup 1) (match_dup 2)))]
9374 "ix86_binary_operator_ok (AND, QImode, operands)
9375 && ix86_match_ccmode (insn,
9376 CONST_INT_P (operands[2])
9377 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9378 {
9379 if (which_alternative == 2)
9380 {
9381 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9382 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9383 return "and{l}\t{%2, %k0|%k0, %2}";
9384 }
9385 return "and{b}\t{%2, %0|%0, %2}";
9386 }
9387 [(set_attr "type" "alu")
9388 (set_attr "mode" "QI,QI,SI")
9389 ;; Potential partial reg stall on alternative 2.
9390 (set (attr "preferred_for_speed")
9391 (cond [(eq_attr "alternative" "2")
9392 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9393 (symbol_ref "true")))])
9394
9395 (define_insn "*and<mode>_2"
9396 [(set (reg FLAGS_REG)
9397 (compare (and:SWI124
9398 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9399 (match_operand:SWI124 2 "<general_operand>" "<r><i>,m"))
9400 (const_int 0)))
9401 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
9402 (and:SWI124 (match_dup 1) (match_dup 2)))]
9403 "ix86_match_ccmode (insn, CCNOmode)
9404 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9405 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9406 [(set_attr "type" "alu")
9407 (set_attr "mode" "<MODE>")])
9408
9409 (define_expand "andqi_ext_1"
9410 [(parallel
9411 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
9412 (const_int 8)
9413 (const_int 8))
9414 (subreg:HI
9415 (and:QI
9416 (subreg:QI
9417 (zero_extract:HI (match_operand:HI 1 "register_operand")
9418 (const_int 8)
9419 (const_int 8)) 0)
9420 (match_operand:QI 2 "const_int_operand")) 0))
9421 (clobber (reg:CC FLAGS_REG))])])
9422
9423 (define_insn "*andqi_ext<mode>_1"
9424 [(set (zero_extract:SWI248
9425 (match_operand:SWI248 0 "register_operand" "+Q,Q")
9426 (const_int 8)
9427 (const_int 8))
9428 (subreg:SWI248
9429 (and:QI
9430 (subreg:QI
9431 (zero_extract:SWI248
9432 (match_operand:SWI248 1 "register_operand" "0,0")
9433 (const_int 8)
9434 (const_int 8)) 0)
9435 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9436 (clobber (reg:CC FLAGS_REG))]
9437 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9438 rtx_equal_p (operands[0], operands[1])"
9439 "and{b}\t{%2, %h0|%h0, %2}"
9440 [(set_attr "isa" "*,nox64")
9441 (set_attr "type" "alu")
9442 (set_attr "mode" "QI")])
9443
9444 ;; Generated by peephole translating test to and. This shows up
9445 ;; often in fp comparisons.
9446 (define_insn "*andqi_ext<mode>_1_cc"
9447 [(set (reg FLAGS_REG)
9448 (compare
9449 (and:QI
9450 (subreg:QI
9451 (zero_extract:SWI248
9452 (match_operand:SWI248 1 "register_operand" "0,0")
9453 (const_int 8)
9454 (const_int 8)) 0)
9455 (match_operand:QI 2 "general_operand" "QnBc,m"))
9456 (const_int 0)))
9457 (set (zero_extract:SWI248
9458 (match_operand:SWI248 0 "register_operand" "+Q,Q")
9459 (const_int 8)
9460 (const_int 8))
9461 (subreg:SWI248
9462 (and:QI
9463 (subreg:QI
9464 (zero_extract:SWI248
9465 (match_dup 1)
9466 (const_int 8)
9467 (const_int 8)) 0)
9468 (match_dup 2)) 0))]
9469 "ix86_match_ccmode (insn, CCNOmode)
9470 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9471 && rtx_equal_p (operands[0], operands[1])"
9472 "and{b}\t{%2, %h0|%h0, %2}"
9473 [(set_attr "isa" "*,nox64")
9474 (set_attr "type" "alu")
9475 (set_attr "mode" "QI")])
9476
9477 (define_insn "*andqi_ext<mode>_2"
9478 [(set (zero_extract:SWI248
9479 (match_operand:SWI248 0 "register_operand" "+Q")
9480 (const_int 8)
9481 (const_int 8))
9482 (subreg:SWI248
9483 (and:QI
9484 (subreg:QI
9485 (zero_extract:SWI248
9486 (match_operand:SWI248 1 "register_operand" "%0")
9487 (const_int 8)
9488 (const_int 8)) 0)
9489 (subreg:QI
9490 (zero_extract:SWI248
9491 (match_operand:SWI248 2 "register_operand" "Q")
9492 (const_int 8)
9493 (const_int 8)) 0)) 0))
9494 (clobber (reg:CC FLAGS_REG))]
9495 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9496 rtx_equal_p (operands[0], operands[1])
9497 || rtx_equal_p (operands[0], operands[2])"
9498 "and{b}\t{%h2, %h0|%h0, %h2}"
9499 [(set_attr "type" "alu")
9500 (set_attr "mode" "QI")])
9501
9502 ;; Convert wide AND instructions with immediate operand to shorter QImode
9503 ;; equivalents when possible.
9504 ;; Don't do the splitting with memory operands, since it introduces risk
9505 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9506 ;; for size, but that can (should?) be handled by generic code instead.
9507 (define_split
9508 [(set (match_operand:SWI248 0 "QIreg_operand")
9509 (and:SWI248 (match_operand:SWI248 1 "register_operand")
9510 (match_operand:SWI248 2 "const_int_operand")))
9511 (clobber (reg:CC FLAGS_REG))]
9512 "reload_completed
9513 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9514 && !(~INTVAL (operands[2]) & ~(255 << 8))"
9515 [(parallel
9516 [(set (zero_extract:SI (match_dup 0)
9517 (const_int 8)
9518 (const_int 8))
9519 (subreg:SI
9520 (and:QI
9521 (subreg:QI
9522 (zero_extract:SI (match_dup 1)
9523 (const_int 8)
9524 (const_int 8)) 0)
9525 (match_dup 2)) 0))
9526 (clobber (reg:CC FLAGS_REG))])]
9527 {
9528 operands[0] = gen_lowpart (SImode, operands[0]);
9529 operands[1] = gen_lowpart (SImode, operands[1]);
9530 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9531 })
9532
9533 ;; Since AND can be encoded with sign extended immediate, this is only
9534 ;; profitable when 7th bit is not set.
9535 (define_split
9536 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9537 (and:SWI248 (match_operand:SWI248 1 "general_operand")
9538 (match_operand:SWI248 2 "const_int_operand")))
9539 (clobber (reg:CC FLAGS_REG))]
9540 "reload_completed
9541 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9542 && !(~INTVAL (operands[2]) & ~255)
9543 && !(INTVAL (operands[2]) & 128)"
9544 [(parallel [(set (strict_low_part (match_dup 0))
9545 (and:QI (match_dup 1)
9546 (match_dup 2)))
9547 (clobber (reg:CC FLAGS_REG))])]
9548 {
9549 operands[0] = gen_lowpart (QImode, operands[0]);
9550 operands[1] = gen_lowpart (QImode, operands[1]);
9551 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9552 })
9553
9554 (define_insn "*andndi3_doubleword"
9555 [(set (match_operand:DI 0 "register_operand")
9556 (and:DI
9557 (not:DI (match_operand:DI 1 "register_operand"))
9558 (match_operand:DI 2 "nonimmediate_operand")))
9559 (clobber (reg:CC FLAGS_REG))]
9560 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9561 && ix86_pre_reload_split ()"
9562 "#")
9563
9564 (define_split
9565 [(set (match_operand:DI 0 "register_operand")
9566 (and:DI
9567 (not:DI (match_operand:DI 1 "register_operand"))
9568 (match_operand:DI 2 "nonimmediate_operand")))
9569 (clobber (reg:CC FLAGS_REG))]
9570 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9571 && can_create_pseudo_p ()"
9572 [(parallel [(set (match_dup 0)
9573 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9574 (clobber (reg:CC FLAGS_REG))])
9575 (parallel [(set (match_dup 3)
9576 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9577 (clobber (reg:CC FLAGS_REG))])]
9578 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9579
9580 (define_split
9581 [(set (match_operand:DI 0 "register_operand")
9582 (and:DI
9583 (not:DI (match_operand:DI 1 "register_operand"))
9584 (match_operand:DI 2 "nonimmediate_operand")))
9585 (clobber (reg:CC FLAGS_REG))]
9586 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9587 && can_create_pseudo_p ()"
9588 [(set (match_dup 6) (not:SI (match_dup 1)))
9589 (parallel [(set (match_dup 0)
9590 (and:SI (match_dup 6) (match_dup 2)))
9591 (clobber (reg:CC FLAGS_REG))])
9592 (set (match_dup 7) (not:SI (match_dup 4)))
9593 (parallel [(set (match_dup 3)
9594 (and:SI (match_dup 7) (match_dup 5)))
9595 (clobber (reg:CC FLAGS_REG))])]
9596 {
9597 operands[6] = gen_reg_rtx (SImode);
9598 operands[7] = gen_reg_rtx (SImode);
9599
9600 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9601 })
9602
9603 (define_insn "*andn<mode>_1"
9604 [(set (match_operand:SWI48 0 "register_operand" "=r,r,k")
9605 (and:SWI48
9606 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
9607 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
9608 (clobber (reg:CC FLAGS_REG))]
9609 "TARGET_BMI || TARGET_AVX512BW"
9610 "@
9611 andn\t{%2, %1, %0|%0, %1, %2}
9612 andn\t{%2, %1, %0|%0, %1, %2}
9613 #"
9614 [(set_attr "isa" "bmi,bmi,avx512bw")
9615 (set_attr "type" "bitmanip,bitmanip,msklog")
9616 (set_attr "btver2_decode" "direct, double,*")
9617 (set_attr "mode" "<MODE>")])
9618
9619 (define_insn "*andn<mode>_1"
9620 [(set (match_operand:SWI12 0 "register_operand" "=r,k")
9621 (and:SWI12
9622 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
9623 (match_operand:SWI12 2 "register_operand" "r,k")))
9624 (clobber (reg:CC FLAGS_REG))]
9625 "TARGET_BMI || TARGET_AVX512BW"
9626 "@
9627 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
9628 #"
9629 [(set_attr "isa" "bmi,avx512f")
9630 (set_attr "type" "bitmanip,msklog")
9631 (set_attr "btver2_decode" "direct,*")
9632 (set (attr "mode")
9633 (cond [(eq_attr "alternative" "0")
9634 (const_string "SI")
9635 (and (eq_attr "alternative" "1")
9636 (match_test "!TARGET_AVX512DQ"))
9637 (const_string "HI")
9638 ]
9639 (const_string "<MODE>")))])
9640
9641 (define_insn "*andn_<mode>_ccno"
9642 [(set (reg FLAGS_REG)
9643 (compare
9644 (and:SWI48
9645 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9646 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9647 (const_int 0)))
9648 (clobber (match_scratch:SWI48 0 "=r,r"))]
9649 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9650 "andn\t{%2, %1, %0|%0, %1, %2}"
9651 [(set_attr "type" "bitmanip")
9652 (set_attr "btver2_decode" "direct, double")
9653 (set_attr "mode" "<MODE>")])
9654 \f
9655 ;; Logical inclusive and exclusive OR instructions
9656
9657 ;; %%% This used to optimize known byte-wide and operations to memory.
9658 ;; If this is considered useful, it should be done with splitters.
9659
9660 (define_expand "<code><mode>3"
9661 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9662 (any_or:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
9663 (match_operand:SWIM1248s 2 "<general_operand>")))]
9664 ""
9665 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9666
9667 (define_insn_and_split "*<code>di3_doubleword"
9668 [(set (match_operand:DI 0 "nonimmediate_operand")
9669 (any_or:DI
9670 (match_operand:DI 1 "nonimmediate_operand")
9671 (match_operand:DI 2 "x86_64_szext_general_operand")))
9672 (clobber (reg:CC FLAGS_REG))]
9673 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9674 && ix86_binary_operator_ok (<CODE>, DImode, operands)
9675 && ix86_pre_reload_split ()"
9676 "#"
9677 "&& 1"
9678 [(const_int 0)]
9679 {
9680 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9681
9682 if (operands[2] == const0_rtx)
9683 emit_move_insn (operands[0], operands[1]);
9684 else if (operands[2] == constm1_rtx)
9685 {
9686 if (<CODE> == IOR)
9687 emit_move_insn (operands[0], constm1_rtx);
9688 else
9689 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9690 }
9691 else
9692 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9693
9694 if (operands[5] == const0_rtx)
9695 emit_move_insn (operands[3], operands[4]);
9696 else if (operands[5] == constm1_rtx)
9697 {
9698 if (<CODE> == IOR)
9699 emit_move_insn (operands[3], constm1_rtx);
9700 else
9701 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9702 }
9703 else
9704 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9705
9706 DONE;
9707 })
9708
9709 (define_insn "*<code><mode>_1"
9710 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,k")
9711 (any_or:SWI248
9712 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
9713 (match_operand:SWI248 2 "<general_operand>" "r<i>,m,k")))
9714 (clobber (reg:CC FLAGS_REG))]
9715 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9716 "@
9717 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
9718 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
9719 #"
9720 [(set (attr "isa")
9721 (cond [(eq_attr "alternative" "2")
9722 (if_then_else (eq_attr "mode" "SI,DI")
9723 (const_string "avx512bw")
9724 (const_string "avx512f"))
9725 ]
9726 (const_string "*")))
9727 (set_attr "type" "alu, alu, msklog")
9728 (set_attr "mode" "<MODE>")])
9729
9730 (define_insn_and_split "*iordi_1_bts"
9731 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9732 (ior:DI
9733 (match_operand:DI 1 "nonimmediate_operand" "%0")
9734 (match_operand:DI 2 "const_int_operand" "n")))
9735 (clobber (reg:CC FLAGS_REG))]
9736 "TARGET_64BIT && TARGET_USE_BT
9737 && ix86_binary_operator_ok (IOR, DImode, operands)
9738 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9739 "#"
9740 "&& reload_completed"
9741 [(parallel [(set (zero_extract:DI (match_dup 0)
9742 (const_int 1)
9743 (match_dup 3))
9744 (const_int 1))
9745 (clobber (reg:CC FLAGS_REG))])]
9746 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9747 [(set_attr "type" "alu1")
9748 (set_attr "prefix_0f" "1")
9749 (set_attr "znver1_decode" "double")
9750 (set_attr "mode" "DI")])
9751
9752 (define_insn_and_split "*xordi_1_btc"
9753 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9754 (xor:DI
9755 (match_operand:DI 1 "nonimmediate_operand" "%0")
9756 (match_operand:DI 2 "const_int_operand" "n")))
9757 (clobber (reg:CC FLAGS_REG))]
9758 "TARGET_64BIT && TARGET_USE_BT
9759 && ix86_binary_operator_ok (XOR, DImode, operands)
9760 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9761 "#"
9762 "&& reload_completed"
9763 [(parallel [(set (zero_extract:DI (match_dup 0)
9764 (const_int 1)
9765 (match_dup 3))
9766 (not:DI (zero_extract:DI (match_dup 0)
9767 (const_int 1)
9768 (match_dup 3))))
9769 (clobber (reg:CC FLAGS_REG))])]
9770 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9771 [(set_attr "type" "alu1")
9772 (set_attr "prefix_0f" "1")
9773 (set_attr "znver1_decode" "double")
9774 (set_attr "mode" "DI")])
9775
9776 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9777 (define_insn "*<code>si_1_zext"
9778 [(set (match_operand:DI 0 "register_operand" "=r")
9779 (zero_extend:DI
9780 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9781 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9782 (clobber (reg:CC FLAGS_REG))]
9783 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9784 "<logic>{l}\t{%2, %k0|%k0, %2}"
9785 [(set_attr "type" "alu")
9786 (set_attr "mode" "SI")])
9787
9788 (define_insn "*<code>si_1_zext_imm"
9789 [(set (match_operand:DI 0 "register_operand" "=r")
9790 (any_or:DI
9791 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9792 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9793 (clobber (reg:CC FLAGS_REG))]
9794 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9795 "<logic>{l}\t{%2, %k0|%k0, %2}"
9796 [(set_attr "type" "alu")
9797 (set_attr "mode" "SI")])
9798
9799 (define_insn "*<code>qi_1"
9800 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,k")
9801 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
9802 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
9803 (clobber (reg:CC FLAGS_REG))]
9804 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9805 "@
9806 <logic>{b}\t{%2, %0|%0, %2}
9807 <logic>{b}\t{%2, %0|%0, %2}
9808 <logic>{l}\t{%k2, %k0|%k0, %k2}
9809 #"
9810 [(set_attr "isa" "*,*,*,avx512f")
9811 (set_attr "type" "alu,alu,alu,msklog")
9812 (set (attr "mode")
9813 (cond [(eq_attr "alternative" "2")
9814 (const_string "SI")
9815 (and (eq_attr "alternative" "3")
9816 (match_test "!TARGET_AVX512DQ"))
9817 (const_string "HI")
9818 ]
9819 (const_string "QI")))
9820 ;; Potential partial reg stall on alternative 2.
9821 (set (attr "preferred_for_speed")
9822 (cond [(eq_attr "alternative" "2")
9823 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9824 (symbol_ref "true")))])
9825
9826 (define_insn "*<code><mode>_1_slp"
9827 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
9828 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
9829 (match_operand:SWI12 2 "general_operand" "<r>mn")))
9830 (clobber (reg:CC FLAGS_REG))]
9831 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9832 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9833 && (rtx_equal_p (operands[0], operands[1])
9834 || rtx_equal_p (operands[0], operands[2]))"
9835 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9836 [(set_attr "type" "alu")
9837 (set_attr "mode" "<MODE>")])
9838
9839 (define_insn "*<code><mode>_2"
9840 [(set (reg FLAGS_REG)
9841 (compare (any_or:SWI
9842 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9843 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
9844 (const_int 0)))
9845 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9846 (any_or:SWI (match_dup 1) (match_dup 2)))]
9847 "ix86_match_ccmode (insn, CCNOmode)
9848 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9849 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9850 [(set_attr "type" "alu")
9851 (set_attr "mode" "<MODE>")])
9852
9853 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9854 ;; ??? Special case for immediate operand is missing - it is tricky.
9855 (define_insn "*<code>si_2_zext"
9856 [(set (reg FLAGS_REG)
9857 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9858 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9859 (const_int 0)))
9860 (set (match_operand:DI 0 "register_operand" "=r")
9861 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9862 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9863 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9864 "<logic>{l}\t{%2, %k0|%k0, %2}"
9865 [(set_attr "type" "alu")
9866 (set_attr "mode" "SI")])
9867
9868 (define_insn "*<code>si_2_zext_imm"
9869 [(set (reg FLAGS_REG)
9870 (compare (any_or:SI
9871 (match_operand:SI 1 "nonimmediate_operand" "%0")
9872 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9873 (const_int 0)))
9874 (set (match_operand:DI 0 "register_operand" "=r")
9875 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9876 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9877 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9878 "<logic>{l}\t{%2, %k0|%k0, %2}"
9879 [(set_attr "type" "alu")
9880 (set_attr "mode" "SI")])
9881
9882 (define_insn "*<code><mode>_3"
9883 [(set (reg FLAGS_REG)
9884 (compare (any_or:SWI
9885 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9886 (match_operand:SWI 2 "<general_operand>" "<g>"))
9887 (const_int 0)))
9888 (clobber (match_scratch:SWI 0 "=<r>"))]
9889 "ix86_match_ccmode (insn, CCNOmode)
9890 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9891 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9892 [(set_attr "type" "alu")
9893 (set_attr "mode" "<MODE>")])
9894
9895 (define_insn "*<code>qi_ext<mode>_1"
9896 [(set (zero_extract:SWI248
9897 (match_operand:SWI248 0 "register_operand" "+Q,Q")
9898 (const_int 8)
9899 (const_int 8))
9900 (subreg:SWI248
9901 (any_or:QI
9902 (subreg:QI
9903 (zero_extract:SWI248
9904 (match_operand:SWI248 1 "register_operand" "0,0")
9905 (const_int 8)
9906 (const_int 8)) 0)
9907 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9908 (clobber (reg:CC FLAGS_REG))]
9909 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9910 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9911 && rtx_equal_p (operands[0], operands[1])"
9912 "<logic>{b}\t{%2, %h0|%h0, %2}"
9913 [(set_attr "isa" "*,nox64")
9914 (set_attr "type" "alu")
9915 (set_attr "mode" "QI")])
9916
9917 (define_insn "*<code>qi_ext<mode>_2"
9918 [(set (zero_extract:SWI248
9919 (match_operand:SWI248 0 "register_operand" "+Q")
9920 (const_int 8)
9921 (const_int 8))
9922 (subreg:SWI248
9923 (any_or:QI
9924 (subreg:QI
9925 (zero_extract:SWI248
9926 (match_operand:SWI248 1 "register_operand" "%0")
9927 (const_int 8)
9928 (const_int 8)) 0)
9929 (subreg:QI
9930 (zero_extract:SWI248
9931 (match_operand:SWI248 2 "register_operand" "Q")
9932 (const_int 8)
9933 (const_int 8)) 0)) 0))
9934 (clobber (reg:CC FLAGS_REG))]
9935 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9936 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9937 && (rtx_equal_p (operands[0], operands[1])
9938 || rtx_equal_p (operands[0], operands[2]))"
9939 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9940 [(set_attr "type" "alu")
9941 (set_attr "mode" "QI")])
9942
9943 ;; Convert wide OR instructions with immediate operand to shorter QImode
9944 ;; equivalents when possible.
9945 ;; Don't do the splitting with memory operands, since it introduces risk
9946 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9947 ;; for size, but that can (should?) be handled by generic code instead.
9948 (define_split
9949 [(set (match_operand:SWI248 0 "QIreg_operand")
9950 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9951 (match_operand:SWI248 2 "const_int_operand")))
9952 (clobber (reg:CC FLAGS_REG))]
9953 "reload_completed
9954 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9955 && !(INTVAL (operands[2]) & ~(255 << 8))"
9956 [(parallel
9957 [(set (zero_extract:SI (match_dup 0)
9958 (const_int 8)
9959 (const_int 8))
9960 (subreg:SI
9961 (any_or:QI
9962 (subreg:QI
9963 (zero_extract:SI (match_dup 1)
9964 (const_int 8)
9965 (const_int 8)) 0)
9966 (match_dup 2)) 0))
9967 (clobber (reg:CC FLAGS_REG))])]
9968 {
9969 operands[0] = gen_lowpart (SImode, operands[0]);
9970 operands[1] = gen_lowpart (SImode, operands[1]);
9971 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9972 })
9973
9974 ;; Since OR can be encoded with sign extended immediate, this is only
9975 ;; profitable when 7th bit is set.
9976 (define_split
9977 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9978 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9979 (match_operand:SWI248 2 "const_int_operand")))
9980 (clobber (reg:CC FLAGS_REG))]
9981 "reload_completed
9982 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9983 && !(INTVAL (operands[2]) & ~255)
9984 && (INTVAL (operands[2]) & 128)"
9985 [(parallel [(set (strict_low_part (match_dup 0))
9986 (any_or:QI (match_dup 1)
9987 (match_dup 2)))
9988 (clobber (reg:CC FLAGS_REG))])]
9989 {
9990 operands[0] = gen_lowpart (QImode, operands[0]);
9991 operands[1] = gen_lowpart (QImode, operands[1]);
9992 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9993 })
9994
9995 (define_expand "xorqi_ext_1_cc"
9996 [(parallel
9997 [(set (reg:CCNO FLAGS_REG)
9998 (compare:CCNO
9999 (xor:QI
10000 (subreg:QI
10001 (zero_extract:HI (match_operand:HI 1 "register_operand")
10002 (const_int 8)
10003 (const_int 8)) 0)
10004 (match_operand:QI 2 "const_int_operand"))
10005 (const_int 0)))
10006 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
10007 (const_int 8)
10008 (const_int 8))
10009 (subreg:HI
10010 (xor:QI
10011 (subreg:QI
10012 (zero_extract:HI (match_dup 1)
10013 (const_int 8)
10014 (const_int 8)) 0)
10015 (match_dup 2)) 0))])])
10016
10017 (define_insn "*xorqi_ext<mode>_1_cc"
10018 [(set (reg FLAGS_REG)
10019 (compare
10020 (xor:QI
10021 (subreg:QI
10022 (zero_extract:SWI248
10023 (match_operand:SWI248 1 "register_operand" "0,0")
10024 (const_int 8)
10025 (const_int 8)) 0)
10026 (match_operand:QI 2 "general_operand" "QnBc,m"))
10027 (const_int 0)))
10028 (set (zero_extract:SWI248
10029 (match_operand:SWI248 0 "register_operand" "+Q,Q")
10030 (const_int 8)
10031 (const_int 8))
10032 (subreg:SWI248
10033 (xor:QI
10034 (subreg:QI
10035 (zero_extract:SWI248
10036 (match_dup 1)
10037 (const_int 8)
10038 (const_int 8)) 0)
10039 (match_dup 2)) 0))]
10040 "ix86_match_ccmode (insn, CCNOmode)
10041 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
10042 && rtx_equal_p (operands[0], operands[1])"
10043 "xor{b}\t{%2, %h0|%h0, %2}"
10044 [(set_attr "isa" "*,nox64")
10045 (set_attr "type" "alu")
10046 (set_attr "mode" "QI")])
10047 \f
10048 ;; Negation instructions
10049
10050 (define_expand "neg<mode>2"
10051 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
10052 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
10053 ""
10054 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
10055
10056 (define_insn_and_split "*neg<dwi>2_doubleword"
10057 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
10058 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
10059 (clobber (reg:CC FLAGS_REG))]
10060 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
10061 "#"
10062 "reload_completed"
10063 [(parallel
10064 [(set (reg:CCC FLAGS_REG)
10065 (ne:CCC (match_dup 1) (const_int 0)))
10066 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
10067 (parallel
10068 [(set (match_dup 2)
10069 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
10070 (match_dup 3))
10071 (const_int 0)))
10072 (clobber (reg:CC FLAGS_REG))])
10073 (parallel
10074 [(set (match_dup 2)
10075 (neg:DWIH (match_dup 2)))
10076 (clobber (reg:CC FLAGS_REG))])]
10077 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
10078
10079 (define_insn "*neg<mode>_1"
10080 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10081 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
10082 (clobber (reg:CC FLAGS_REG))]
10083 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
10084 "neg{<imodesuffix>}\t%0"
10085 [(set_attr "type" "negnot")
10086 (set_attr "mode" "<MODE>")])
10087
10088 (define_insn "*negsi_1_zext"
10089 [(set (match_operand:DI 0 "register_operand" "=r")
10090 (zero_extend:DI
10091 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
10092 (clobber (reg:CC FLAGS_REG))]
10093 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10094 "neg{l}\t%k0"
10095 [(set_attr "type" "negnot")
10096 (set_attr "mode" "SI")])
10097
10098 (define_insn "*neg<mode>_2"
10099 [(set (reg FLAGS_REG)
10100 (compare
10101 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10102 (const_int 0)))
10103 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10104 (neg:SWI (match_dup 1)))]
10105 "ix86_match_ccmode (insn, CCGOCmode)
10106 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
10107 "neg{<imodesuffix>}\t%0"
10108 [(set_attr "type" "negnot")
10109 (set_attr "mode" "<MODE>")])
10110
10111 (define_insn "*negsi_2_zext"
10112 [(set (reg FLAGS_REG)
10113 (compare
10114 (neg:SI (match_operand:SI 1 "register_operand" "0"))
10115 (const_int 0)))
10116 (set (match_operand:DI 0 "register_operand" "=r")
10117 (zero_extend:DI
10118 (neg:SI (match_dup 1))))]
10119 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10120 && ix86_unary_operator_ok (NEG, SImode, operands)"
10121 "neg{l}\t%k0"
10122 [(set_attr "type" "negnot")
10123 (set_attr "mode" "SI")])
10124
10125 (define_insn "*neg<mode>_ccc_1"
10126 [(set (reg:CCC FLAGS_REG)
10127 (ne:CCC
10128 (match_operand:SWI 1 "nonimmediate_operand" "0")
10129 (const_int 0)))
10130 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10131 (neg:SWI (match_dup 1)))]
10132 ""
10133 "neg{<imodesuffix>}\t%0"
10134 [(set_attr "type" "negnot")
10135 (set_attr "mode" "<MODE>")])
10136
10137 (define_insn "*neg<mode>_ccc_2"
10138 [(set (reg:CCC FLAGS_REG)
10139 (ne:CCC
10140 (match_operand:SWI 1 "nonimmediate_operand" "0")
10141 (const_int 0)))
10142 (clobber (match_scratch:SWI 0 "=<r>"))]
10143 ""
10144 "neg{<imodesuffix>}\t%0"
10145 [(set_attr "type" "negnot")
10146 (set_attr "mode" "<MODE>")])
10147
10148 ;; Negate with jump on overflow.
10149 (define_expand "negv<mode>3"
10150 [(parallel [(set (reg:CCO FLAGS_REG)
10151 (ne:CCO (match_operand:SWI 1 "register_operand")
10152 (match_dup 3)))
10153 (set (match_operand:SWI 0 "register_operand")
10154 (neg:SWI (match_dup 1)))])
10155 (set (pc) (if_then_else
10156 (eq (reg:CCO FLAGS_REG) (const_int 0))
10157 (label_ref (match_operand 2))
10158 (pc)))]
10159 ""
10160 {
10161 operands[3]
10162 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
10163 <MODE>mode);
10164 })
10165
10166 (define_insn "*negv<mode>3"
10167 [(set (reg:CCO FLAGS_REG)
10168 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
10169 (match_operand:SWI 2 "const_int_operand")))
10170 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10171 (neg:SWI (match_dup 1)))]
10172 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
10173 && mode_signbit_p (<MODE>mode, operands[2])"
10174 "neg{<imodesuffix>}\t%0"
10175 [(set_attr "type" "negnot")
10176 (set_attr "mode" "<MODE>")])
10177
10178 ;; Special expand pattern to handle integer mode abs
10179
10180 (define_expand "abs<mode>2"
10181 [(parallel
10182 [(set (match_operand:SDWIM 0 "register_operand")
10183 (abs:SDWIM
10184 (match_operand:SDWIM 1 "general_operand")))
10185 (clobber (reg:CC FLAGS_REG))])]
10186 "TARGET_CMOVE
10187 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
10188 {
10189 if (TARGET_EXPAND_ABS)
10190 {
10191 machine_mode mode = <MODE>mode;
10192 operands[1] = force_reg (mode, operands[1]);
10193
10194 /* Generate rtx abs using:
10195 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
10196
10197 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
10198 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
10199 shift_amount, NULL_RTX,
10200 0, OPTAB_DIRECT);
10201 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
10202 operands[0], 0, OPTAB_DIRECT);
10203 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
10204 operands[0], 0, OPTAB_DIRECT);
10205 if (!rtx_equal_p (minus_dst, operands[0]))
10206 emit_move_insn (operands[0], minus_dst);
10207 DONE;
10208 }
10209 })
10210
10211 (define_insn_and_split "*abs<dwi>2_doubleword"
10212 [(set (match_operand:<DWI> 0 "register_operand")
10213 (abs:<DWI>
10214 (match_operand:<DWI> 1 "general_operand")))
10215 (clobber (reg:CC FLAGS_REG))]
10216 "TARGET_CMOVE
10217 && ix86_pre_reload_split ()"
10218 "#"
10219 "&& 1"
10220 [(parallel
10221 [(set (reg:CCC FLAGS_REG)
10222 (ne:CCC (match_dup 1) (const_int 0)))
10223 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
10224 (parallel
10225 [(set (match_dup 5)
10226 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
10227 (match_dup 4))
10228 (const_int 0)))
10229 (clobber (reg:CC FLAGS_REG))])
10230 (parallel
10231 [(set (reg:CCGOC FLAGS_REG)
10232 (compare:CCGOC
10233 (neg:DWIH (match_dup 5))
10234 (const_int 0)))
10235 (set (match_dup 5)
10236 (neg:DWIH (match_dup 5)))])
10237 (set (match_dup 0)
10238 (if_then_else:DWIH
10239 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
10240 (match_dup 2)
10241 (match_dup 1)))
10242 (set (match_dup 3)
10243 (if_then_else:DWIH
10244 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
10245 (match_dup 5)
10246 (match_dup 4)))]
10247 {
10248 operands[1] = force_reg (<DWI>mode, operands[1]);
10249 operands[2] = gen_reg_rtx (<DWI>mode);
10250
10251 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
10252 })
10253
10254 (define_insn_and_split "*abs<mode>2_1"
10255 [(set (match_operand:SWI 0 "register_operand")
10256 (abs:SWI
10257 (match_operand:SWI 1 "general_operand")))
10258 (clobber (reg:CC FLAGS_REG))]
10259 "TARGET_CMOVE
10260 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
10261 && ix86_pre_reload_split ()"
10262 "#"
10263 "&& 1"
10264 [(parallel
10265 [(set (reg:CCGOC FLAGS_REG)
10266 (compare:CCGOC
10267 (neg:SWI (match_dup 1))
10268 (const_int 0)))
10269 (set (match_dup 2)
10270 (neg:SWI (match_dup 1)))])
10271 (set (match_dup 0)
10272 (if_then_else:SWI
10273 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
10274 (match_dup 2)
10275 (match_dup 1)))]
10276 {
10277 operands[1] = force_reg (<MODE>mode, operands[1]);
10278 operands[2] = gen_reg_rtx (<MODE>mode);
10279 })
10280
10281 (define_expand "<code>tf2"
10282 [(set (match_operand:TF 0 "register_operand")
10283 (absneg:TF (match_operand:TF 1 "register_operand")))]
10284 "TARGET_SSE"
10285 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10286
10287 (define_insn_and_split "*<code>tf2_1"
10288 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
10289 (absneg:TF
10290 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
10291 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
10292 "TARGET_SSE"
10293 "#"
10294 "&& reload_completed"
10295 [(set (match_dup 0)
10296 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
10297 {
10298 if (TARGET_AVX)
10299 {
10300 if (MEM_P (operands[1]))
10301 std::swap (operands[1], operands[2]);
10302 }
10303 else
10304 {
10305 if (operands_match_p (operands[0], operands[2]))
10306 std::swap (operands[1], operands[2]);
10307 }
10308 }
10309 [(set_attr "isa" "noavx,noavx,avx,avx")])
10310
10311 (define_insn_and_split "*nabstf2_1"
10312 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
10313 (neg:TF
10314 (abs:TF
10315 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
10316 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
10317 "TARGET_SSE"
10318 "#"
10319 "&& reload_completed"
10320 [(set (match_dup 0)
10321 (ior:TF (match_dup 1) (match_dup 2)))]
10322 {
10323 if (TARGET_AVX)
10324 {
10325 if (MEM_P (operands[1]))
10326 std::swap (operands[1], operands[2]);
10327 }
10328 else
10329 {
10330 if (operands_match_p (operands[0], operands[2]))
10331 std::swap (operands[1], operands[2]);
10332 }
10333 }
10334 [(set_attr "isa" "noavx,noavx,avx,avx")])
10335
10336 (define_expand "<code><mode>2"
10337 [(set (match_operand:X87MODEF 0 "register_operand")
10338 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
10339 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10340 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10341
10342 ;; Changing of sign for FP values is doable using integer unit too.
10343 (define_insn "*<code><mode>2_i387_1"
10344 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10345 (absneg:X87MODEF
10346 (match_operand:X87MODEF 1 "register_operand" "0,0")))
10347 (clobber (reg:CC FLAGS_REG))]
10348 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10349 "#")
10350
10351 (define_split
10352 [(set (match_operand:X87MODEF 0 "fp_register_operand")
10353 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
10354 (clobber (reg:CC FLAGS_REG))]
10355 "TARGET_80387 && reload_completed"
10356 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
10357
10358 (define_split
10359 [(set (match_operand:X87MODEF 0 "general_reg_operand")
10360 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
10361 (clobber (reg:CC FLAGS_REG))]
10362 "TARGET_80387 && reload_completed"
10363 [(const_int 0)]
10364 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10365
10366 (define_insn "*<code><mode>2_1"
10367 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
10368 (absneg:MODEF
10369 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
10370 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
10371 (clobber (reg:CC FLAGS_REG))]
10372 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10373 "#"
10374 [(set_attr "isa" "noavx,noavx,avx,*,*")
10375 (set (attr "enabled")
10376 (if_then_else
10377 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
10378 (if_then_else
10379 (eq_attr "alternative" "3,4")
10380 (symbol_ref "TARGET_MIX_SSE_I387")
10381 (const_string "*"))
10382 (if_then_else
10383 (eq_attr "alternative" "3,4")
10384 (symbol_ref "true")
10385 (symbol_ref "false"))))])
10386
10387 (define_split
10388 [(set (match_operand:MODEF 0 "sse_reg_operand")
10389 (absneg:MODEF
10390 (match_operand:MODEF 1 "sse_reg_operand")))
10391 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
10392 (clobber (reg:CC FLAGS_REG))]
10393 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
10394 && reload_completed"
10395 [(set (match_dup 0)
10396 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
10397 {
10398 machine_mode mode = <MODE>mode;
10399 machine_mode vmode = <ssevecmodef>mode;
10400
10401 operands[0] = lowpart_subreg (vmode, operands[0], mode);
10402 operands[1] = lowpart_subreg (vmode, operands[1], mode);
10403
10404 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
10405 std::swap (operands[1], operands[2]);
10406 })
10407
10408 (define_split
10409 [(set (match_operand:MODEF 0 "fp_register_operand")
10410 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
10411 (use (match_operand 2))
10412 (clobber (reg:CC FLAGS_REG))]
10413 "TARGET_80387 && reload_completed"
10414 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
10415
10416 (define_split
10417 [(set (match_operand:MODEF 0 "general_reg_operand")
10418 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
10419 (use (match_operand 2))
10420 (clobber (reg:CC FLAGS_REG))]
10421 "TARGET_80387 && reload_completed"
10422 [(const_int 0)]
10423 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10424
10425 (define_insn_and_split "*nabs<mode>2_1"
10426 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
10427 (neg:MODEF
10428 (abs:MODEF
10429 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
10430 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
10431 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10432 "#"
10433 "&& reload_completed"
10434 [(set (match_dup 0)
10435 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
10436 {
10437 machine_mode mode = <MODE>mode;
10438 machine_mode vmode = <ssevecmodef>mode;
10439
10440 operands[0] = lowpart_subreg (vmode, operands[0], mode);
10441 operands[1] = lowpart_subreg (vmode, operands[1], mode);
10442
10443 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
10444 std::swap (operands[1], operands[2]);
10445 }
10446 [(set_attr "isa" "noavx,noavx,avx")])
10447
10448 ;; Conditionalize these after reload. If they match before reload, we
10449 ;; lose the clobber and ability to use integer instructions.
10450
10451 (define_insn "*<code><mode>2_i387"
10452 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10453 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10454 "TARGET_80387 && reload_completed"
10455 "<absneg_mnemonic>"
10456 [(set_attr "type" "fsgn")
10457 (set_attr "mode" "<MODE>")])
10458
10459 ;; Copysign instructions
10460
10461 (define_expand "copysign<mode>3"
10462 [(match_operand:SSEMODEF 0 "register_operand")
10463 (match_operand:SSEMODEF 1 "nonmemory_operand")
10464 (match_operand:SSEMODEF 2 "register_operand")]
10465 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10466 || (TARGET_SSE && (<MODE>mode == TFmode))"
10467 "ix86_expand_copysign (operands); DONE;")
10468
10469 (define_insn_and_split "@copysign<mode>3_const"
10470 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv")
10471 (unspec:SSEMODEF
10472 [(match_operand:<ssevecmodef> 1 "nonimm_or_0_operand" "YvmC")
10473 (match_operand:SSEMODEF 2 "register_operand" "0")
10474 (match_operand:<ssevecmodef> 3 "nonimmediate_operand" "Yvm")]
10475 UNSPEC_COPYSIGN))]
10476 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10477 || (TARGET_SSE && (<MODE>mode == TFmode))"
10478 "#"
10479 "&& reload_completed"
10480 [(const_int 0)]
10481 "ix86_split_copysign_const (operands); DONE;")
10482
10483 (define_insn "@copysign<mode>3_var"
10484 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10485 (unspec:SSEMODEF
10486 [(match_operand:SSEMODEF 2 "register_operand" "Yv,0,0,Yv,Yv")
10487 (match_operand:SSEMODEF 3 "register_operand" "1,1,Yv,1,Yv")
10488 (match_operand:<ssevecmodef> 4
10489 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10490 (match_operand:<ssevecmodef> 5
10491 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10492 UNSPEC_COPYSIGN))
10493 (clobber (match_scratch:<ssevecmodef> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10494 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10495 || (TARGET_SSE && (<MODE>mode == TFmode))"
10496 "#")
10497
10498 (define_split
10499 [(set (match_operand:SSEMODEF 0 "register_operand")
10500 (unspec:SSEMODEF
10501 [(match_operand:SSEMODEF 2 "register_operand")
10502 (match_operand:SSEMODEF 3 "register_operand")
10503 (match_operand:<ssevecmodef> 4)
10504 (match_operand:<ssevecmodef> 5)]
10505 UNSPEC_COPYSIGN))
10506 (clobber (match_scratch:<ssevecmodef> 1))]
10507 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10508 || (TARGET_SSE && (<MODE>mode == TFmode)))
10509 && reload_completed"
10510 [(const_int 0)]
10511 "ix86_split_copysign_var (operands); DONE;")
10512
10513 (define_expand "xorsign<mode>3"
10514 [(match_operand:MODEF 0 "register_operand")
10515 (match_operand:MODEF 1 "register_operand")
10516 (match_operand:MODEF 2 "register_operand")]
10517 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10518 "ix86_expand_xorsign (operands); DONE;")
10519
10520 (define_insn_and_split "@xorsign<mode>3_1"
10521 [(set (match_operand:MODEF 0 "register_operand" "=Yv")
10522 (unspec:MODEF
10523 [(match_operand:MODEF 1 "register_operand" "Yv")
10524 (match_operand:MODEF 2 "register_operand" "0")
10525 (match_operand:<ssevecmode> 3 "nonimmediate_operand" "Yvm")]
10526 UNSPEC_XORSIGN))]
10527 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10528 "#"
10529 "&& reload_completed"
10530 [(const_int 0)]
10531 "ix86_split_xorsign (operands); DONE;")
10532 \f
10533 ;; One complement instructions
10534
10535 (define_expand "one_cmpl<mode>2"
10536 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
10537 (not:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")))]
10538 ""
10539 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10540
10541 (define_insn_and_split "*one_cmpldi2_doubleword"
10542 [(set (match_operand:DI 0 "nonimmediate_operand")
10543 (not:DI (match_operand:DI 1 "nonimmediate_operand")))]
10544 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10545 && ix86_unary_operator_ok (NOT, DImode, operands)
10546 && ix86_pre_reload_split ()"
10547 "#"
10548 "&& 1"
10549 [(set (match_dup 0)
10550 (not:SI (match_dup 1)))
10551 (set (match_dup 2)
10552 (not:SI (match_dup 3)))]
10553 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10554
10555 (define_insn "*one_cmpl<mode>2_1"
10556 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,k")
10557 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
10558 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10559 "@
10560 not{<imodesuffix>}\t%0
10561 #"
10562 [(set (attr "isa")
10563 (cond [(eq_attr "alternative" "1")
10564 (if_then_else (eq_attr "mode" "SI,DI")
10565 (const_string "avx512bw")
10566 (const_string "avx512f"))
10567 ]
10568 (const_string "*")))
10569 (set_attr "type" "negnot,msklog")
10570 (set_attr "mode" "<MODE>")])
10571
10572 (define_insn "*one_cmplsi2_1_zext"
10573 [(set (match_operand:DI 0 "register_operand" "=r,k")
10574 (zero_extend:DI
10575 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
10576 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10577 "@
10578 not{l}\t%k0
10579 #"
10580 [(set_attr "isa" "x64,avx512bw")
10581 (set_attr "type" "negnot,msklog")
10582 (set_attr "mode" "SI,SI")])
10583
10584 (define_insn "*one_cmplqi2_1"
10585 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,k")
10586 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
10587 "ix86_unary_operator_ok (NOT, QImode, operands)"
10588 "@
10589 not{b}\t%0
10590 not{l}\t%k0
10591 #"
10592 [(set_attr "isa" "*,*,avx512f")
10593 (set_attr "type" "negnot,negnot,msklog")
10594 (set (attr "mode")
10595 (cond [(eq_attr "alternative" "1")
10596 (const_string "SI")
10597 (and (eq_attr "alternative" "2")
10598 (match_test "!TARGET_AVX512DQ"))
10599 (const_string "HI")
10600 ]
10601 (const_string "QI")))
10602 ;; Potential partial reg stall on alternative 1.
10603 (set (attr "preferred_for_speed")
10604 (cond [(eq_attr "alternative" "1")
10605 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10606 (symbol_ref "true")))])
10607
10608 (define_insn "*one_cmpl<mode>2_2"
10609 [(set (reg FLAGS_REG)
10610 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10611 (const_int 0)))
10612 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10613 (not:SWI (match_dup 1)))]
10614 "ix86_match_ccmode (insn, CCNOmode)
10615 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10616 "#"
10617 [(set_attr "type" "alu1")
10618 (set_attr "mode" "<MODE>")])
10619
10620 (define_split
10621 [(set (match_operand 0 "flags_reg_operand")
10622 (match_operator 2 "compare_operator"
10623 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10624 (const_int 0)]))
10625 (set (match_operand:SWI 1 "nonimmediate_operand")
10626 (not:SWI (match_dup 3)))]
10627 "ix86_match_ccmode (insn, CCNOmode)"
10628 [(parallel [(set (match_dup 0)
10629 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10630 (const_int 0)]))
10631 (set (match_dup 1)
10632 (xor:SWI (match_dup 3) (const_int -1)))])])
10633
10634 (define_insn "*one_cmplsi2_2_zext"
10635 [(set (reg FLAGS_REG)
10636 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10637 (const_int 0)))
10638 (set (match_operand:DI 0 "register_operand" "=r")
10639 (zero_extend:DI (not:SI (match_dup 1))))]
10640 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10641 && ix86_unary_operator_ok (NOT, SImode, operands)"
10642 "#"
10643 [(set_attr "type" "alu1")
10644 (set_attr "mode" "SI")])
10645
10646 (define_split
10647 [(set (match_operand 0 "flags_reg_operand")
10648 (match_operator 2 "compare_operator"
10649 [(not:SI (match_operand:SI 3 "register_operand"))
10650 (const_int 0)]))
10651 (set (match_operand:DI 1 "register_operand")
10652 (zero_extend:DI (not:SI (match_dup 3))))]
10653 "ix86_match_ccmode (insn, CCNOmode)"
10654 [(parallel [(set (match_dup 0)
10655 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10656 (const_int 0)]))
10657 (set (match_dup 1)
10658 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10659 \f
10660 ;; Shift instructions
10661
10662 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10663 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10664 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10665 ;; from the assembler input.
10666 ;;
10667 ;; This instruction shifts the target reg/mem as usual, but instead of
10668 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10669 ;; is a left shift double, bits are taken from the high order bits of
10670 ;; reg, else if the insn is a shift right double, bits are taken from the
10671 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10672 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10673 ;;
10674 ;; Since sh[lr]d does not change the `reg' operand, that is done
10675 ;; separately, making all shifts emit pairs of shift double and normal
10676 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10677 ;; support a 63 bit shift, each shift where the count is in a reg expands
10678 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10679 ;;
10680 ;; If the shift count is a constant, we need never emit more than one
10681 ;; shift pair, instead using moves and sign extension for counts greater
10682 ;; than 31.
10683
10684 (define_expand "ashl<mode>3"
10685 [(set (match_operand:SDWIM 0 "<shift_operand>")
10686 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10687 (match_operand:QI 2 "nonmemory_operand")))]
10688 ""
10689 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10690
10691 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
10692 [(set (match_operand:<DWI> 0 "register_operand")
10693 (ashift:<DWI>
10694 (match_operand:<DWI> 1 "register_operand")
10695 (subreg:QI
10696 (and:SI
10697 (match_operand:SI 2 "register_operand" "c")
10698 (match_operand:SI 3 "const_int_operand")) 0)))
10699 (clobber (reg:CC FLAGS_REG))]
10700 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10701 && ix86_pre_reload_split ()"
10702 "#"
10703 "&& 1"
10704 [(parallel
10705 [(set (match_dup 6)
10706 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10707 (lshiftrt:DWIH (match_dup 5)
10708 (minus:QI (match_dup 8) (match_dup 2)))))
10709 (clobber (reg:CC FLAGS_REG))])
10710 (parallel
10711 [(set (match_dup 4)
10712 (ashift:DWIH (match_dup 5) (match_dup 2)))
10713 (clobber (reg:CC FLAGS_REG))])]
10714 {
10715 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10716
10717 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10718
10719 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10720 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10721 {
10722 rtx tem = gen_reg_rtx (SImode);
10723 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10724 operands[2] = tem;
10725 }
10726
10727 operands[2] = gen_lowpart (QImode, operands[2]);
10728
10729 if (!rtx_equal_p (operands[6], operands[7]))
10730 emit_move_insn (operands[6], operands[7]);
10731 })
10732
10733 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
10734 [(set (match_operand:<DWI> 0 "register_operand")
10735 (ashift:<DWI>
10736 (match_operand:<DWI> 1 "register_operand")
10737 (and:QI
10738 (match_operand:QI 2 "register_operand" "c")
10739 (match_operand:QI 3 "const_int_operand"))))
10740 (clobber (reg:CC FLAGS_REG))]
10741 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10742 && ix86_pre_reload_split ()"
10743 "#"
10744 "&& 1"
10745 [(parallel
10746 [(set (match_dup 6)
10747 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10748 (lshiftrt:DWIH (match_dup 5)
10749 (minus:QI (match_dup 8) (match_dup 2)))))
10750 (clobber (reg:CC FLAGS_REG))])
10751 (parallel
10752 [(set (match_dup 4)
10753 (ashift:DWIH (match_dup 5) (match_dup 2)))
10754 (clobber (reg:CC FLAGS_REG))])]
10755 {
10756 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10757
10758 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10759
10760 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10761 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10762 {
10763 rtx tem = gen_reg_rtx (QImode);
10764 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10765 operands[2] = tem;
10766 }
10767
10768 if (!rtx_equal_p (operands[6], operands[7]))
10769 emit_move_insn (operands[6], operands[7]);
10770 })
10771
10772 (define_insn "*ashl<mode>3_doubleword"
10773 [(set (match_operand:DWI 0 "register_operand" "=&r")
10774 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10775 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10776 (clobber (reg:CC FLAGS_REG))]
10777 ""
10778 "#"
10779 [(set_attr "type" "multi")])
10780
10781 (define_split
10782 [(set (match_operand:DWI 0 "register_operand")
10783 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10784 (match_operand:QI 2 "nonmemory_operand")))
10785 (clobber (reg:CC FLAGS_REG))]
10786 "epilogue_completed"
10787 [(const_int 0)]
10788 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10789
10790 ;; By default we don't ask for a scratch register, because when DWImode
10791 ;; values are manipulated, registers are already at a premium. But if
10792 ;; we have one handy, we won't turn it away.
10793
10794 (define_peephole2
10795 [(match_scratch:DWIH 3 "r")
10796 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10797 (ashift:<DWI>
10798 (match_operand:<DWI> 1 "nonmemory_operand")
10799 (match_operand:QI 2 "nonmemory_operand")))
10800 (clobber (reg:CC FLAGS_REG))])
10801 (match_dup 3)]
10802 "TARGET_CMOVE"
10803 [(const_int 0)]
10804 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10805
10806 (define_insn "x86_64_shld"
10807 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10808 (ior:DI (ashift:DI (match_dup 0)
10809 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10810 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10811 (minus:QI (const_int 64) (match_dup 2)))))
10812 (clobber (reg:CC FLAGS_REG))]
10813 "TARGET_64BIT"
10814 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10815 [(set_attr "type" "ishift")
10816 (set_attr "prefix_0f" "1")
10817 (set_attr "mode" "DI")
10818 (set_attr "athlon_decode" "vector")
10819 (set_attr "amdfam10_decode" "vector")
10820 (set_attr "bdver1_decode" "vector")])
10821
10822 (define_insn "x86_shld"
10823 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10824 (ior:SI (ashift:SI (match_dup 0)
10825 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10826 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10827 (minus:QI (const_int 32) (match_dup 2)))))
10828 (clobber (reg:CC FLAGS_REG))]
10829 ""
10830 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10831 [(set_attr "type" "ishift")
10832 (set_attr "prefix_0f" "1")
10833 (set_attr "mode" "SI")
10834 (set_attr "pent_pair" "np")
10835 (set_attr "athlon_decode" "vector")
10836 (set_attr "amdfam10_decode" "vector")
10837 (set_attr "bdver1_decode" "vector")])
10838
10839 (define_expand "@x86_shift<mode>_adj_1"
10840 [(set (reg:CCZ FLAGS_REG)
10841 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10842 (match_dup 4))
10843 (const_int 0)))
10844 (set (match_operand:SWI48 0 "register_operand")
10845 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10846 (match_operand:SWI48 1 "register_operand")
10847 (match_dup 0)))
10848 (set (match_dup 1)
10849 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10850 (match_operand:SWI48 3 "register_operand")
10851 (match_dup 1)))]
10852 "TARGET_CMOVE"
10853 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10854
10855 (define_expand "@x86_shift<mode>_adj_2"
10856 [(use (match_operand:SWI48 0 "register_operand"))
10857 (use (match_operand:SWI48 1 "register_operand"))
10858 (use (match_operand:QI 2 "register_operand"))]
10859 ""
10860 {
10861 rtx_code_label *label = gen_label_rtx ();
10862 rtx tmp;
10863
10864 emit_insn (gen_testqi_ccz_1 (operands[2],
10865 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10866
10867 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10868 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10869 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10870 gen_rtx_LABEL_REF (VOIDmode, label),
10871 pc_rtx);
10872 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10873 JUMP_LABEL (tmp) = label;
10874
10875 emit_move_insn (operands[0], operands[1]);
10876 ix86_expand_clear (operands[1]);
10877
10878 emit_label (label);
10879 LABEL_NUSES (label) = 1;
10880
10881 DONE;
10882 })
10883
10884 ;; Avoid useless masking of count operand.
10885 (define_insn_and_split "*ashl<mode>3_mask"
10886 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10887 (ashift:SWI48
10888 (match_operand:SWI48 1 "nonimmediate_operand")
10889 (subreg:QI
10890 (and:SI
10891 (match_operand:SI 2 "register_operand" "c,r")
10892 (match_operand:SI 3 "const_int_operand")) 0)))
10893 (clobber (reg:CC FLAGS_REG))]
10894 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10895 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10896 == GET_MODE_BITSIZE (<MODE>mode)-1
10897 && ix86_pre_reload_split ()"
10898 "#"
10899 "&& 1"
10900 [(parallel
10901 [(set (match_dup 0)
10902 (ashift:SWI48 (match_dup 1)
10903 (match_dup 2)))
10904 (clobber (reg:CC FLAGS_REG))])]
10905 "operands[2] = gen_lowpart (QImode, operands[2]);"
10906 [(set_attr "isa" "*,bmi2")])
10907
10908 (define_insn_and_split "*ashl<mode>3_mask_1"
10909 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10910 (ashift:SWI48
10911 (match_operand:SWI48 1 "nonimmediate_operand")
10912 (and:QI
10913 (match_operand:QI 2 "register_operand" "c,r")
10914 (match_operand:QI 3 "const_int_operand"))))
10915 (clobber (reg:CC FLAGS_REG))]
10916 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10917 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10918 == GET_MODE_BITSIZE (<MODE>mode)-1
10919 && ix86_pre_reload_split ()"
10920 "#"
10921 "&& 1"
10922 [(parallel
10923 [(set (match_dup 0)
10924 (ashift:SWI48 (match_dup 1)
10925 (match_dup 2)))
10926 (clobber (reg:CC FLAGS_REG))])]
10927 ""
10928 [(set_attr "isa" "*,bmi2")])
10929
10930 (define_insn "*bmi2_ashl<mode>3_1"
10931 [(set (match_operand:SWI48 0 "register_operand" "=r")
10932 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10933 (match_operand:SWI48 2 "register_operand" "r")))]
10934 "TARGET_BMI2"
10935 "shlx\t{%2, %1, %0|%0, %1, %2}"
10936 [(set_attr "type" "ishiftx")
10937 (set_attr "mode" "<MODE>")])
10938
10939 (define_insn "*ashl<mode>3_1"
10940 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10941 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10942 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10943 (clobber (reg:CC FLAGS_REG))]
10944 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10945 {
10946 switch (get_attr_type (insn))
10947 {
10948 case TYPE_LEA:
10949 case TYPE_ISHIFTX:
10950 return "#";
10951
10952 case TYPE_ALU:
10953 gcc_assert (operands[2] == const1_rtx);
10954 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10955 return "add{<imodesuffix>}\t%0, %0";
10956
10957 default:
10958 if (operands[2] == const1_rtx
10959 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10960 return "sal{<imodesuffix>}\t%0";
10961 else
10962 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10963 }
10964 }
10965 [(set_attr "isa" "*,*,bmi2")
10966 (set (attr "type")
10967 (cond [(eq_attr "alternative" "1")
10968 (const_string "lea")
10969 (eq_attr "alternative" "2")
10970 (const_string "ishiftx")
10971 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10972 (match_operand 0 "register_operand"))
10973 (match_operand 2 "const1_operand"))
10974 (const_string "alu")
10975 ]
10976 (const_string "ishift")))
10977 (set (attr "length_immediate")
10978 (if_then_else
10979 (ior (eq_attr "type" "alu")
10980 (and (eq_attr "type" "ishift")
10981 (and (match_operand 2 "const1_operand")
10982 (ior (match_test "TARGET_SHIFT1")
10983 (match_test "optimize_function_for_size_p (cfun)")))))
10984 (const_string "0")
10985 (const_string "*")))
10986 (set_attr "mode" "<MODE>")])
10987
10988 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10989 (define_split
10990 [(set (match_operand:SWI48 0 "register_operand")
10991 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10992 (match_operand:QI 2 "register_operand")))
10993 (clobber (reg:CC FLAGS_REG))]
10994 "TARGET_BMI2 && reload_completed"
10995 [(set (match_dup 0)
10996 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10997 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10998
10999 (define_insn "*bmi2_ashlsi3_1_zext"
11000 [(set (match_operand:DI 0 "register_operand" "=r")
11001 (zero_extend:DI
11002 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11003 (match_operand:SI 2 "register_operand" "r"))))]
11004 "TARGET_64BIT && TARGET_BMI2"
11005 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
11006 [(set_attr "type" "ishiftx")
11007 (set_attr "mode" "SI")])
11008
11009 (define_insn "*ashlsi3_1_zext"
11010 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
11011 (zero_extend:DI
11012 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
11013 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
11014 (clobber (reg:CC FLAGS_REG))]
11015 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11016 {
11017 switch (get_attr_type (insn))
11018 {
11019 case TYPE_LEA:
11020 case TYPE_ISHIFTX:
11021 return "#";
11022
11023 case TYPE_ALU:
11024 gcc_assert (operands[2] == const1_rtx);
11025 return "add{l}\t%k0, %k0";
11026
11027 default:
11028 if (operands[2] == const1_rtx
11029 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11030 return "sal{l}\t%k0";
11031 else
11032 return "sal{l}\t{%2, %k0|%k0, %2}";
11033 }
11034 }
11035 [(set_attr "isa" "*,*,bmi2")
11036 (set (attr "type")
11037 (cond [(eq_attr "alternative" "1")
11038 (const_string "lea")
11039 (eq_attr "alternative" "2")
11040 (const_string "ishiftx")
11041 (and (match_test "TARGET_DOUBLE_WITH_ADD")
11042 (match_operand 2 "const1_operand"))
11043 (const_string "alu")
11044 ]
11045 (const_string "ishift")))
11046 (set (attr "length_immediate")
11047 (if_then_else
11048 (ior (eq_attr "type" "alu")
11049 (and (eq_attr "type" "ishift")
11050 (and (match_operand 2 "const1_operand")
11051 (ior (match_test "TARGET_SHIFT1")
11052 (match_test "optimize_function_for_size_p (cfun)")))))
11053 (const_string "0")
11054 (const_string "*")))
11055 (set_attr "mode" "SI")])
11056
11057 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11058 (define_split
11059 [(set (match_operand:DI 0 "register_operand")
11060 (zero_extend:DI
11061 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
11062 (match_operand:QI 2 "register_operand"))))
11063 (clobber (reg:CC FLAGS_REG))]
11064 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11065 [(set (match_dup 0)
11066 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11067 "operands[2] = gen_lowpart (SImode, operands[2]);")
11068
11069 (define_insn "*ashlhi3_1"
11070 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
11071 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11072 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11073 (clobber (reg:CC FLAGS_REG))]
11074 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11075 {
11076 switch (get_attr_type (insn))
11077 {
11078 case TYPE_LEA:
11079 return "#";
11080
11081 case TYPE_ALU:
11082 gcc_assert (operands[2] == const1_rtx);
11083 return "add{w}\t%0, %0";
11084
11085 default:
11086 if (operands[2] == const1_rtx
11087 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11088 return "sal{w}\t%0";
11089 else
11090 return "sal{w}\t{%2, %0|%0, %2}";
11091 }
11092 }
11093 [(set (attr "type")
11094 (cond [(eq_attr "alternative" "1")
11095 (const_string "lea")
11096 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11097 (match_operand 0 "register_operand"))
11098 (match_operand 2 "const1_operand"))
11099 (const_string "alu")
11100 ]
11101 (const_string "ishift")))
11102 (set (attr "length_immediate")
11103 (if_then_else
11104 (ior (eq_attr "type" "alu")
11105 (and (eq_attr "type" "ishift")
11106 (and (match_operand 2 "const1_operand")
11107 (ior (match_test "TARGET_SHIFT1")
11108 (match_test "optimize_function_for_size_p (cfun)")))))
11109 (const_string "0")
11110 (const_string "*")))
11111 (set_attr "mode" "HI,SI")])
11112
11113 (define_insn "*ashlqi3_1"
11114 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
11115 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11116 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11117 (clobber (reg:CC FLAGS_REG))]
11118 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11119 {
11120 switch (get_attr_type (insn))
11121 {
11122 case TYPE_LEA:
11123 return "#";
11124
11125 case TYPE_ALU:
11126 gcc_assert (operands[2] == const1_rtx);
11127 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
11128 return "add{l}\t%k0, %k0";
11129 else
11130 return "add{b}\t%0, %0";
11131
11132 default:
11133 if (operands[2] == const1_rtx
11134 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11135 {
11136 if (get_attr_mode (insn) == MODE_SI)
11137 return "sal{l}\t%k0";
11138 else
11139 return "sal{b}\t%0";
11140 }
11141 else
11142 {
11143 if (get_attr_mode (insn) == MODE_SI)
11144 return "sal{l}\t{%2, %k0|%k0, %2}";
11145 else
11146 return "sal{b}\t{%2, %0|%0, %2}";
11147 }
11148 }
11149 }
11150 [(set (attr "type")
11151 (cond [(eq_attr "alternative" "2")
11152 (const_string "lea")
11153 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11154 (match_operand 0 "register_operand"))
11155 (match_operand 2 "const1_operand"))
11156 (const_string "alu")
11157 ]
11158 (const_string "ishift")))
11159 (set (attr "length_immediate")
11160 (if_then_else
11161 (ior (eq_attr "type" "alu")
11162 (and (eq_attr "type" "ishift")
11163 (and (match_operand 2 "const1_operand")
11164 (ior (match_test "TARGET_SHIFT1")
11165 (match_test "optimize_function_for_size_p (cfun)")))))
11166 (const_string "0")
11167 (const_string "*")))
11168 (set_attr "mode" "QI,SI,SI")
11169 ;; Potential partial reg stall on alternative 1.
11170 (set (attr "preferred_for_speed")
11171 (cond [(eq_attr "alternative" "1")
11172 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11173 (symbol_ref "true")))])
11174
11175 (define_insn "*ashl<mode>3_1_slp"
11176 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
11177 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0")
11178 (match_operand:QI 2 "nonmemory_operand" "cI")))
11179 (clobber (reg:CC FLAGS_REG))]
11180 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11181 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11182 && rtx_equal_p (operands[0], operands[1])"
11183 {
11184 switch (get_attr_type (insn))
11185 {
11186 case TYPE_ALU:
11187 gcc_assert (operands[2] == const1_rtx);
11188 return "add{<imodesuffix>}\t%0, %0";
11189
11190 default:
11191 if (operands[2] == const1_rtx
11192 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11193 return "sal{<imodesuffix>}\t%0";
11194 else
11195 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11196 }
11197 }
11198 [(set (attr "type")
11199 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
11200 (match_operand 2 "const1_operand"))
11201 (const_string "alu")
11202 ]
11203 (const_string "ishift")))
11204 (set (attr "length_immediate")
11205 (if_then_else
11206 (ior (eq_attr "type" "alu")
11207 (and (eq_attr "type" "ishift")
11208 (and (match_operand 2 "const1_operand")
11209 (ior (match_test "TARGET_SHIFT1")
11210 (match_test "optimize_function_for_size_p (cfun)")))))
11211 (const_string "0")
11212 (const_string "*")))
11213 (set_attr "mode" "<MODE>")])
11214
11215 ;; Convert ashift to the lea pattern to avoid flags dependency.
11216 (define_split
11217 [(set (match_operand:SWI 0 "register_operand")
11218 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
11219 (match_operand 2 "const_0_to_3_operand")))
11220 (clobber (reg:CC FLAGS_REG))]
11221 "reload_completed
11222 && REGNO (operands[0]) != REGNO (operands[1])"
11223 [(set (match_dup 0)
11224 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
11225 {
11226 if (<MODE>mode != <LEAMODE>mode)
11227 {
11228 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
11229 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
11230 }
11231 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11232 })
11233
11234 ;; Convert ashift to the lea pattern to avoid flags dependency.
11235 (define_split
11236 [(set (match_operand:DI 0 "register_operand")
11237 (zero_extend:DI
11238 (ashift:SI (match_operand:SI 1 "index_register_operand")
11239 (match_operand 2 "const_0_to_3_operand"))))
11240 (clobber (reg:CC FLAGS_REG))]
11241 "TARGET_64BIT && reload_completed
11242 && REGNO (operands[0]) != REGNO (operands[1])"
11243 [(set (match_dup 0)
11244 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
11245 {
11246 operands[1] = gen_lowpart (SImode, operands[1]);
11247 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11248 })
11249
11250 ;; This pattern can't accept a variable shift count, since shifts by
11251 ;; zero don't affect the flags. We assume that shifts by constant
11252 ;; zero are optimized away.
11253 (define_insn "*ashl<mode>3_cmp"
11254 [(set (reg FLAGS_REG)
11255 (compare
11256 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
11257 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11258 (const_int 0)))
11259 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11260 (ashift:SWI (match_dup 1) (match_dup 2)))]
11261 "(optimize_function_for_size_p (cfun)
11262 || !TARGET_PARTIAL_FLAG_REG_STALL
11263 || (operands[2] == const1_rtx
11264 && (TARGET_SHIFT1
11265 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11266 && ix86_match_ccmode (insn, CCGOCmode)
11267 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
11268 {
11269 switch (get_attr_type (insn))
11270 {
11271 case TYPE_ALU:
11272 gcc_assert (operands[2] == const1_rtx);
11273 return "add{<imodesuffix>}\t%0, %0";
11274
11275 default:
11276 if (operands[2] == const1_rtx
11277 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11278 return "sal{<imodesuffix>}\t%0";
11279 else
11280 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11281 }
11282 }
11283 [(set (attr "type")
11284 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11285 (match_operand 0 "register_operand"))
11286 (match_operand 2 "const1_operand"))
11287 (const_string "alu")
11288 ]
11289 (const_string "ishift")))
11290 (set (attr "length_immediate")
11291 (if_then_else
11292 (ior (eq_attr "type" "alu")
11293 (and (eq_attr "type" "ishift")
11294 (and (match_operand 2 "const1_operand")
11295 (ior (match_test "TARGET_SHIFT1")
11296 (match_test "optimize_function_for_size_p (cfun)")))))
11297 (const_string "0")
11298 (const_string "*")))
11299 (set_attr "mode" "<MODE>")])
11300
11301 (define_insn "*ashlsi3_cmp_zext"
11302 [(set (reg FLAGS_REG)
11303 (compare
11304 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11305 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11306 (const_int 0)))
11307 (set (match_operand:DI 0 "register_operand" "=r")
11308 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11309 "TARGET_64BIT
11310 && (optimize_function_for_size_p (cfun)
11311 || !TARGET_PARTIAL_FLAG_REG_STALL
11312 || (operands[2] == const1_rtx
11313 && (TARGET_SHIFT1
11314 || TARGET_DOUBLE_WITH_ADD)))
11315 && ix86_match_ccmode (insn, CCGOCmode)
11316 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11317 {
11318 switch (get_attr_type (insn))
11319 {
11320 case TYPE_ALU:
11321 gcc_assert (operands[2] == const1_rtx);
11322 return "add{l}\t%k0, %k0";
11323
11324 default:
11325 if (operands[2] == const1_rtx
11326 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11327 return "sal{l}\t%k0";
11328 else
11329 return "sal{l}\t{%2, %k0|%k0, %2}";
11330 }
11331 }
11332 [(set (attr "type")
11333 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
11334 (match_operand 2 "const1_operand"))
11335 (const_string "alu")
11336 ]
11337 (const_string "ishift")))
11338 (set (attr "length_immediate")
11339 (if_then_else
11340 (ior (eq_attr "type" "alu")
11341 (and (eq_attr "type" "ishift")
11342 (and (match_operand 2 "const1_operand")
11343 (ior (match_test "TARGET_SHIFT1")
11344 (match_test "optimize_function_for_size_p (cfun)")))))
11345 (const_string "0")
11346 (const_string "*")))
11347 (set_attr "mode" "SI")])
11348
11349 (define_insn "*ashl<mode>3_cconly"
11350 [(set (reg FLAGS_REG)
11351 (compare
11352 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
11353 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11354 (const_int 0)))
11355 (clobber (match_scratch:SWI 0 "=<r>"))]
11356 "(optimize_function_for_size_p (cfun)
11357 || !TARGET_PARTIAL_FLAG_REG_STALL
11358 || (operands[2] == const1_rtx
11359 && (TARGET_SHIFT1
11360 || TARGET_DOUBLE_WITH_ADD)))
11361 && ix86_match_ccmode (insn, CCGOCmode)"
11362 {
11363 switch (get_attr_type (insn))
11364 {
11365 case TYPE_ALU:
11366 gcc_assert (operands[2] == const1_rtx);
11367 return "add{<imodesuffix>}\t%0, %0";
11368
11369 default:
11370 if (operands[2] == const1_rtx
11371 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11372 return "sal{<imodesuffix>}\t%0";
11373 else
11374 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11375 }
11376 }
11377 [(set (attr "type")
11378 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11379 (match_operand 0 "register_operand"))
11380 (match_operand 2 "const1_operand"))
11381 (const_string "alu")
11382 ]
11383 (const_string "ishift")))
11384 (set (attr "length_immediate")
11385 (if_then_else
11386 (ior (eq_attr "type" "alu")
11387 (and (eq_attr "type" "ishift")
11388 (and (match_operand 2 "const1_operand")
11389 (ior (match_test "TARGET_SHIFT1")
11390 (match_test "optimize_function_for_size_p (cfun)")))))
11391 (const_string "0")
11392 (const_string "*")))
11393 (set_attr "mode" "<MODE>")])
11394
11395 ;; See comment above `ashl<mode>3' about how this works.
11396
11397 (define_expand "<insn><mode>3"
11398 [(set (match_operand:SDWIM 0 "<shift_operand>")
11399 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
11400 (match_operand:QI 2 "nonmemory_operand")))]
11401 ""
11402 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11403
11404 ;; Avoid useless masking of count operand.
11405 (define_insn_and_split "*<insn><mode>3_mask"
11406 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11407 (any_shiftrt:SWI48
11408 (match_operand:SWI48 1 "nonimmediate_operand")
11409 (subreg:QI
11410 (and:SI
11411 (match_operand:SI 2 "register_operand" "c,r")
11412 (match_operand:SI 3 "const_int_operand")) 0)))
11413 (clobber (reg:CC FLAGS_REG))]
11414 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11415 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11416 == GET_MODE_BITSIZE (<MODE>mode)-1
11417 && ix86_pre_reload_split ()"
11418 "#"
11419 "&& 1"
11420 [(parallel
11421 [(set (match_dup 0)
11422 (any_shiftrt:SWI48 (match_dup 1)
11423 (match_dup 2)))
11424 (clobber (reg:CC FLAGS_REG))])]
11425 "operands[2] = gen_lowpart (QImode, operands[2]);"
11426 [(set_attr "isa" "*,bmi2")])
11427
11428 (define_insn_and_split "*<insn><mode>3_mask_1"
11429 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11430 (any_shiftrt:SWI48
11431 (match_operand:SWI48 1 "nonimmediate_operand")
11432 (and:QI
11433 (match_operand:QI 2 "register_operand" "c,r")
11434 (match_operand:QI 3 "const_int_operand"))))
11435 (clobber (reg:CC FLAGS_REG))]
11436 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11437 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11438 == GET_MODE_BITSIZE (<MODE>mode)-1
11439 && ix86_pre_reload_split ()"
11440 "#"
11441 "&& 1"
11442 [(parallel
11443 [(set (match_dup 0)
11444 (any_shiftrt:SWI48 (match_dup 1)
11445 (match_dup 2)))
11446 (clobber (reg:CC FLAGS_REG))])]
11447 ""
11448 [(set_attr "isa" "*,bmi2")])
11449
11450 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
11451 [(set (match_operand:<DWI> 0 "register_operand")
11452 (any_shiftrt:<DWI>
11453 (match_operand:<DWI> 1 "register_operand")
11454 (subreg:QI
11455 (and:SI
11456 (match_operand:SI 2 "register_operand" "c")
11457 (match_operand:SI 3 "const_int_operand")) 0)))
11458 (clobber (reg:CC FLAGS_REG))]
11459 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11460 && ix86_pre_reload_split ()"
11461 "#"
11462 "&& 1"
11463 [(parallel
11464 [(set (match_dup 4)
11465 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11466 (ashift:DWIH (match_dup 7)
11467 (minus:QI (match_dup 8) (match_dup 2)))))
11468 (clobber (reg:CC FLAGS_REG))])
11469 (parallel
11470 [(set (match_dup 6)
11471 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11472 (clobber (reg:CC FLAGS_REG))])]
11473 {
11474 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11475
11476 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11477
11478 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11479 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11480 {
11481 rtx tem = gen_reg_rtx (SImode);
11482 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
11483 operands[2] = tem;
11484 }
11485
11486 operands[2] = gen_lowpart (QImode, operands[2]);
11487
11488 if (!rtx_equal_p (operands[4], operands[5]))
11489 emit_move_insn (operands[4], operands[5]);
11490 })
11491
11492 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
11493 [(set (match_operand:<DWI> 0 "register_operand")
11494 (any_shiftrt:<DWI>
11495 (match_operand:<DWI> 1 "register_operand")
11496 (and:QI
11497 (match_operand:QI 2 "register_operand" "c")
11498 (match_operand:QI 3 "const_int_operand"))))
11499 (clobber (reg:CC FLAGS_REG))]
11500 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11501 && ix86_pre_reload_split ()"
11502 "#"
11503 "&& 1"
11504 [(parallel
11505 [(set (match_dup 4)
11506 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11507 (ashift:DWIH (match_dup 7)
11508 (minus:QI (match_dup 8) (match_dup 2)))))
11509 (clobber (reg:CC FLAGS_REG))])
11510 (parallel
11511 [(set (match_dup 6)
11512 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11513 (clobber (reg:CC FLAGS_REG))])]
11514 {
11515 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11516
11517 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11518
11519 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11520 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11521 {
11522 rtx tem = gen_reg_rtx (QImode);
11523 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
11524 operands[2] = tem;
11525 }
11526
11527 if (!rtx_equal_p (operands[4], operands[5]))
11528 emit_move_insn (operands[4], operands[5]);
11529 })
11530
11531 (define_insn_and_split "*<insn><mode>3_doubleword"
11532 [(set (match_operand:DWI 0 "register_operand" "=&r")
11533 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
11534 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
11535 (clobber (reg:CC FLAGS_REG))]
11536 ""
11537 "#"
11538 "epilogue_completed"
11539 [(const_int 0)]
11540 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
11541 [(set_attr "type" "multi")])
11542
11543 ;; By default we don't ask for a scratch register, because when DWImode
11544 ;; values are manipulated, registers are already at a premium. But if
11545 ;; we have one handy, we won't turn it away.
11546
11547 (define_peephole2
11548 [(match_scratch:DWIH 3 "r")
11549 (parallel [(set (match_operand:<DWI> 0 "register_operand")
11550 (any_shiftrt:<DWI>
11551 (match_operand:<DWI> 1 "register_operand")
11552 (match_operand:QI 2 "nonmemory_operand")))
11553 (clobber (reg:CC FLAGS_REG))])
11554 (match_dup 3)]
11555 "TARGET_CMOVE"
11556 [(const_int 0)]
11557 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
11558
11559 (define_insn "x86_64_shrd"
11560 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11561 (ior:DI (lshiftrt:DI (match_dup 0)
11562 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11563 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11564 (minus:QI (const_int 64) (match_dup 2)))))
11565 (clobber (reg:CC FLAGS_REG))]
11566 "TARGET_64BIT"
11567 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11568 [(set_attr "type" "ishift")
11569 (set_attr "prefix_0f" "1")
11570 (set_attr "mode" "DI")
11571 (set_attr "athlon_decode" "vector")
11572 (set_attr "amdfam10_decode" "vector")
11573 (set_attr "bdver1_decode" "vector")])
11574
11575 (define_insn "x86_shrd"
11576 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11577 (ior:SI (lshiftrt:SI (match_dup 0)
11578 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11579 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11580 (minus:QI (const_int 32) (match_dup 2)))))
11581 (clobber (reg:CC FLAGS_REG))]
11582 ""
11583 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11584 [(set_attr "type" "ishift")
11585 (set_attr "prefix_0f" "1")
11586 (set_attr "mode" "SI")
11587 (set_attr "pent_pair" "np")
11588 (set_attr "athlon_decode" "vector")
11589 (set_attr "amdfam10_decode" "vector")
11590 (set_attr "bdver1_decode" "vector")])
11591
11592 ;; Base name for insn mnemonic.
11593 (define_mode_attr cvt_mnemonic
11594 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
11595
11596 (define_insn "ashr<mode>3_cvt"
11597 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
11598 (ashiftrt:SWI48
11599 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
11600 (match_operand:QI 2 "const_int_operand")))
11601 (clobber (reg:CC FLAGS_REG))]
11602 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
11603 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11604 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
11605 "@
11606 <cvt_mnemonic>
11607 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
11608 [(set_attr "type" "imovx,ishift")
11609 (set_attr "prefix_0f" "0,*")
11610 (set_attr "length_immediate" "0,*")
11611 (set_attr "modrm" "0,1")
11612 (set_attr "mode" "<MODE>")])
11613
11614 (define_insn "*ashrsi3_cvt_zext"
11615 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11616 (zero_extend:DI
11617 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11618 (match_operand:QI 2 "const_int_operand"))))
11619 (clobber (reg:CC FLAGS_REG))]
11620 "TARGET_64BIT && INTVAL (operands[2]) == 31
11621 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11622 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11623 "@
11624 {cltd|cdq}
11625 sar{l}\t{%2, %k0|%k0, %2}"
11626 [(set_attr "type" "imovx,ishift")
11627 (set_attr "prefix_0f" "0,*")
11628 (set_attr "length_immediate" "0,*")
11629 (set_attr "modrm" "0,1")
11630 (set_attr "mode" "SI")])
11631
11632 (define_expand "@x86_shift<mode>_adj_3"
11633 [(use (match_operand:SWI48 0 "register_operand"))
11634 (use (match_operand:SWI48 1 "register_operand"))
11635 (use (match_operand:QI 2 "register_operand"))]
11636 ""
11637 {
11638 rtx_code_label *label = gen_label_rtx ();
11639 rtx tmp;
11640
11641 emit_insn (gen_testqi_ccz_1 (operands[2],
11642 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11643
11644 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11645 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11646 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11647 gen_rtx_LABEL_REF (VOIDmode, label),
11648 pc_rtx);
11649 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11650 JUMP_LABEL (tmp) = label;
11651
11652 emit_move_insn (operands[0], operands[1]);
11653 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11654 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11655 emit_label (label);
11656 LABEL_NUSES (label) = 1;
11657
11658 DONE;
11659 })
11660
11661 (define_insn "*bmi2_<insn><mode>3_1"
11662 [(set (match_operand:SWI48 0 "register_operand" "=r")
11663 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11664 (match_operand:SWI48 2 "register_operand" "r")))]
11665 "TARGET_BMI2"
11666 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11667 [(set_attr "type" "ishiftx")
11668 (set_attr "mode" "<MODE>")])
11669
11670 (define_insn "*<insn><mode>3_1"
11671 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11672 (any_shiftrt:SWI48
11673 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11674 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11675 (clobber (reg:CC FLAGS_REG))]
11676 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11677 {
11678 switch (get_attr_type (insn))
11679 {
11680 case TYPE_ISHIFTX:
11681 return "#";
11682
11683 default:
11684 if (operands[2] == const1_rtx
11685 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11686 return "<shift>{<imodesuffix>}\t%0";
11687 else
11688 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11689 }
11690 }
11691 [(set_attr "isa" "*,bmi2")
11692 (set_attr "type" "ishift,ishiftx")
11693 (set (attr "length_immediate")
11694 (if_then_else
11695 (and (match_operand 2 "const1_operand")
11696 (ior (match_test "TARGET_SHIFT1")
11697 (match_test "optimize_function_for_size_p (cfun)")))
11698 (const_string "0")
11699 (const_string "*")))
11700 (set_attr "mode" "<MODE>")])
11701
11702 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11703 (define_split
11704 [(set (match_operand:SWI48 0 "register_operand")
11705 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11706 (match_operand:QI 2 "register_operand")))
11707 (clobber (reg:CC FLAGS_REG))]
11708 "TARGET_BMI2 && reload_completed"
11709 [(set (match_dup 0)
11710 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11711 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11712
11713 (define_insn "*bmi2_<insn>si3_1_zext"
11714 [(set (match_operand:DI 0 "register_operand" "=r")
11715 (zero_extend:DI
11716 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11717 (match_operand:SI 2 "register_operand" "r"))))]
11718 "TARGET_64BIT && TARGET_BMI2"
11719 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11720 [(set_attr "type" "ishiftx")
11721 (set_attr "mode" "SI")])
11722
11723 (define_insn "*<insn>si3_1_zext"
11724 [(set (match_operand:DI 0 "register_operand" "=r,r")
11725 (zero_extend:DI
11726 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11727 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11728 (clobber (reg:CC FLAGS_REG))]
11729 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11730 {
11731 switch (get_attr_type (insn))
11732 {
11733 case TYPE_ISHIFTX:
11734 return "#";
11735
11736 default:
11737 if (operands[2] == const1_rtx
11738 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11739 return "<shift>{l}\t%k0";
11740 else
11741 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11742 }
11743 }
11744 [(set_attr "isa" "*,bmi2")
11745 (set_attr "type" "ishift,ishiftx")
11746 (set (attr "length_immediate")
11747 (if_then_else
11748 (and (match_operand 2 "const1_operand")
11749 (ior (match_test "TARGET_SHIFT1")
11750 (match_test "optimize_function_for_size_p (cfun)")))
11751 (const_string "0")
11752 (const_string "*")))
11753 (set_attr "mode" "SI")])
11754
11755 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11756 (define_split
11757 [(set (match_operand:DI 0 "register_operand")
11758 (zero_extend:DI
11759 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11760 (match_operand:QI 2 "register_operand"))))
11761 (clobber (reg:CC FLAGS_REG))]
11762 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11763 [(set (match_dup 0)
11764 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11765 "operands[2] = gen_lowpart (SImode, operands[2]);")
11766
11767 (define_insn "*<insn><mode>3_1"
11768 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11769 (any_shiftrt:SWI12
11770 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11771 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11772 (clobber (reg:CC FLAGS_REG))]
11773 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11774 {
11775 if (operands[2] == const1_rtx
11776 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11777 return "<shift>{<imodesuffix>}\t%0";
11778 else
11779 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11780 }
11781 [(set_attr "type" "ishift")
11782 (set (attr "length_immediate")
11783 (if_then_else
11784 (and (match_operand 2 "const1_operand")
11785 (ior (match_test "TARGET_SHIFT1")
11786 (match_test "optimize_function_for_size_p (cfun)")))
11787 (const_string "0")
11788 (const_string "*")))
11789 (set_attr "mode" "<MODE>")])
11790
11791 (define_insn "*<insn><mode>3_1_slp"
11792 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
11793 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0")
11794 (match_operand:QI 2 "nonmemory_operand" "cI")))
11795 (clobber (reg:CC FLAGS_REG))]
11796 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11797 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11798 && rtx_equal_p (operands[0], operands[1])"
11799 {
11800 if (operands[2] == const1_rtx
11801 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11802 return "<shift>{<imodesuffix>}\t%0";
11803 else
11804 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11805 }
11806 [(set_attr "type" "ishift")
11807 (set (attr "length_immediate")
11808 (if_then_else
11809 (and (match_operand 2 "const1_operand")
11810 (ior (match_test "TARGET_SHIFT1")
11811 (match_test "optimize_function_for_size_p (cfun)")))
11812 (const_string "0")
11813 (const_string "*")))
11814 (set_attr "mode" "<MODE>")])
11815
11816 ;; This pattern can't accept a variable shift count, since shifts by
11817 ;; zero don't affect the flags. We assume that shifts by constant
11818 ;; zero are optimized away.
11819 (define_insn "*<insn><mode>3_cmp"
11820 [(set (reg FLAGS_REG)
11821 (compare
11822 (any_shiftrt:SWI
11823 (match_operand:SWI 1 "nonimmediate_operand" "0")
11824 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11825 (const_int 0)))
11826 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11827 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11828 "(optimize_function_for_size_p (cfun)
11829 || !TARGET_PARTIAL_FLAG_REG_STALL
11830 || (operands[2] == const1_rtx
11831 && TARGET_SHIFT1))
11832 && ix86_match_ccmode (insn, CCGOCmode)
11833 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11834 {
11835 if (operands[2] == const1_rtx
11836 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11837 return "<shift>{<imodesuffix>}\t%0";
11838 else
11839 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11840 }
11841 [(set_attr "type" "ishift")
11842 (set (attr "length_immediate")
11843 (if_then_else
11844 (and (match_operand 2 "const1_operand")
11845 (ior (match_test "TARGET_SHIFT1")
11846 (match_test "optimize_function_for_size_p (cfun)")))
11847 (const_string "0")
11848 (const_string "*")))
11849 (set_attr "mode" "<MODE>")])
11850
11851 (define_insn "*<insn>si3_cmp_zext"
11852 [(set (reg FLAGS_REG)
11853 (compare
11854 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11855 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11856 (const_int 0)))
11857 (set (match_operand:DI 0 "register_operand" "=r")
11858 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11859 "TARGET_64BIT
11860 && (optimize_function_for_size_p (cfun)
11861 || !TARGET_PARTIAL_FLAG_REG_STALL
11862 || (operands[2] == const1_rtx
11863 && TARGET_SHIFT1))
11864 && ix86_match_ccmode (insn, CCGOCmode)
11865 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11866 {
11867 if (operands[2] == const1_rtx
11868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11869 return "<shift>{l}\t%k0";
11870 else
11871 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11872 }
11873 [(set_attr "type" "ishift")
11874 (set (attr "length_immediate")
11875 (if_then_else
11876 (and (match_operand 2 "const1_operand")
11877 (ior (match_test "TARGET_SHIFT1")
11878 (match_test "optimize_function_for_size_p (cfun)")))
11879 (const_string "0")
11880 (const_string "*")))
11881 (set_attr "mode" "SI")])
11882
11883 (define_insn "*<insn><mode>3_cconly"
11884 [(set (reg FLAGS_REG)
11885 (compare
11886 (any_shiftrt:SWI
11887 (match_operand:SWI 1 "register_operand" "0")
11888 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11889 (const_int 0)))
11890 (clobber (match_scratch:SWI 0 "=<r>"))]
11891 "(optimize_function_for_size_p (cfun)
11892 || !TARGET_PARTIAL_FLAG_REG_STALL
11893 || (operands[2] == const1_rtx
11894 && TARGET_SHIFT1))
11895 && ix86_match_ccmode (insn, CCGOCmode)"
11896 {
11897 if (operands[2] == const1_rtx
11898 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11899 return "<shift>{<imodesuffix>}\t%0";
11900 else
11901 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11902 }
11903 [(set_attr "type" "ishift")
11904 (set (attr "length_immediate")
11905 (if_then_else
11906 (and (match_operand 2 "const1_operand")
11907 (ior (match_test "TARGET_SHIFT1")
11908 (match_test "optimize_function_for_size_p (cfun)")))
11909 (const_string "0")
11910 (const_string "*")))
11911 (set_attr "mode" "<MODE>")])
11912 \f
11913 ;; Rotate instructions
11914
11915 (define_expand "<insn>ti3"
11916 [(set (match_operand:TI 0 "register_operand")
11917 (any_rotate:TI (match_operand:TI 1 "register_operand")
11918 (match_operand:QI 2 "nonmemory_operand")))]
11919 "TARGET_64BIT"
11920 {
11921 if (const_1_to_63_operand (operands[2], VOIDmode))
11922 emit_insn (gen_ix86_<insn>ti3_doubleword
11923 (operands[0], operands[1], operands[2]));
11924 else
11925 FAIL;
11926
11927 DONE;
11928 })
11929
11930 (define_expand "<insn>di3"
11931 [(set (match_operand:DI 0 "shiftdi_operand")
11932 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11933 (match_operand:QI 2 "nonmemory_operand")))]
11934 ""
11935 {
11936 if (TARGET_64BIT)
11937 ix86_expand_binary_operator (<CODE>, DImode, operands);
11938 else if (const_1_to_31_operand (operands[2], VOIDmode))
11939 emit_insn (gen_ix86_<insn>di3_doubleword
11940 (operands[0], operands[1], operands[2]));
11941 else
11942 FAIL;
11943
11944 DONE;
11945 })
11946
11947 (define_expand "<insn><mode>3"
11948 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11949 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11950 (match_operand:QI 2 "nonmemory_operand")))]
11951 ""
11952 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11953
11954 ;; Avoid useless masking of count operand.
11955 (define_insn_and_split "*<insn><mode>3_mask"
11956 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11957 (any_rotate:SWI48
11958 (match_operand:SWI48 1 "nonimmediate_operand")
11959 (subreg:QI
11960 (and:SI
11961 (match_operand:SI 2 "register_operand" "c")
11962 (match_operand:SI 3 "const_int_operand")) 0)))
11963 (clobber (reg:CC FLAGS_REG))]
11964 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11965 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11966 == GET_MODE_BITSIZE (<MODE>mode)-1
11967 && ix86_pre_reload_split ()"
11968 "#"
11969 "&& 1"
11970 [(parallel
11971 [(set (match_dup 0)
11972 (any_rotate:SWI48 (match_dup 1)
11973 (match_dup 2)))
11974 (clobber (reg:CC FLAGS_REG))])]
11975 "operands[2] = gen_lowpart (QImode, operands[2]);")
11976
11977 (define_split
11978 [(set (match_operand:SWI48 0 "register_operand")
11979 (any_rotate:SWI48
11980 (match_operand:SWI48 1 "const_int_operand")
11981 (subreg:QI
11982 (and:SI
11983 (match_operand:SI 2 "register_operand")
11984 (match_operand:SI 3 "const_int_operand")) 0)))]
11985 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
11986 == GET_MODE_BITSIZE (<MODE>mode) - 1"
11987 [(set (match_dup 4) (match_dup 1))
11988 (set (match_dup 0)
11989 (any_rotate:SWI48 (match_dup 4)
11990 (subreg:QI (match_dup 2) 0)))]
11991 "operands[4] = gen_reg_rtx (<MODE>mode);")
11992
11993 (define_insn_and_split "*<insn><mode>3_mask_1"
11994 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11995 (any_rotate:SWI48
11996 (match_operand:SWI48 1 "nonimmediate_operand")
11997 (and:QI
11998 (match_operand:QI 2 "register_operand" "c")
11999 (match_operand:QI 3 "const_int_operand"))))
12000 (clobber (reg:CC FLAGS_REG))]
12001 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
12002 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12003 == GET_MODE_BITSIZE (<MODE>mode)-1
12004 && ix86_pre_reload_split ()"
12005 "#"
12006 "&& 1"
12007 [(parallel
12008 [(set (match_dup 0)
12009 (any_rotate:SWI48 (match_dup 1)
12010 (match_dup 2)))
12011 (clobber (reg:CC FLAGS_REG))])])
12012
12013 (define_split
12014 [(set (match_operand:SWI48 0 "register_operand")
12015 (any_rotate:SWI48
12016 (match_operand:SWI48 1 "const_int_operand")
12017 (and:QI
12018 (match_operand:QI 2 "register_operand")
12019 (match_operand:QI 3 "const_int_operand"))))]
12020 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
12021 == GET_MODE_BITSIZE (<MODE>mode) - 1"
12022 [(set (match_dup 4) (match_dup 1))
12023 (set (match_dup 0)
12024 (any_rotate:SWI48 (match_dup 4) (match_dup 2)))]
12025 "operands[4] = gen_reg_rtx (<MODE>mode);")
12026
12027 ;; Implement rotation using two double-precision
12028 ;; shift instructions and a scratch register.
12029
12030 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
12031 [(set (match_operand:<DWI> 0 "register_operand" "=r")
12032 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
12033 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
12034 (clobber (reg:CC FLAGS_REG))
12035 (clobber (match_scratch:DWIH 3 "=&r"))]
12036 ""
12037 "#"
12038 "reload_completed"
12039 [(set (match_dup 3) (match_dup 4))
12040 (parallel
12041 [(set (match_dup 4)
12042 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
12043 (lshiftrt:DWIH (match_dup 5)
12044 (minus:QI (match_dup 6) (match_dup 2)))))
12045 (clobber (reg:CC FLAGS_REG))])
12046 (parallel
12047 [(set (match_dup 5)
12048 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
12049 (lshiftrt:DWIH (match_dup 3)
12050 (minus:QI (match_dup 6) (match_dup 2)))))
12051 (clobber (reg:CC FLAGS_REG))])]
12052 {
12053 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
12054
12055 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
12056 })
12057
12058 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
12059 [(set (match_operand:<DWI> 0 "register_operand" "=r")
12060 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
12061 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
12062 (clobber (reg:CC FLAGS_REG))
12063 (clobber (match_scratch:DWIH 3 "=&r"))]
12064 ""
12065 "#"
12066 "reload_completed"
12067 [(set (match_dup 3) (match_dup 4))
12068 (parallel
12069 [(set (match_dup 4)
12070 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
12071 (ashift:DWIH (match_dup 5)
12072 (minus:QI (match_dup 6) (match_dup 2)))))
12073 (clobber (reg:CC FLAGS_REG))])
12074 (parallel
12075 [(set (match_dup 5)
12076 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
12077 (ashift:DWIH (match_dup 3)
12078 (minus:QI (match_dup 6) (match_dup 2)))))
12079 (clobber (reg:CC FLAGS_REG))])]
12080 {
12081 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
12082
12083 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
12084 })
12085
12086 (define_mode_attr rorx_immediate_operand
12087 [(SI "const_0_to_31_operand")
12088 (DI "const_0_to_63_operand")])
12089
12090 (define_insn "*bmi2_rorx<mode>3_1"
12091 [(set (match_operand:SWI48 0 "register_operand" "=r")
12092 (rotatert:SWI48
12093 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12094 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
12095 "TARGET_BMI2"
12096 "rorx\t{%2, %1, %0|%0, %1, %2}"
12097 [(set_attr "type" "rotatex")
12098 (set_attr "mode" "<MODE>")])
12099
12100 (define_insn "*<insn><mode>3_1"
12101 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
12102 (any_rotate:SWI48
12103 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
12104 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
12105 (clobber (reg:CC FLAGS_REG))]
12106 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12107 {
12108 switch (get_attr_type (insn))
12109 {
12110 case TYPE_ROTATEX:
12111 return "#";
12112
12113 default:
12114 if (operands[2] == const1_rtx
12115 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12116 return "<rotate>{<imodesuffix>}\t%0";
12117 else
12118 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
12119 }
12120 }
12121 [(set_attr "isa" "*,bmi2")
12122 (set_attr "type" "rotate,rotatex")
12123 (set (attr "length_immediate")
12124 (if_then_else
12125 (and (eq_attr "type" "rotate")
12126 (and (match_operand 2 "const1_operand")
12127 (ior (match_test "TARGET_SHIFT1")
12128 (match_test "optimize_function_for_size_p (cfun)"))))
12129 (const_string "0")
12130 (const_string "*")))
12131 (set_attr "mode" "<MODE>")])
12132
12133 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
12134 (define_split
12135 [(set (match_operand:SWI48 0 "register_operand")
12136 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
12137 (match_operand:QI 2 "const_int_operand")))
12138 (clobber (reg:CC FLAGS_REG))]
12139 "TARGET_BMI2 && reload_completed"
12140 [(set (match_dup 0)
12141 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
12142 {
12143 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
12144
12145 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
12146 })
12147
12148 (define_split
12149 [(set (match_operand:SWI48 0 "register_operand")
12150 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
12151 (match_operand:QI 2 "const_int_operand")))
12152 (clobber (reg:CC FLAGS_REG))]
12153 "TARGET_BMI2 && reload_completed"
12154 [(set (match_dup 0)
12155 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
12156
12157 (define_insn "*bmi2_rorxsi3_1_zext"
12158 [(set (match_operand:DI 0 "register_operand" "=r")
12159 (zero_extend:DI
12160 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
12161 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
12162 "TARGET_64BIT && TARGET_BMI2"
12163 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
12164 [(set_attr "type" "rotatex")
12165 (set_attr "mode" "SI")])
12166
12167 (define_insn "*<insn>si3_1_zext"
12168 [(set (match_operand:DI 0 "register_operand" "=r,r")
12169 (zero_extend:DI
12170 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
12171 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
12172 (clobber (reg:CC FLAGS_REG))]
12173 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12174 {
12175 switch (get_attr_type (insn))
12176 {
12177 case TYPE_ROTATEX:
12178 return "#";
12179
12180 default:
12181 if (operands[2] == const1_rtx
12182 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12183 return "<rotate>{l}\t%k0";
12184 else
12185 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
12186 }
12187 }
12188 [(set_attr "isa" "*,bmi2")
12189 (set_attr "type" "rotate,rotatex")
12190 (set (attr "length_immediate")
12191 (if_then_else
12192 (and (eq_attr "type" "rotate")
12193 (and (match_operand 2 "const1_operand")
12194 (ior (match_test "TARGET_SHIFT1")
12195 (match_test "optimize_function_for_size_p (cfun)"))))
12196 (const_string "0")
12197 (const_string "*")))
12198 (set_attr "mode" "SI")])
12199
12200 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
12201 (define_split
12202 [(set (match_operand:DI 0 "register_operand")
12203 (zero_extend:DI
12204 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
12205 (match_operand:QI 2 "const_int_operand"))))
12206 (clobber (reg:CC FLAGS_REG))]
12207 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
12208 [(set (match_dup 0)
12209 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
12210 {
12211 int bitsize = GET_MODE_BITSIZE (SImode);
12212
12213 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
12214 })
12215
12216 (define_split
12217 [(set (match_operand:DI 0 "register_operand")
12218 (zero_extend:DI
12219 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
12220 (match_operand:QI 2 "const_int_operand"))))
12221 (clobber (reg:CC FLAGS_REG))]
12222 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
12223 [(set (match_dup 0)
12224 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
12225
12226 (define_insn "*<insn><mode>3_1"
12227 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
12228 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
12229 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
12230 (clobber (reg:CC FLAGS_REG))]
12231 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12232 {
12233 if (operands[2] == const1_rtx
12234 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12235 return "<rotate>{<imodesuffix>}\t%0";
12236 else
12237 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
12238 }
12239 [(set_attr "type" "rotate")
12240 (set (attr "length_immediate")
12241 (if_then_else
12242 (and (match_operand 2 "const1_operand")
12243 (ior (match_test "TARGET_SHIFT1")
12244 (match_test "optimize_function_for_size_p (cfun)")))
12245 (const_string "0")
12246 (const_string "*")))
12247 (set_attr "mode" "<MODE>")])
12248
12249 (define_insn "*<insn><mode>3_1_slp"
12250 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
12251 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0")
12252 (match_operand:QI 2 "nonmemory_operand" "cI")))
12253 (clobber (reg:CC FLAGS_REG))]
12254 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12255 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12256 && rtx_equal_p (operands[0], operands[1])"
12257 {
12258 if (operands[2] == const1_rtx
12259 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12260 return "<rotate>{<imodesuffix>}\t%0";
12261 else
12262 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
12263 }
12264 [(set_attr "type" "rotate")
12265 (set (attr "length_immediate")
12266 (if_then_else
12267 (and (match_operand 2 "const1_operand")
12268 (ior (match_test "TARGET_SHIFT1")
12269 (match_test "optimize_function_for_size_p (cfun)")))
12270 (const_string "0")
12271 (const_string "*")))
12272 (set_attr "mode" "<MODE>")])
12273
12274 (define_split
12275 [(set (match_operand:HI 0 "QIreg_operand")
12276 (any_rotate:HI (match_dup 0) (const_int 8)))
12277 (clobber (reg:CC FLAGS_REG))]
12278 "reload_completed
12279 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
12280 [(parallel [(set (strict_low_part (match_dup 0))
12281 (bswap:HI (match_dup 0)))
12282 (clobber (reg:CC FLAGS_REG))])])
12283 \f
12284 ;; Bit set / bit test instructions
12285
12286 ;; %%% bts, btr, btc
12287
12288 ;; These instructions are *slow* when applied to memory.
12289
12290 (define_code_attr btsc [(ior "bts") (xor "btc")])
12291
12292 (define_insn "*<btsc><mode>"
12293 [(set (match_operand:SWI48 0 "register_operand" "=r")
12294 (any_or:SWI48
12295 (ashift:SWI48 (const_int 1)
12296 (match_operand:QI 2 "register_operand" "r"))
12297 (match_operand:SWI48 1 "register_operand" "0")))
12298 (clobber (reg:CC FLAGS_REG))]
12299 "TARGET_USE_BT"
12300 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12301 [(set_attr "type" "alu1")
12302 (set_attr "prefix_0f" "1")
12303 (set_attr "znver1_decode" "double")
12304 (set_attr "mode" "<MODE>")])
12305
12306 ;; Avoid useless masking of count operand.
12307 (define_insn_and_split "*<btsc><mode>_mask"
12308 [(set (match_operand:SWI48 0 "register_operand")
12309 (any_or:SWI48
12310 (ashift:SWI48
12311 (const_int 1)
12312 (subreg:QI
12313 (and:SI
12314 (match_operand:SI 1 "register_operand")
12315 (match_operand:SI 2 "const_int_operand")) 0))
12316 (match_operand:SWI48 3 "register_operand")))
12317 (clobber (reg:CC FLAGS_REG))]
12318 "TARGET_USE_BT
12319 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12320 == GET_MODE_BITSIZE (<MODE>mode)-1
12321 && ix86_pre_reload_split ()"
12322 "#"
12323 "&& 1"
12324 [(parallel
12325 [(set (match_dup 0)
12326 (any_or:SWI48
12327 (ashift:SWI48 (const_int 1)
12328 (match_dup 1))
12329 (match_dup 3)))
12330 (clobber (reg:CC FLAGS_REG))])]
12331 "operands[1] = gen_lowpart (QImode, operands[1]);")
12332
12333 (define_insn_and_split "*<btsc><mode>_mask_1"
12334 [(set (match_operand:SWI48 0 "register_operand")
12335 (any_or:SWI48
12336 (ashift:SWI48
12337 (const_int 1)
12338 (and:QI
12339 (match_operand:QI 1 "register_operand")
12340 (match_operand:QI 2 "const_int_operand")))
12341 (match_operand:SWI48 3 "register_operand")))
12342 (clobber (reg:CC FLAGS_REG))]
12343 "TARGET_USE_BT
12344 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12345 == GET_MODE_BITSIZE (<MODE>mode)-1
12346 && ix86_pre_reload_split ()"
12347 "#"
12348 "&& 1"
12349 [(parallel
12350 [(set (match_dup 0)
12351 (any_or:SWI48
12352 (ashift:SWI48 (const_int 1)
12353 (match_dup 1))
12354 (match_dup 3)))
12355 (clobber (reg:CC FLAGS_REG))])])
12356
12357 (define_insn "*btr<mode>"
12358 [(set (match_operand:SWI48 0 "register_operand" "=r")
12359 (and:SWI48
12360 (rotate:SWI48 (const_int -2)
12361 (match_operand:QI 2 "register_operand" "r"))
12362 (match_operand:SWI48 1 "register_operand" "0")))
12363 (clobber (reg:CC FLAGS_REG))]
12364 "TARGET_USE_BT"
12365 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12366 [(set_attr "type" "alu1")
12367 (set_attr "prefix_0f" "1")
12368 (set_attr "znver1_decode" "double")
12369 (set_attr "mode" "<MODE>")])
12370
12371 ;; Avoid useless masking of count operand.
12372 (define_insn_and_split "*btr<mode>_mask"
12373 [(set (match_operand:SWI48 0 "register_operand")
12374 (and:SWI48
12375 (rotate:SWI48
12376 (const_int -2)
12377 (subreg:QI
12378 (and:SI
12379 (match_operand:SI 1 "register_operand")
12380 (match_operand:SI 2 "const_int_operand")) 0))
12381 (match_operand:SWI48 3 "register_operand")))
12382 (clobber (reg:CC FLAGS_REG))]
12383 "TARGET_USE_BT
12384 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12385 == GET_MODE_BITSIZE (<MODE>mode)-1
12386 && ix86_pre_reload_split ()"
12387 "#"
12388 "&& 1"
12389 [(parallel
12390 [(set (match_dup 0)
12391 (and:SWI48
12392 (rotate:SWI48 (const_int -2)
12393 (match_dup 1))
12394 (match_dup 3)))
12395 (clobber (reg:CC FLAGS_REG))])]
12396 "operands[1] = gen_lowpart (QImode, operands[1]);")
12397
12398 (define_insn_and_split "*btr<mode>_mask_1"
12399 [(set (match_operand:SWI48 0 "register_operand")
12400 (and:SWI48
12401 (rotate:SWI48
12402 (const_int -2)
12403 (and:QI
12404 (match_operand:QI 1 "register_operand")
12405 (match_operand:QI 2 "const_int_operand")))
12406 (match_operand:SWI48 3 "register_operand")))
12407 (clobber (reg:CC FLAGS_REG))]
12408 "TARGET_USE_BT
12409 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12410 == GET_MODE_BITSIZE (<MODE>mode)-1
12411 && ix86_pre_reload_split ()"
12412 "#"
12413 "&& 1"
12414 [(parallel
12415 [(set (match_dup 0)
12416 (and:SWI48
12417 (rotate:SWI48 (const_int -2)
12418 (match_dup 1))
12419 (match_dup 3)))
12420 (clobber (reg:CC FLAGS_REG))])])
12421
12422 (define_insn_and_split "*btr<mode>_1"
12423 [(set (match_operand:SWI12 0 "register_operand")
12424 (and:SWI12
12425 (subreg:SWI12
12426 (rotate:SI (const_int -2)
12427 (match_operand:QI 2 "register_operand")) 0)
12428 (match_operand:SWI12 1 "nonimmediate_operand")))
12429 (clobber (reg:CC FLAGS_REG))]
12430 "TARGET_USE_BT && ix86_pre_reload_split ()"
12431 "#"
12432 "&& 1"
12433 [(parallel
12434 [(set (match_dup 0)
12435 (and:SI (rotate:SI (const_int -2) (match_dup 2))
12436 (match_dup 1)))
12437 (clobber (reg:CC FLAGS_REG))])]
12438 {
12439 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
12440 if (MEM_P (operands[1]))
12441 operands[1] = force_reg (<MODE>mode, operands[1]);
12442 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
12443 })
12444
12445 (define_insn_and_split "*btr<mode>_2"
12446 [(set (zero_extract:HI
12447 (match_operand:SWI12 0 "nonimmediate_operand")
12448 (const_int 1)
12449 (zero_extend:SI (match_operand:QI 1 "register_operand")))
12450 (const_int 0))
12451 (clobber (reg:CC FLAGS_REG))]
12452 "TARGET_USE_BT && ix86_pre_reload_split ()"
12453 "#"
12454 "&& MEM_P (operands[0])"
12455 [(set (match_dup 2) (match_dup 0))
12456 (parallel
12457 [(set (match_dup 3)
12458 (and:SI (rotate:SI (const_int -2) (match_dup 1))
12459 (match_dup 4)))
12460 (clobber (reg:CC FLAGS_REG))])
12461 (set (match_dup 0) (match_dup 5))]
12462 {
12463 operands[2] = gen_reg_rtx (<MODE>mode);
12464 operands[5] = gen_reg_rtx (<MODE>mode);
12465 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
12466 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
12467 })
12468
12469 (define_split
12470 [(set (zero_extract:HI
12471 (match_operand:SWI12 0 "register_operand")
12472 (const_int 1)
12473 (zero_extend:SI (match_operand:QI 1 "register_operand")))
12474 (const_int 0))
12475 (clobber (reg:CC FLAGS_REG))]
12476 "TARGET_USE_BT && ix86_pre_reload_split ()"
12477 [(parallel
12478 [(set (match_dup 0)
12479 (and:SI (rotate:SI (const_int -2) (match_dup 1))
12480 (match_dup 2)))
12481 (clobber (reg:CC FLAGS_REG))])]
12482 {
12483 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
12484 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
12485 })
12486
12487 ;; These instructions are never faster than the corresponding
12488 ;; and/ior/xor operations when using immediate operand, so with
12489 ;; 32-bit there's no point. But in 64-bit, we can't hold the
12490 ;; relevant immediates within the instruction itself, so operating
12491 ;; on bits in the high 32-bits of a register becomes easier.
12492 ;;
12493 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12494 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12495 ;; negdf respectively, so they can never be disabled entirely.
12496
12497 (define_insn "*btsq_imm"
12498 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12499 (const_int 1)
12500 (match_operand 1 "const_0_to_63_operand" "J"))
12501 (const_int 1))
12502 (clobber (reg:CC FLAGS_REG))]
12503 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12504 "bts{q}\t{%1, %0|%0, %1}"
12505 [(set_attr "type" "alu1")
12506 (set_attr "prefix_0f" "1")
12507 (set_attr "znver1_decode" "double")
12508 (set_attr "mode" "DI")])
12509
12510 (define_insn "*btrq_imm"
12511 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12512 (const_int 1)
12513 (match_operand 1 "const_0_to_63_operand" "J"))
12514 (const_int 0))
12515 (clobber (reg:CC FLAGS_REG))]
12516 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12517 "btr{q}\t{%1, %0|%0, %1}"
12518 [(set_attr "type" "alu1")
12519 (set_attr "prefix_0f" "1")
12520 (set_attr "znver1_decode" "double")
12521 (set_attr "mode" "DI")])
12522
12523 (define_insn "*btcq_imm"
12524 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12525 (const_int 1)
12526 (match_operand 1 "const_0_to_63_operand" "J"))
12527 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12528 (clobber (reg:CC FLAGS_REG))]
12529 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12530 "btc{q}\t{%1, %0|%0, %1}"
12531 [(set_attr "type" "alu1")
12532 (set_attr "prefix_0f" "1")
12533 (set_attr "znver1_decode" "double")
12534 (set_attr "mode" "DI")])
12535
12536 ;; Allow Nocona to avoid these instructions if a register is available.
12537
12538 (define_peephole2
12539 [(match_scratch:DI 2 "r")
12540 (parallel [(set (zero_extract:DI
12541 (match_operand:DI 0 "nonimmediate_operand")
12542 (const_int 1)
12543 (match_operand 1 "const_0_to_63_operand"))
12544 (const_int 1))
12545 (clobber (reg:CC FLAGS_REG))])]
12546 "TARGET_64BIT && !TARGET_USE_BT"
12547 [(parallel [(set (match_dup 0)
12548 (ior:DI (match_dup 0) (match_dup 3)))
12549 (clobber (reg:CC FLAGS_REG))])]
12550 {
12551 int i = INTVAL (operands[1]);
12552
12553 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12554
12555 if (!x86_64_immediate_operand (operands[3], DImode))
12556 {
12557 emit_move_insn (operands[2], operands[3]);
12558 operands[3] = operands[2];
12559 }
12560 })
12561
12562 (define_peephole2
12563 [(match_scratch:DI 2 "r")
12564 (parallel [(set (zero_extract:DI
12565 (match_operand:DI 0 "nonimmediate_operand")
12566 (const_int 1)
12567 (match_operand 1 "const_0_to_63_operand"))
12568 (const_int 0))
12569 (clobber (reg:CC FLAGS_REG))])]
12570 "TARGET_64BIT && !TARGET_USE_BT"
12571 [(parallel [(set (match_dup 0)
12572 (and:DI (match_dup 0) (match_dup 3)))
12573 (clobber (reg:CC FLAGS_REG))])]
12574 {
12575 int i = INTVAL (operands[1]);
12576
12577 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
12578
12579 if (!x86_64_immediate_operand (operands[3], DImode))
12580 {
12581 emit_move_insn (operands[2], operands[3]);
12582 operands[3] = operands[2];
12583 }
12584 })
12585
12586 (define_peephole2
12587 [(match_scratch:DI 2 "r")
12588 (parallel [(set (zero_extract:DI
12589 (match_operand:DI 0 "nonimmediate_operand")
12590 (const_int 1)
12591 (match_operand 1 "const_0_to_63_operand"))
12592 (not:DI (zero_extract:DI
12593 (match_dup 0) (const_int 1) (match_dup 1))))
12594 (clobber (reg:CC FLAGS_REG))])]
12595 "TARGET_64BIT && !TARGET_USE_BT"
12596 [(parallel [(set (match_dup 0)
12597 (xor:DI (match_dup 0) (match_dup 3)))
12598 (clobber (reg:CC FLAGS_REG))])]
12599 {
12600 int i = INTVAL (operands[1]);
12601
12602 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12603
12604 if (!x86_64_immediate_operand (operands[3], DImode))
12605 {
12606 emit_move_insn (operands[2], operands[3]);
12607 operands[3] = operands[2];
12608 }
12609 })
12610
12611 ;; %%% bt
12612
12613 (define_insn "*bt<mode>"
12614 [(set (reg:CCC FLAGS_REG)
12615 (compare:CCC
12616 (zero_extract:SWI48
12617 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
12618 (const_int 1)
12619 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
12620 (const_int 0)))]
12621 ""
12622 {
12623 switch (get_attr_mode (insn))
12624 {
12625 case MODE_SI:
12626 return "bt{l}\t{%1, %k0|%k0, %1}";
12627
12628 case MODE_DI:
12629 return "bt{q}\t{%q1, %0|%0, %q1}";
12630
12631 default:
12632 gcc_unreachable ();
12633 }
12634 }
12635 [(set_attr "type" "alu1")
12636 (set_attr "prefix_0f" "1")
12637 (set (attr "mode")
12638 (if_then_else
12639 (and (match_test "CONST_INT_P (operands[1])")
12640 (match_test "INTVAL (operands[1]) < 32"))
12641 (const_string "SI")
12642 (const_string "<MODE>")))])
12643
12644 (define_insn_and_split "*jcc_bt<mode>"
12645 [(set (pc)
12646 (if_then_else (match_operator 0 "bt_comparison_operator"
12647 [(zero_extract:SWI48
12648 (match_operand:SWI48 1 "nonimmediate_operand")
12649 (const_int 1)
12650 (match_operand:SI 2 "nonmemory_operand"))
12651 (const_int 0)])
12652 (label_ref (match_operand 3))
12653 (pc)))
12654 (clobber (reg:CC FLAGS_REG))]
12655 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12656 && (CONST_INT_P (operands[2])
12657 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12658 && INTVAL (operands[2])
12659 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12660 : !memory_operand (operands[1], <MODE>mode))
12661 && ix86_pre_reload_split ()"
12662 "#"
12663 "&& 1"
12664 [(set (reg:CCC FLAGS_REG)
12665 (compare:CCC
12666 (zero_extract:SWI48
12667 (match_dup 1)
12668 (const_int 1)
12669 (match_dup 2))
12670 (const_int 0)))
12671 (set (pc)
12672 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12673 (label_ref (match_dup 3))
12674 (pc)))]
12675 {
12676 operands[0] = shallow_copy_rtx (operands[0]);
12677 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12678 })
12679
12680 (define_insn_and_split "*jcc_bt<mode>_1"
12681 [(set (pc)
12682 (if_then_else (match_operator 0 "bt_comparison_operator"
12683 [(zero_extract:SWI48
12684 (match_operand:SWI48 1 "register_operand")
12685 (const_int 1)
12686 (zero_extend:SI
12687 (match_operand:QI 2 "register_operand")))
12688 (const_int 0)])
12689 (label_ref (match_operand 3))
12690 (pc)))
12691 (clobber (reg:CC FLAGS_REG))]
12692 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12693 && ix86_pre_reload_split ()"
12694 "#"
12695 "&& 1"
12696 [(set (reg:CCC FLAGS_REG)
12697 (compare:CCC
12698 (zero_extract:SWI48
12699 (match_dup 1)
12700 (const_int 1)
12701 (match_dup 2))
12702 (const_int 0)))
12703 (set (pc)
12704 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12705 (label_ref (match_dup 3))
12706 (pc)))]
12707 {
12708 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12709 operands[0] = shallow_copy_rtx (operands[0]);
12710 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12711 })
12712
12713 ;; Avoid useless masking of bit offset operand.
12714 (define_insn_and_split "*jcc_bt<mode>_mask"
12715 [(set (pc)
12716 (if_then_else (match_operator 0 "bt_comparison_operator"
12717 [(zero_extract:SWI48
12718 (match_operand:SWI48 1 "register_operand")
12719 (const_int 1)
12720 (and:SI
12721 (match_operand:SI 2 "register_operand")
12722 (match_operand 3 "const_int_operand")))])
12723 (label_ref (match_operand 4))
12724 (pc)))
12725 (clobber (reg:CC FLAGS_REG))]
12726 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12727 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12728 == GET_MODE_BITSIZE (<MODE>mode)-1
12729 && ix86_pre_reload_split ()"
12730 "#"
12731 "&& 1"
12732 [(set (reg:CCC FLAGS_REG)
12733 (compare:CCC
12734 (zero_extract:SWI48
12735 (match_dup 1)
12736 (const_int 1)
12737 (match_dup 2))
12738 (const_int 0)))
12739 (set (pc)
12740 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12741 (label_ref (match_dup 4))
12742 (pc)))]
12743 {
12744 operands[0] = shallow_copy_rtx (operands[0]);
12745 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12746 })
12747 \f
12748 ;; Store-flag instructions.
12749
12750 (define_split
12751 [(set (match_operand:QI 0 "nonimmediate_operand")
12752 (match_operator:QI 1 "add_comparison_operator"
12753 [(not:SWI (match_operand:SWI 2 "register_operand"))
12754 (match_operand:SWI 3 "nonimmediate_operand")]))]
12755 ""
12756 [(set (reg:CCC FLAGS_REG)
12757 (compare:CCC
12758 (plus:SWI (match_dup 2) (match_dup 3))
12759 (match_dup 2)))
12760 (set (match_dup 0)
12761 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
12762
12763 (define_split
12764 [(set (match_operand:QI 0 "nonimmediate_operand")
12765 (match_operator:QI 1 "shr_comparison_operator"
12766 [(match_operand:DI 2 "register_operand")
12767 (match_operand 3 "const_int_operand")]))]
12768 "TARGET_64BIT
12769 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
12770 [(set (reg:CCZ FLAGS_REG)
12771 (compare:CCZ
12772 (lshiftrt:DI (match_dup 2) (match_dup 4))
12773 (const_int 0)))
12774 (set (match_dup 0)
12775 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
12776 {
12777 enum rtx_code new_code;
12778
12779 operands[1] = shallow_copy_rtx (operands[1]);
12780 switch (GET_CODE (operands[1]))
12781 {
12782 case GTU: new_code = NE; break;
12783 case LEU: new_code = EQ; break;
12784 default: gcc_unreachable ();
12785 }
12786 PUT_CODE (operands[1], new_code);
12787
12788 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
12789 })
12790
12791 ;; For all sCOND expanders, also expand the compare or test insn that
12792 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12793
12794 (define_insn_and_split "*setcc_di_1"
12795 [(set (match_operand:DI 0 "register_operand" "=q")
12796 (match_operator:DI 1 "ix86_comparison_operator"
12797 [(reg FLAGS_REG) (const_int 0)]))]
12798 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12799 "#"
12800 "&& reload_completed"
12801 [(set (match_dup 2) (match_dup 1))
12802 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12803 {
12804 operands[1] = shallow_copy_rtx (operands[1]);
12805 PUT_MODE (operands[1], QImode);
12806 operands[2] = gen_lowpart (QImode, operands[0]);
12807 })
12808
12809 (define_insn_and_split "*setcc_<mode>_1_and"
12810 [(set (match_operand:SWI24 0 "register_operand" "=q")
12811 (match_operator:SWI24 1 "ix86_comparison_operator"
12812 [(reg FLAGS_REG) (const_int 0)]))
12813 (clobber (reg:CC FLAGS_REG))]
12814 "!TARGET_PARTIAL_REG_STALL
12815 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12816 "#"
12817 "&& reload_completed"
12818 [(set (match_dup 2) (match_dup 1))
12819 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
12820 (clobber (reg:CC FLAGS_REG))])]
12821 {
12822 operands[1] = shallow_copy_rtx (operands[1]);
12823 PUT_MODE (operands[1], QImode);
12824 operands[2] = gen_lowpart (QImode, operands[0]);
12825 })
12826
12827 (define_insn_and_split "*setcc_<mode>_1_movzbl"
12828 [(set (match_operand:SWI24 0 "register_operand" "=q")
12829 (match_operator:SWI24 1 "ix86_comparison_operator"
12830 [(reg FLAGS_REG) (const_int 0)]))]
12831 "!TARGET_PARTIAL_REG_STALL
12832 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12833 "#"
12834 "&& reload_completed"
12835 [(set (match_dup 2) (match_dup 1))
12836 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
12837 {
12838 operands[1] = shallow_copy_rtx (operands[1]);
12839 PUT_MODE (operands[1], QImode);
12840 operands[2] = gen_lowpart (QImode, operands[0]);
12841 })
12842
12843 (define_insn "*setcc_qi"
12844 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12845 (match_operator:QI 1 "ix86_comparison_operator"
12846 [(reg FLAGS_REG) (const_int 0)]))]
12847 ""
12848 "set%C1\t%0"
12849 [(set_attr "type" "setcc")
12850 (set_attr "mode" "QI")])
12851
12852 (define_insn "*setcc_qi_slp"
12853 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
12854 (match_operator:QI 1 "ix86_comparison_operator"
12855 [(reg FLAGS_REG) (const_int 0)]))]
12856 ""
12857 "set%C1\t%0"
12858 [(set_attr "type" "setcc")
12859 (set_attr "mode" "QI")])
12860
12861 ;; In general it is not safe to assume too much about CCmode registers,
12862 ;; so simplify-rtx stops when it sees a second one. Under certain
12863 ;; conditions this is safe on x86, so help combine not create
12864 ;;
12865 ;; seta %al
12866 ;; testb %al, %al
12867 ;; sete %al
12868
12869 (define_split
12870 [(set (match_operand:QI 0 "nonimmediate_operand")
12871 (ne:QI (match_operator 1 "ix86_comparison_operator"
12872 [(reg FLAGS_REG) (const_int 0)])
12873 (const_int 0)))]
12874 ""
12875 [(set (match_dup 0) (match_dup 1))]
12876 {
12877 operands[1] = shallow_copy_rtx (operands[1]);
12878 PUT_MODE (operands[1], QImode);
12879 })
12880
12881 (define_split
12882 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
12883 (ne:QI (match_operator 1 "ix86_comparison_operator"
12884 [(reg FLAGS_REG) (const_int 0)])
12885 (const_int 0)))]
12886 ""
12887 [(set (match_dup 0) (match_dup 1))]
12888 {
12889 operands[1] = shallow_copy_rtx (operands[1]);
12890 PUT_MODE (operands[1], QImode);
12891 })
12892
12893 (define_split
12894 [(set (match_operand:QI 0 "nonimmediate_operand")
12895 (eq:QI (match_operator 1 "ix86_comparison_operator"
12896 [(reg FLAGS_REG) (const_int 0)])
12897 (const_int 0)))]
12898 ""
12899 [(set (match_dup 0) (match_dup 1))]
12900 {
12901 operands[1] = shallow_copy_rtx (operands[1]);
12902 PUT_MODE (operands[1], QImode);
12903 PUT_CODE (operands[1],
12904 ix86_reverse_condition (GET_CODE (operands[1]),
12905 GET_MODE (XEXP (operands[1], 0))));
12906
12907 /* Make sure that (a) the CCmode we have for the flags is strong
12908 enough for the reversed compare or (b) we have a valid FP compare. */
12909 if (! ix86_comparison_operator (operands[1], VOIDmode))
12910 FAIL;
12911 })
12912
12913 (define_split
12914 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
12915 (eq:QI (match_operator 1 "ix86_comparison_operator"
12916 [(reg FLAGS_REG) (const_int 0)])
12917 (const_int 0)))]
12918 ""
12919 [(set (match_dup 0) (match_dup 1))]
12920 {
12921 operands[1] = shallow_copy_rtx (operands[1]);
12922 PUT_MODE (operands[1], QImode);
12923 PUT_CODE (operands[1],
12924 ix86_reverse_condition (GET_CODE (operands[1]),
12925 GET_MODE (XEXP (operands[1], 0))));
12926
12927 /* Make sure that (a) the CCmode we have for the flags is strong
12928 enough for the reversed compare or (b) we have a valid FP compare. */
12929 if (! ix86_comparison_operator (operands[1], VOIDmode))
12930 FAIL;
12931 })
12932
12933 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12934 ;; subsequent logical operations are used to imitate conditional moves.
12935 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12936 ;; it directly.
12937
12938 (define_insn "setcc_<mode>_sse"
12939 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12940 (match_operator:MODEF 3 "sse_comparison_operator"
12941 [(match_operand:MODEF 1 "register_operand" "0,x")
12942 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12943 "SSE_FLOAT_MODE_P (<MODE>mode)"
12944 "@
12945 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12946 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12947 [(set_attr "isa" "noavx,avx")
12948 (set_attr "type" "ssecmp")
12949 (set_attr "length_immediate" "1")
12950 (set_attr "prefix" "orig,vex")
12951 (set_attr "mode" "<MODE>")])
12952 \f
12953 ;; Basic conditional jump instructions.
12954
12955 (define_split
12956 [(set (pc)
12957 (if_then_else
12958 (match_operator 1 "add_comparison_operator"
12959 [(not:SWI (match_operand:SWI 2 "register_operand"))
12960 (match_operand:SWI 3 "nonimmediate_operand")])
12961 (label_ref (match_operand 0))
12962 (pc)))]
12963 ""
12964 [(set (reg:CCC FLAGS_REG)
12965 (compare:CCC
12966 (plus:SWI (match_dup 2) (match_dup 3))
12967 (match_dup 2)))
12968 (set (pc)
12969 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
12970 (label_ref (match_operand 0))
12971 (pc)))])
12972
12973 (define_split
12974 [(set (pc)
12975 (if_then_else
12976 (match_operator 1 "shr_comparison_operator"
12977 [(match_operand:DI 2 "register_operand")
12978 (match_operand 3 "const_int_operand")])
12979 (label_ref (match_operand 0))
12980 (pc)))]
12981 "TARGET_64BIT
12982 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
12983 [(set (reg:CCZ FLAGS_REG)
12984 (compare:CCZ
12985 (lshiftrt:DI (match_dup 2) (match_dup 4))
12986 (const_int 0)))
12987 (set (pc)
12988 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
12989 (label_ref (match_operand 0))
12990 (pc)))]
12991 {
12992 enum rtx_code new_code;
12993
12994 operands[1] = shallow_copy_rtx (operands[1]);
12995 switch (GET_CODE (operands[1]))
12996 {
12997 case GTU: new_code = NE; break;
12998 case LEU: new_code = EQ; break;
12999 default: gcc_unreachable ();
13000 }
13001 PUT_CODE (operands[1], new_code);
13002
13003 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
13004 })
13005
13006 ;; We ignore the overflow flag for signed branch instructions.
13007
13008 (define_insn "*jcc"
13009 [(set (pc)
13010 (if_then_else (match_operator 1 "ix86_comparison_operator"
13011 [(reg FLAGS_REG) (const_int 0)])
13012 (label_ref (match_operand 0))
13013 (pc)))]
13014 ""
13015 "%!%+j%C1\t%l0"
13016 [(set_attr "type" "ibr")
13017 (set_attr "modrm" "0")
13018 (set (attr "length")
13019 (if_then_else
13020 (and (ge (minus (match_dup 0) (pc))
13021 (const_int -126))
13022 (lt (minus (match_dup 0) (pc))
13023 (const_int 128)))
13024 (const_int 2)
13025 (const_int 6)))])
13026
13027 ;; In general it is not safe to assume too much about CCmode registers,
13028 ;; so simplify-rtx stops when it sees a second one. Under certain
13029 ;; conditions this is safe on x86, so help combine not create
13030 ;;
13031 ;; seta %al
13032 ;; testb %al, %al
13033 ;; je Lfoo
13034
13035 (define_split
13036 [(set (pc)
13037 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13038 [(reg FLAGS_REG) (const_int 0)])
13039 (const_int 0))
13040 (label_ref (match_operand 1))
13041 (pc)))]
13042 ""
13043 [(set (pc)
13044 (if_then_else (match_dup 0)
13045 (label_ref (match_dup 1))
13046 (pc)))]
13047 {
13048 operands[0] = shallow_copy_rtx (operands[0]);
13049 PUT_MODE (operands[0], VOIDmode);
13050 })
13051
13052 (define_split
13053 [(set (pc)
13054 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13055 [(reg FLAGS_REG) (const_int 0)])
13056 (const_int 0))
13057 (label_ref (match_operand 1))
13058 (pc)))]
13059 ""
13060 [(set (pc)
13061 (if_then_else (match_dup 0)
13062 (label_ref (match_dup 1))
13063 (pc)))]
13064 {
13065 operands[0] = shallow_copy_rtx (operands[0]);
13066 PUT_MODE (operands[0], VOIDmode);
13067 PUT_CODE (operands[0],
13068 ix86_reverse_condition (GET_CODE (operands[0]),
13069 GET_MODE (XEXP (operands[0], 0))));
13070
13071 /* Make sure that (a) the CCmode we have for the flags is strong
13072 enough for the reversed compare or (b) we have a valid FP compare. */
13073 if (! ix86_comparison_operator (operands[0], VOIDmode))
13074 FAIL;
13075 })
13076 \f
13077 ;; Unconditional and other jump instructions
13078
13079 (define_insn "jump"
13080 [(set (pc)
13081 (label_ref (match_operand 0)))]
13082 ""
13083 "%!jmp\t%l0"
13084 [(set_attr "type" "ibr")
13085 (set_attr "modrm" "0")
13086 (set (attr "length")
13087 (if_then_else
13088 (and (ge (minus (match_dup 0) (pc))
13089 (const_int -126))
13090 (lt (minus (match_dup 0) (pc))
13091 (const_int 128)))
13092 (const_int 2)
13093 (const_int 5)))])
13094
13095 (define_expand "indirect_jump"
13096 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
13097 ""
13098 {
13099 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
13100 operands[0] = convert_memory_address (word_mode, operands[0]);
13101 cfun->machine->has_local_indirect_jump = true;
13102 })
13103
13104 (define_insn "*indirect_jump"
13105 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
13106 ""
13107 "* return ix86_output_indirect_jmp (operands[0]);"
13108 [(set (attr "type")
13109 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13110 != indirect_branch_keep)")
13111 (const_string "multi")
13112 (const_string "ibr")))
13113 (set_attr "length_immediate" "0")])
13114
13115 (define_expand "tablejump"
13116 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
13117 (use (label_ref (match_operand 1)))])]
13118 ""
13119 {
13120 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13121 relative. Convert the relative address to an absolute address. */
13122 if (flag_pic)
13123 {
13124 rtx op0, op1;
13125 enum rtx_code code;
13126
13127 /* We can't use @GOTOFF for text labels on VxWorks;
13128 see gotoff_operand. */
13129 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
13130 {
13131 code = PLUS;
13132 op0 = operands[0];
13133 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13134 }
13135 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13136 {
13137 code = PLUS;
13138 op0 = operands[0];
13139 op1 = pic_offset_table_rtx;
13140 }
13141 else
13142 {
13143 code = MINUS;
13144 op0 = pic_offset_table_rtx;
13145 op1 = operands[0];
13146 }
13147
13148 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13149 OPTAB_DIRECT);
13150 }
13151
13152 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
13153 operands[0] = convert_memory_address (word_mode, operands[0]);
13154 cfun->machine->has_local_indirect_jump = true;
13155 })
13156
13157 (define_insn "*tablejump_1"
13158 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
13159 (use (label_ref (match_operand 1)))]
13160 ""
13161 "* return ix86_output_indirect_jmp (operands[0]);"
13162 [(set (attr "type")
13163 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13164 != indirect_branch_keep)")
13165 (const_string "multi")
13166 (const_string "ibr")))
13167 (set_attr "length_immediate" "0")])
13168 \f
13169 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13170
13171 (define_peephole2
13172 [(set (reg FLAGS_REG) (match_operand 0))
13173 (set (match_operand:QI 1 "register_operand")
13174 (match_operator:QI 2 "ix86_comparison_operator"
13175 [(reg FLAGS_REG) (const_int 0)]))
13176 (set (match_operand 3 "any_QIreg_operand")
13177 (zero_extend (match_dup 1)))]
13178 "(peep2_reg_dead_p (3, operands[1])
13179 || operands_match_p (operands[1], operands[3]))
13180 && ! reg_overlap_mentioned_p (operands[3], operands[0])
13181 && peep2_regno_dead_p (0, FLAGS_REG)"
13182 [(set (match_dup 4) (match_dup 0))
13183 (set (strict_low_part (match_dup 5))
13184 (match_dup 2))]
13185 {
13186 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13187 operands[5] = gen_lowpart (QImode, operands[3]);
13188 ix86_expand_clear (operands[3]);
13189 })
13190
13191 (define_peephole2
13192 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
13193 (match_operand 4)])
13194 (set (match_operand:QI 1 "register_operand")
13195 (match_operator:QI 2 "ix86_comparison_operator"
13196 [(reg FLAGS_REG) (const_int 0)]))
13197 (set (match_operand 3 "any_QIreg_operand")
13198 (zero_extend (match_dup 1)))]
13199 "(peep2_reg_dead_p (3, operands[1])
13200 || operands_match_p (operands[1], operands[3]))
13201 && ! reg_overlap_mentioned_p (operands[3], operands[0])
13202 && ! reg_overlap_mentioned_p (operands[3], operands[4])
13203 && ! reg_set_p (operands[3], operands[4])
13204 && peep2_regno_dead_p (0, FLAGS_REG)"
13205 [(parallel [(set (match_dup 5) (match_dup 0))
13206 (match_dup 4)])
13207 (set (strict_low_part (match_dup 6))
13208 (match_dup 2))]
13209 {
13210 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13211 operands[6] = gen_lowpart (QImode, operands[3]);
13212 ix86_expand_clear (operands[3]);
13213 })
13214
13215 (define_peephole2
13216 [(set (reg FLAGS_REG) (match_operand 0))
13217 (parallel [(set (reg FLAGS_REG) (match_operand 1))
13218 (match_operand 5)])
13219 (set (match_operand:QI 2 "register_operand")
13220 (match_operator:QI 3 "ix86_comparison_operator"
13221 [(reg FLAGS_REG) (const_int 0)]))
13222 (set (match_operand 4 "any_QIreg_operand")
13223 (zero_extend (match_dup 2)))]
13224 "(peep2_reg_dead_p (4, operands[2])
13225 || operands_match_p (operands[2], operands[4]))
13226 && ! reg_overlap_mentioned_p (operands[4], operands[0])
13227 && ! reg_overlap_mentioned_p (operands[4], operands[1])
13228 && ! reg_overlap_mentioned_p (operands[4], operands[5])
13229 && ! reg_set_p (operands[4], operands[5])
13230 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
13231 && peep2_regno_dead_p (0, FLAGS_REG)"
13232 [(set (match_dup 6) (match_dup 0))
13233 (parallel [(set (match_dup 7) (match_dup 1))
13234 (match_dup 5)])
13235 (set (strict_low_part (match_dup 8))
13236 (match_dup 3))]
13237 {
13238 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13239 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
13240 operands[8] = gen_lowpart (QImode, operands[4]);
13241 ix86_expand_clear (operands[4]);
13242 })
13243
13244 ;; Similar, but match zero extend with andsi3.
13245
13246 (define_peephole2
13247 [(set (reg FLAGS_REG) (match_operand 0))
13248 (set (match_operand:QI 1 "register_operand")
13249 (match_operator:QI 2 "ix86_comparison_operator"
13250 [(reg FLAGS_REG) (const_int 0)]))
13251 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
13252 (and:SI (match_dup 3) (const_int 255)))
13253 (clobber (reg:CC FLAGS_REG))])]
13254 "REGNO (operands[1]) == REGNO (operands[3])
13255 && ! reg_overlap_mentioned_p (operands[3], operands[0])
13256 && peep2_regno_dead_p (0, FLAGS_REG)"
13257 [(set (match_dup 4) (match_dup 0))
13258 (set (strict_low_part (match_dup 5))
13259 (match_dup 2))]
13260 {
13261 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13262 operands[5] = gen_lowpart (QImode, operands[3]);
13263 ix86_expand_clear (operands[3]);
13264 })
13265
13266 (define_peephole2
13267 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
13268 (match_operand 4)])
13269 (set (match_operand:QI 1 "register_operand")
13270 (match_operator:QI 2 "ix86_comparison_operator"
13271 [(reg FLAGS_REG) (const_int 0)]))
13272 (parallel [(set (match_operand 3 "any_QIreg_operand")
13273 (zero_extend (match_dup 1)))
13274 (clobber (reg:CC FLAGS_REG))])]
13275 "(peep2_reg_dead_p (3, operands[1])
13276 || operands_match_p (operands[1], operands[3]))
13277 && ! reg_overlap_mentioned_p (operands[3], operands[0])
13278 && ! reg_overlap_mentioned_p (operands[3], operands[4])
13279 && ! reg_set_p (operands[3], operands[4])
13280 && peep2_regno_dead_p (0, FLAGS_REG)"
13281 [(parallel [(set (match_dup 5) (match_dup 0))
13282 (match_dup 4)])
13283 (set (strict_low_part (match_dup 6))
13284 (match_dup 2))]
13285 {
13286 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13287 operands[6] = gen_lowpart (QImode, operands[3]);
13288 ix86_expand_clear (operands[3]);
13289 })
13290
13291 (define_peephole2
13292 [(set (reg FLAGS_REG) (match_operand 0))
13293 (parallel [(set (reg FLAGS_REG) (match_operand 1))
13294 (match_operand 5)])
13295 (set (match_operand:QI 2 "register_operand")
13296 (match_operator:QI 3 "ix86_comparison_operator"
13297 [(reg FLAGS_REG) (const_int 0)]))
13298 (parallel [(set (match_operand 4 "any_QIreg_operand")
13299 (zero_extend (match_dup 2)))
13300 (clobber (reg:CC FLAGS_REG))])]
13301 "(peep2_reg_dead_p (4, operands[2])
13302 || operands_match_p (operands[2], operands[4]))
13303 && ! reg_overlap_mentioned_p (operands[4], operands[0])
13304 && ! reg_overlap_mentioned_p (operands[4], operands[1])
13305 && ! reg_overlap_mentioned_p (operands[4], operands[5])
13306 && ! reg_set_p (operands[4], operands[5])
13307 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
13308 && peep2_regno_dead_p (0, FLAGS_REG)"
13309 [(set (match_dup 6) (match_dup 0))
13310 (parallel [(set (match_dup 7) (match_dup 1))
13311 (match_dup 5)])
13312 (set (strict_low_part (match_dup 8))
13313 (match_dup 3))]
13314 {
13315 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13316 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
13317 operands[8] = gen_lowpart (QImode, operands[4]);
13318 ix86_expand_clear (operands[4]);
13319 })
13320 \f
13321 ;; Call instructions.
13322
13323 ;; The predicates normally associated with named expanders are not properly
13324 ;; checked for calls. This is a bug in the generic code, but it isn't that
13325 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13326
13327 ;; P6 processors will jump to the address after the decrement when %esp
13328 ;; is used as a call operand, so they will execute return address as a code.
13329 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13330
13331 ;; Register constraint for call instruction.
13332 (define_mode_attr c [(SI "l") (DI "r")])
13333
13334 ;; Call subroutine returning no value.
13335
13336 (define_expand "call"
13337 [(call (match_operand:QI 0)
13338 (match_operand 1))
13339 (use (match_operand 2))]
13340 ""
13341 {
13342 ix86_expand_call (NULL, operands[0], operands[1],
13343 operands[2], NULL, false);
13344 DONE;
13345 })
13346
13347 (define_expand "sibcall"
13348 [(call (match_operand:QI 0)
13349 (match_operand 1))
13350 (use (match_operand 2))]
13351 ""
13352 {
13353 ix86_expand_call (NULL, operands[0], operands[1],
13354 operands[2], NULL, true);
13355 DONE;
13356 })
13357
13358 (define_insn "*call"
13359 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
13360 (match_operand 1))]
13361 "!SIBLING_CALL_P (insn)"
13362 "* return ix86_output_call_insn (insn, operands[0]);"
13363 [(set_attr "type" "call")])
13364
13365 ;; This covers both call and sibcall since only GOT slot is allowed.
13366 (define_insn "*call_got_x32"
13367 [(call (mem:QI (zero_extend:DI
13368 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
13369 (match_operand 1))]
13370 "TARGET_X32"
13371 {
13372 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
13373 return ix86_output_call_insn (insn, fnaddr);
13374 }
13375 [(set_attr "type" "call")])
13376
13377 ;; Since sibcall never returns, we can only use call-clobbered register
13378 ;; as GOT base.
13379 (define_insn "*sibcall_GOT_32"
13380 [(call (mem:QI
13381 (mem:SI (plus:SI
13382 (match_operand:SI 0 "register_no_elim_operand" "U")
13383 (match_operand:SI 1 "GOT32_symbol_operand"))))
13384 (match_operand 2))]
13385 "!TARGET_MACHO
13386 && !TARGET_64BIT
13387 && !TARGET_INDIRECT_BRANCH_REGISTER
13388 && SIBLING_CALL_P (insn)"
13389 {
13390 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
13391 fnaddr = gen_const_mem (SImode, fnaddr);
13392 return ix86_output_call_insn (insn, fnaddr);
13393 }
13394 [(set_attr "type" "call")])
13395
13396 (define_insn "*sibcall"
13397 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
13398 (match_operand 1))]
13399 "SIBLING_CALL_P (insn)"
13400 "* return ix86_output_call_insn (insn, operands[0]);"
13401 [(set_attr "type" "call")])
13402
13403 (define_insn "*sibcall_memory"
13404 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
13405 (match_operand 1))
13406 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13407 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13408 "* return ix86_output_call_insn (insn, operands[0]);"
13409 [(set_attr "type" "call")])
13410
13411 (define_peephole2
13412 [(set (match_operand:W 0 "register_operand")
13413 (match_operand:W 1 "memory_operand"))
13414 (call (mem:QI (match_dup 0))
13415 (match_operand 3))]
13416 "!TARGET_X32
13417 && !TARGET_INDIRECT_BRANCH_REGISTER
13418 && SIBLING_CALL_P (peep2_next_insn (1))
13419 && !reg_mentioned_p (operands[0],
13420 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13421 [(parallel [(call (mem:QI (match_dup 1))
13422 (match_dup 3))
13423 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13424
13425 (define_peephole2
13426 [(set (match_operand:W 0 "register_operand")
13427 (match_operand:W 1 "memory_operand"))
13428 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13429 (call (mem:QI (match_dup 0))
13430 (match_operand 3))]
13431 "!TARGET_X32
13432 && !TARGET_INDIRECT_BRANCH_REGISTER
13433 && SIBLING_CALL_P (peep2_next_insn (2))
13434 && !reg_mentioned_p (operands[0],
13435 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13436 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13437 (parallel [(call (mem:QI (match_dup 1))
13438 (match_dup 3))
13439 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13440
13441 (define_expand "call_pop"
13442 [(parallel [(call (match_operand:QI 0)
13443 (match_operand:SI 1))
13444 (set (reg:SI SP_REG)
13445 (plus:SI (reg:SI SP_REG)
13446 (match_operand:SI 3)))])]
13447 "!TARGET_64BIT"
13448 {
13449 ix86_expand_call (NULL, operands[0], operands[1],
13450 operands[2], operands[3], false);
13451 DONE;
13452 })
13453
13454 (define_insn "*call_pop"
13455 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
13456 (match_operand 1))
13457 (set (reg:SI SP_REG)
13458 (plus:SI (reg:SI SP_REG)
13459 (match_operand:SI 2 "immediate_operand" "i")))]
13460 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13461 "* return ix86_output_call_insn (insn, operands[0]);"
13462 [(set_attr "type" "call")])
13463
13464 (define_insn "*sibcall_pop"
13465 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
13466 (match_operand 1))
13467 (set (reg:SI SP_REG)
13468 (plus:SI (reg:SI SP_REG)
13469 (match_operand:SI 2 "immediate_operand" "i")))]
13470 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13471 "* return ix86_output_call_insn (insn, operands[0]);"
13472 [(set_attr "type" "call")])
13473
13474 (define_insn "*sibcall_pop_memory"
13475 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
13476 (match_operand 1))
13477 (set (reg:SI SP_REG)
13478 (plus:SI (reg:SI SP_REG)
13479 (match_operand:SI 2 "immediate_operand" "i")))
13480 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13481 "!TARGET_64BIT"
13482 "* return ix86_output_call_insn (insn, operands[0]);"
13483 [(set_attr "type" "call")])
13484
13485 (define_peephole2
13486 [(set (match_operand:SI 0 "register_operand")
13487 (match_operand:SI 1 "memory_operand"))
13488 (parallel [(call (mem:QI (match_dup 0))
13489 (match_operand 3))
13490 (set (reg:SI SP_REG)
13491 (plus:SI (reg:SI SP_REG)
13492 (match_operand:SI 4 "immediate_operand")))])]
13493 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13494 && !reg_mentioned_p (operands[0],
13495 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13496 [(parallel [(call (mem:QI (match_dup 1))
13497 (match_dup 3))
13498 (set (reg:SI SP_REG)
13499 (plus:SI (reg:SI SP_REG)
13500 (match_dup 4)))
13501 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13502
13503 (define_peephole2
13504 [(set (match_operand:SI 0 "register_operand")
13505 (match_operand:SI 1 "memory_operand"))
13506 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13507 (parallel [(call (mem:QI (match_dup 0))
13508 (match_operand 3))
13509 (set (reg:SI SP_REG)
13510 (plus:SI (reg:SI SP_REG)
13511 (match_operand:SI 4 "immediate_operand")))])]
13512 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13513 && !reg_mentioned_p (operands[0],
13514 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13515 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13516 (parallel [(call (mem:QI (match_dup 1))
13517 (match_dup 3))
13518 (set (reg:SI SP_REG)
13519 (plus:SI (reg:SI SP_REG)
13520 (match_dup 4)))
13521 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13522
13523 ;; Combining simple memory jump instruction
13524
13525 (define_peephole2
13526 [(set (match_operand:W 0 "register_operand")
13527 (match_operand:W 1 "memory_operand"))
13528 (set (pc) (match_dup 0))]
13529 "!TARGET_X32
13530 && !TARGET_INDIRECT_BRANCH_REGISTER
13531 && peep2_reg_dead_p (2, operands[0])"
13532 [(set (pc) (match_dup 1))])
13533
13534 ;; Call subroutine, returning value in operand 0
13535
13536 (define_expand "call_value"
13537 [(set (match_operand 0)
13538 (call (match_operand:QI 1)
13539 (match_operand 2)))
13540 (use (match_operand 3))]
13541 ""
13542 {
13543 ix86_expand_call (operands[0], operands[1], operands[2],
13544 operands[3], NULL, false);
13545 DONE;
13546 })
13547
13548 (define_expand "sibcall_value"
13549 [(set (match_operand 0)
13550 (call (match_operand:QI 1)
13551 (match_operand 2)))
13552 (use (match_operand 3))]
13553 ""
13554 {
13555 ix86_expand_call (operands[0], operands[1], operands[2],
13556 operands[3], NULL, true);
13557 DONE;
13558 })
13559
13560 (define_insn "*call_value"
13561 [(set (match_operand 0)
13562 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
13563 (match_operand 2)))]
13564 "!SIBLING_CALL_P (insn)"
13565 "* return ix86_output_call_insn (insn, operands[1]);"
13566 [(set_attr "type" "callv")])
13567
13568 ;; This covers both call and sibcall since only GOT slot is allowed.
13569 (define_insn "*call_value_got_x32"
13570 [(set (match_operand 0)
13571 (call (mem:QI
13572 (zero_extend:DI
13573 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
13574 (match_operand 2)))]
13575 "TARGET_X32"
13576 {
13577 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
13578 return ix86_output_call_insn (insn, fnaddr);
13579 }
13580 [(set_attr "type" "callv")])
13581
13582 ;; Since sibcall never returns, we can only use call-clobbered register
13583 ;; as GOT base.
13584 (define_insn "*sibcall_value_GOT_32"
13585 [(set (match_operand 0)
13586 (call (mem:QI
13587 (mem:SI (plus:SI
13588 (match_operand:SI 1 "register_no_elim_operand" "U")
13589 (match_operand:SI 2 "GOT32_symbol_operand"))))
13590 (match_operand 3)))]
13591 "!TARGET_MACHO
13592 && !TARGET_64BIT
13593 && !TARGET_INDIRECT_BRANCH_REGISTER
13594 && SIBLING_CALL_P (insn)"
13595 {
13596 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
13597 fnaddr = gen_const_mem (SImode, fnaddr);
13598 return ix86_output_call_insn (insn, fnaddr);
13599 }
13600 [(set_attr "type" "callv")])
13601
13602 (define_insn "*sibcall_value"
13603 [(set (match_operand 0)
13604 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
13605 (match_operand 2)))]
13606 "SIBLING_CALL_P (insn)"
13607 "* return ix86_output_call_insn (insn, operands[1]);"
13608 [(set_attr "type" "callv")])
13609
13610 (define_insn "*sibcall_value_memory"
13611 [(set (match_operand 0)
13612 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
13613 (match_operand 2)))
13614 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13615 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13616 "* return ix86_output_call_insn (insn, operands[1]);"
13617 [(set_attr "type" "callv")])
13618
13619 (define_peephole2
13620 [(set (match_operand:W 0 "register_operand")
13621 (match_operand:W 1 "memory_operand"))
13622 (set (match_operand 2)
13623 (call (mem:QI (match_dup 0))
13624 (match_operand 3)))]
13625 "!TARGET_X32
13626 && !TARGET_INDIRECT_BRANCH_REGISTER
13627 && SIBLING_CALL_P (peep2_next_insn (1))
13628 && !reg_mentioned_p (operands[0],
13629 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13630 [(parallel [(set (match_dup 2)
13631 (call (mem:QI (match_dup 1))
13632 (match_dup 3)))
13633 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13634
13635 (define_peephole2
13636 [(set (match_operand:W 0 "register_operand")
13637 (match_operand:W 1 "memory_operand"))
13638 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13639 (set (match_operand 2)
13640 (call (mem:QI (match_dup 0))
13641 (match_operand 3)))]
13642 "!TARGET_X32
13643 && !TARGET_INDIRECT_BRANCH_REGISTER
13644 && SIBLING_CALL_P (peep2_next_insn (2))
13645 && !reg_mentioned_p (operands[0],
13646 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13647 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13648 (parallel [(set (match_dup 2)
13649 (call (mem:QI (match_dup 1))
13650 (match_dup 3)))
13651 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13652
13653 (define_expand "call_value_pop"
13654 [(parallel [(set (match_operand 0)
13655 (call (match_operand:QI 1)
13656 (match_operand:SI 2)))
13657 (set (reg:SI SP_REG)
13658 (plus:SI (reg:SI SP_REG)
13659 (match_operand:SI 4)))])]
13660 "!TARGET_64BIT"
13661 {
13662 ix86_expand_call (operands[0], operands[1], operands[2],
13663 operands[3], operands[4], false);
13664 DONE;
13665 })
13666
13667 (define_insn "*call_value_pop"
13668 [(set (match_operand 0)
13669 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
13670 (match_operand 2)))
13671 (set (reg:SI SP_REG)
13672 (plus:SI (reg:SI SP_REG)
13673 (match_operand:SI 3 "immediate_operand" "i")))]
13674 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13675 "* return ix86_output_call_insn (insn, operands[1]);"
13676 [(set_attr "type" "callv")])
13677
13678 (define_insn "*sibcall_value_pop"
13679 [(set (match_operand 0)
13680 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
13681 (match_operand 2)))
13682 (set (reg:SI SP_REG)
13683 (plus:SI (reg:SI SP_REG)
13684 (match_operand:SI 3 "immediate_operand" "i")))]
13685 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13686 "* return ix86_output_call_insn (insn, operands[1]);"
13687 [(set_attr "type" "callv")])
13688
13689 (define_insn "*sibcall_value_pop_memory"
13690 [(set (match_operand 0)
13691 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
13692 (match_operand 2)))
13693 (set (reg:SI SP_REG)
13694 (plus:SI (reg:SI SP_REG)
13695 (match_operand:SI 3 "immediate_operand" "i")))
13696 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13697 "!TARGET_64BIT"
13698 "* return ix86_output_call_insn (insn, operands[1]);"
13699 [(set_attr "type" "callv")])
13700
13701 (define_peephole2
13702 [(set (match_operand:SI 0 "register_operand")
13703 (match_operand:SI 1 "memory_operand"))
13704 (parallel [(set (match_operand 2)
13705 (call (mem:QI (match_dup 0))
13706 (match_operand 3)))
13707 (set (reg:SI SP_REG)
13708 (plus:SI (reg:SI SP_REG)
13709 (match_operand:SI 4 "immediate_operand")))])]
13710 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13711 && !reg_mentioned_p (operands[0],
13712 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13713 [(parallel [(set (match_dup 2)
13714 (call (mem:QI (match_dup 1))
13715 (match_dup 3)))
13716 (set (reg:SI SP_REG)
13717 (plus:SI (reg:SI SP_REG)
13718 (match_dup 4)))
13719 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13720
13721 (define_peephole2
13722 [(set (match_operand:SI 0 "register_operand")
13723 (match_operand:SI 1 "memory_operand"))
13724 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13725 (parallel [(set (match_operand 2)
13726 (call (mem:QI (match_dup 0))
13727 (match_operand 3)))
13728 (set (reg:SI SP_REG)
13729 (plus:SI (reg:SI SP_REG)
13730 (match_operand:SI 4 "immediate_operand")))])]
13731 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13732 && !reg_mentioned_p (operands[0],
13733 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13734 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13735 (parallel [(set (match_dup 2)
13736 (call (mem:QI (match_dup 1))
13737 (match_dup 3)))
13738 (set (reg:SI SP_REG)
13739 (plus:SI (reg:SI SP_REG)
13740 (match_dup 4)))
13741 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13742
13743 ;; Call subroutine returning any type.
13744
13745 (define_expand "untyped_call"
13746 [(parallel [(call (match_operand 0)
13747 (const_int 0))
13748 (match_operand 1)
13749 (match_operand 2)])]
13750 ""
13751 {
13752 int i;
13753
13754 /* In order to give reg-stack an easier job in validating two
13755 coprocessor registers as containing a possible return value,
13756 simply pretend the untyped call returns a complex long double
13757 value.
13758
13759 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13760 and should have the default ABI. */
13761
13762 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13763 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13764 operands[0], const0_rtx,
13765 GEN_INT ((TARGET_64BIT
13766 ? (ix86_abi == SYSV_ABI
13767 ? X86_64_SSE_REGPARM_MAX
13768 : X86_64_MS_SSE_REGPARM_MAX)
13769 : X86_32_SSE_REGPARM_MAX)
13770 - 1),
13771 NULL, false);
13772
13773 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13774 {
13775 rtx set = XVECEXP (operands[2], 0, i);
13776 emit_move_insn (SET_DEST (set), SET_SRC (set));
13777 }
13778
13779 /* The optimizer does not know that the call sets the function value
13780 registers we stored in the result block. We avoid problems by
13781 claiming that all hard registers are used and clobbered at this
13782 point. */
13783 emit_insn (gen_blockage ());
13784
13785 DONE;
13786 })
13787 \f
13788 ;; Prologue and epilogue instructions
13789
13790 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13791 ;; all of memory. This blocks insns from being moved across this point.
13792
13793 (define_insn "blockage"
13794 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13795 ""
13796 ""
13797 [(set_attr "length" "0")])
13798
13799 ;; Do not schedule instructions accessing memory across this point.
13800
13801 (define_expand "memory_blockage"
13802 [(set (match_dup 0)
13803 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13804 ""
13805 {
13806 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13807 MEM_VOLATILE_P (operands[0]) = 1;
13808 })
13809
13810 (define_insn "*memory_blockage"
13811 [(set (match_operand:BLK 0)
13812 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13813 ""
13814 ""
13815 [(set_attr "length" "0")])
13816
13817 ;; As USE insns aren't meaningful after reload, this is used instead
13818 ;; to prevent deleting instructions setting registers for PIC code
13819 (define_insn "prologue_use"
13820 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13821 ""
13822 ""
13823 [(set_attr "length" "0")])
13824
13825 ;; Insn emitted into the body of a function to return from a function.
13826 ;; This is only done if the function's epilogue is known to be simple.
13827 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13828
13829 (define_expand "return"
13830 [(simple_return)]
13831 "ix86_can_use_return_insn_p ()"
13832 {
13833 if (crtl->args.pops_args)
13834 {
13835 rtx popc = GEN_INT (crtl->args.pops_args);
13836 emit_jump_insn (gen_simple_return_pop_internal (popc));
13837 DONE;
13838 }
13839 })
13840
13841 ;; We need to disable this for TARGET_SEH, as otherwise
13842 ;; shrink-wrapped prologue gets enabled too. This might exceed
13843 ;; the maximum size of prologue in unwind information.
13844 ;; Also disallow shrink-wrapping if using stack slot to pass the
13845 ;; static chain pointer - the first instruction has to be pushl %esi
13846 ;; and it can't be moved around, as we use alternate entry points
13847 ;; in that case.
13848 ;; Also disallow for ms_hook_prologue functions which have frame
13849 ;; pointer set up in function label which is correctly handled in
13850 ;; ix86_expand_{prologue|epligoue}() only.
13851
13852 (define_expand "simple_return"
13853 [(simple_return)]
13854 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
13855 {
13856 if (crtl->args.pops_args)
13857 {
13858 rtx popc = GEN_INT (crtl->args.pops_args);
13859 emit_jump_insn (gen_simple_return_pop_internal (popc));
13860 DONE;
13861 }
13862 })
13863
13864 (define_insn "simple_return_internal"
13865 [(simple_return)]
13866 "reload_completed"
13867 "* return ix86_output_function_return (false);"
13868 [(set_attr "length" "1")
13869 (set_attr "atom_unit" "jeu")
13870 (set_attr "length_immediate" "0")
13871 (set_attr "modrm" "0")])
13872
13873 (define_insn "interrupt_return"
13874 [(simple_return)
13875 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13876 "reload_completed"
13877 {
13878 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
13879 })
13880
13881 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13882 ;; instruction Athlon and K8 have.
13883
13884 (define_insn "simple_return_internal_long"
13885 [(simple_return)
13886 (unspec [(const_int 0)] UNSPEC_REP)]
13887 "reload_completed"
13888 "* return ix86_output_function_return (true);"
13889 [(set_attr "length" "2")
13890 (set_attr "atom_unit" "jeu")
13891 (set_attr "length_immediate" "0")
13892 (set_attr "prefix_rep" "1")
13893 (set_attr "modrm" "0")])
13894
13895 (define_insn_and_split "simple_return_pop_internal"
13896 [(simple_return)
13897 (use (match_operand:SI 0 "const_int_operand"))]
13898 "reload_completed"
13899 "%!ret\t%0"
13900 "&& cfun->machine->function_return_type != indirect_branch_keep"
13901 [(const_int 0)]
13902 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13903 [(set_attr "length" "3")
13904 (set_attr "atom_unit" "jeu")
13905 (set_attr "length_immediate" "2")
13906 (set_attr "modrm" "0")])
13907
13908 (define_expand "simple_return_indirect_internal"
13909 [(parallel
13910 [(simple_return)
13911 (use (match_operand 0 "register_operand"))])])
13912
13913 (define_insn "*simple_return_indirect_internal<mode>"
13914 [(simple_return)
13915 (use (match_operand:W 0 "register_operand" "r"))]
13916 "reload_completed"
13917 "* return ix86_output_indirect_function_return (operands[0]);"
13918 [(set (attr "type")
13919 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13920 != indirect_branch_keep)")
13921 (const_string "multi")
13922 (const_string "ibr")))
13923 (set_attr "length_immediate" "0")])
13924
13925 (define_insn "nop"
13926 [(const_int 0)]
13927 ""
13928 "nop"
13929 [(set_attr "length" "1")
13930 (set_attr "length_immediate" "0")
13931 (set_attr "modrm" "0")])
13932
13933 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13934 (define_insn "nops"
13935 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13936 UNSPECV_NOPS)]
13937 "reload_completed"
13938 {
13939 int num = INTVAL (operands[0]);
13940
13941 gcc_assert (IN_RANGE (num, 1, 8));
13942
13943 while (num--)
13944 fputs ("\tnop\n", asm_out_file);
13945
13946 return "";
13947 }
13948 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13949 (set_attr "length_immediate" "0")
13950 (set_attr "modrm" "0")])
13951
13952 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13953 ;; branch prediction penalty for the third jump in a 16-byte
13954 ;; block on K8.
13955
13956 (define_insn "pad"
13957 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13958 ""
13959 {
13960 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13961 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13962 #else
13963 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13964 The align insn is used to avoid 3 jump instructions in the row to improve
13965 branch prediction and the benefits hardly outweigh the cost of extra 8
13966 nops on the average inserted by full alignment pseudo operation. */
13967 #endif
13968 return "";
13969 }
13970 [(set_attr "length" "16")])
13971
13972 (define_expand "prologue"
13973 [(const_int 0)]
13974 ""
13975 "ix86_expand_prologue (); DONE;")
13976
13977 (define_expand "set_got"
13978 [(parallel
13979 [(set (match_operand:SI 0 "register_operand")
13980 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13981 (clobber (reg:CC FLAGS_REG))])]
13982 "!TARGET_64BIT"
13983 {
13984 if (flag_pic && !TARGET_VXWORKS_RTP)
13985 ix86_pc_thunk_call_expanded = true;
13986 })
13987
13988 (define_insn "*set_got"
13989 [(set (match_operand:SI 0 "register_operand" "=r")
13990 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13991 (clobber (reg:CC FLAGS_REG))]
13992 "!TARGET_64BIT"
13993 "* return output_set_got (operands[0], NULL_RTX);"
13994 [(set_attr "type" "multi")
13995 (set_attr "length" "12")])
13996
13997 (define_expand "set_got_labelled"
13998 [(parallel
13999 [(set (match_operand:SI 0 "register_operand")
14000 (unspec:SI [(label_ref (match_operand 1))]
14001 UNSPEC_SET_GOT))
14002 (clobber (reg:CC FLAGS_REG))])]
14003 "!TARGET_64BIT"
14004 {
14005 if (flag_pic && !TARGET_VXWORKS_RTP)
14006 ix86_pc_thunk_call_expanded = true;
14007 })
14008
14009 (define_insn "*set_got_labelled"
14010 [(set (match_operand:SI 0 "register_operand" "=r")
14011 (unspec:SI [(label_ref (match_operand 1))]
14012 UNSPEC_SET_GOT))
14013 (clobber (reg:CC FLAGS_REG))]
14014 "!TARGET_64BIT"
14015 "* return output_set_got (operands[0], operands[1]);"
14016 [(set_attr "type" "multi")
14017 (set_attr "length" "12")])
14018
14019 (define_insn "set_got_rex64"
14020 [(set (match_operand:DI 0 "register_operand" "=r")
14021 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14022 "TARGET_64BIT"
14023 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14024 [(set_attr "type" "lea")
14025 (set_attr "length_address" "4")
14026 (set_attr "mode" "DI")])
14027
14028 (define_insn "set_rip_rex64"
14029 [(set (match_operand:DI 0 "register_operand" "=r")
14030 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
14031 "TARGET_64BIT"
14032 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14033 [(set_attr "type" "lea")
14034 (set_attr "length_address" "4")
14035 (set_attr "mode" "DI")])
14036
14037 (define_insn "set_got_offset_rex64"
14038 [(set (match_operand:DI 0 "register_operand" "=r")
14039 (unspec:DI
14040 [(label_ref (match_operand 1))]
14041 UNSPEC_SET_GOT_OFFSET))]
14042 "TARGET_LP64"
14043 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14044 [(set_attr "type" "imov")
14045 (set_attr "length_immediate" "0")
14046 (set_attr "length_address" "8")
14047 (set_attr "mode" "DI")])
14048
14049 (define_expand "epilogue"
14050 [(const_int 0)]
14051 ""
14052 "ix86_expand_epilogue (1); DONE;")
14053
14054 (define_expand "sibcall_epilogue"
14055 [(const_int 0)]
14056 ""
14057 "ix86_expand_epilogue (0); DONE;")
14058
14059 (define_expand "eh_return"
14060 [(use (match_operand 0 "register_operand"))]
14061 ""
14062 {
14063 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14064
14065 /* Tricky bit: we write the address of the handler to which we will
14066 be returning into someone else's stack frame, one word below the
14067 stack address we wish to restore. */
14068 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14069 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
14070 /* Return address is always in word_mode. */
14071 tmp = gen_rtx_MEM (word_mode, tmp);
14072 if (GET_MODE (ra) != word_mode)
14073 ra = convert_to_mode (word_mode, ra, 1);
14074 emit_move_insn (tmp, ra);
14075
14076 emit_jump_insn (gen_eh_return_internal ());
14077 emit_barrier ();
14078 DONE;
14079 })
14080
14081 (define_insn_and_split "eh_return_internal"
14082 [(eh_return)]
14083 ""
14084 "#"
14085 "epilogue_completed"
14086 [(const_int 0)]
14087 "ix86_expand_epilogue (2); DONE;")
14088
14089 (define_expand "@leave_<mode>"
14090 [(parallel
14091 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
14092 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
14093 (clobber (mem:BLK (scratch)))])]
14094 ""
14095 "operands[0] = GEN_INT (<MODE_SIZE>);")
14096
14097 (define_insn "*leave"
14098 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14099 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14100 (clobber (mem:BLK (scratch)))]
14101 "!TARGET_64BIT"
14102 "leave"
14103 [(set_attr "type" "leave")])
14104
14105 (define_insn "*leave_rex64"
14106 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14107 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14108 (clobber (mem:BLK (scratch)))]
14109 "TARGET_64BIT"
14110 "leave"
14111 [(set_attr "type" "leave")])
14112 \f
14113 ;; Handle -fsplit-stack.
14114
14115 (define_expand "split_stack_prologue"
14116 [(const_int 0)]
14117 ""
14118 {
14119 ix86_expand_split_stack_prologue ();
14120 DONE;
14121 })
14122
14123 ;; In order to support the call/return predictor, we use a return
14124 ;; instruction which the middle-end doesn't see.
14125 (define_insn "split_stack_return"
14126 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
14127 UNSPECV_SPLIT_STACK_RETURN)]
14128 ""
14129 {
14130 if (operands[0] == const0_rtx)
14131 return "ret";
14132 else
14133 return "ret\t%0";
14134 }
14135 [(set_attr "atom_unit" "jeu")
14136 (set_attr "modrm" "0")
14137 (set (attr "length")
14138 (if_then_else (match_operand:SI 0 "const0_operand")
14139 (const_int 1)
14140 (const_int 3)))
14141 (set (attr "length_immediate")
14142 (if_then_else (match_operand:SI 0 "const0_operand")
14143 (const_int 0)
14144 (const_int 2)))])
14145
14146 ;; If there are operand 0 bytes available on the stack, jump to
14147 ;; operand 1.
14148
14149 (define_expand "split_stack_space_check"
14150 [(set (pc) (if_then_else
14151 (ltu (minus (reg SP_REG)
14152 (match_operand 0 "register_operand"))
14153 (match_dup 2))
14154 (label_ref (match_operand 1))
14155 (pc)))]
14156 ""
14157 {
14158 rtx reg = gen_reg_rtx (Pmode);
14159
14160 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
14161
14162 operands[2] = ix86_split_stack_guard ();
14163 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
14164
14165 DONE;
14166 })
14167 \f
14168 ;; Bit manipulation instructions.
14169
14170 (define_expand "ffs<mode>2"
14171 [(set (match_dup 2) (const_int -1))
14172 (parallel [(set (match_dup 3) (match_dup 4))
14173 (set (match_operand:SWI48 0 "register_operand")
14174 (ctz:SWI48
14175 (match_operand:SWI48 1 "nonimmediate_operand")))])
14176 (set (match_dup 0) (if_then_else:SWI48
14177 (eq (match_dup 3) (const_int 0))
14178 (match_dup 2)
14179 (match_dup 0)))
14180 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
14181 (clobber (reg:CC FLAGS_REG))])]
14182 ""
14183 {
14184 machine_mode flags_mode;
14185
14186 if (<MODE>mode == SImode && !TARGET_CMOVE)
14187 {
14188 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
14189 DONE;
14190 }
14191
14192 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
14193
14194 operands[2] = gen_reg_rtx (<MODE>mode);
14195 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
14196 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
14197 })
14198
14199 (define_insn_and_split "ffssi2_no_cmove"
14200 [(set (match_operand:SI 0 "register_operand" "=r")
14201 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14202 (clobber (match_scratch:SI 2 "=&q"))
14203 (clobber (reg:CC FLAGS_REG))]
14204 "!TARGET_CMOVE"
14205 "#"
14206 "&& reload_completed"
14207 [(parallel [(set (match_dup 4) (match_dup 5))
14208 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14209 (set (strict_low_part (match_dup 3))
14210 (eq:QI (match_dup 4) (const_int 0)))
14211 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14212 (clobber (reg:CC FLAGS_REG))])
14213 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14214 (clobber (reg:CC FLAGS_REG))])
14215 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14216 (clobber (reg:CC FLAGS_REG))])]
14217 {
14218 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
14219
14220 operands[3] = gen_lowpart (QImode, operands[2]);
14221 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
14222 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
14223
14224 ix86_expand_clear (operands[2]);
14225 })
14226
14227 (define_insn_and_split "*tzcnt<mode>_1"
14228 [(set (reg:CCC FLAGS_REG)
14229 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14230 (const_int 0)))
14231 (set (match_operand:SWI48 0 "register_operand" "=r")
14232 (ctz:SWI48 (match_dup 1)))]
14233 "TARGET_BMI"
14234 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14235 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14236 && optimize_function_for_speed_p (cfun)
14237 && !reg_mentioned_p (operands[0], operands[1])"
14238 [(parallel
14239 [(set (reg:CCC FLAGS_REG)
14240 (compare:CCC (match_dup 1) (const_int 0)))
14241 (set (match_dup 0)
14242 (ctz:SWI48 (match_dup 1)))
14243 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
14244 "ix86_expand_clear (operands[0]);"
14245 [(set_attr "type" "alu1")
14246 (set_attr "prefix_0f" "1")
14247 (set_attr "prefix_rep" "1")
14248 (set_attr "btver2_decode" "double")
14249 (set_attr "mode" "<MODE>")])
14250
14251 ; False dependency happens when destination is only updated by tzcnt,
14252 ; lzcnt or popcnt. There is no false dependency when destination is
14253 ; also used in source.
14254 (define_insn "*tzcnt<mode>_1_falsedep"
14255 [(set (reg:CCC FLAGS_REG)
14256 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14257 (const_int 0)))
14258 (set (match_operand:SWI48 0 "register_operand" "=r")
14259 (ctz:SWI48 (match_dup 1)))
14260 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14261 UNSPEC_INSN_FALSE_DEP)]
14262 "TARGET_BMI"
14263 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14264 [(set_attr "type" "alu1")
14265 (set_attr "prefix_0f" "1")
14266 (set_attr "prefix_rep" "1")
14267 (set_attr "btver2_decode" "double")
14268 (set_attr "mode" "<MODE>")])
14269
14270 (define_insn "*bsf<mode>_1"
14271 [(set (reg:CCZ FLAGS_REG)
14272 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14273 (const_int 0)))
14274 (set (match_operand:SWI48 0 "register_operand" "=r")
14275 (ctz:SWI48 (match_dup 1)))]
14276 ""
14277 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
14278 [(set_attr "type" "alu1")
14279 (set_attr "prefix_0f" "1")
14280 (set_attr "btver2_decode" "double")
14281 (set_attr "znver1_decode" "vector")
14282 (set_attr "mode" "<MODE>")])
14283
14284 (define_insn_and_split "ctz<mode>2"
14285 [(set (match_operand:SWI48 0 "register_operand" "=r")
14286 (ctz:SWI48
14287 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14288 (clobber (reg:CC FLAGS_REG))]
14289 ""
14290 {
14291 if (TARGET_BMI)
14292 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14293 else if (optimize_function_for_size_p (cfun))
14294 ;
14295 else if (TARGET_GENERIC)
14296 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
14297 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
14298
14299 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
14300 }
14301 "(TARGET_BMI || TARGET_GENERIC)
14302 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14303 && optimize_function_for_speed_p (cfun)
14304 && !reg_mentioned_p (operands[0], operands[1])"
14305 [(parallel
14306 [(set (match_dup 0)
14307 (ctz:SWI48 (match_dup 1)))
14308 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14309 (clobber (reg:CC FLAGS_REG))])]
14310 "ix86_expand_clear (operands[0]);"
14311 [(set_attr "type" "alu1")
14312 (set_attr "prefix_0f" "1")
14313 (set (attr "prefix_rep")
14314 (if_then_else
14315 (ior (match_test "TARGET_BMI")
14316 (and (not (match_test "optimize_function_for_size_p (cfun)"))
14317 (match_test "TARGET_GENERIC")))
14318 (const_string "1")
14319 (const_string "0")))
14320 (set_attr "mode" "<MODE>")])
14321
14322 ; False dependency happens when destination is only updated by tzcnt,
14323 ; lzcnt or popcnt. There is no false dependency when destination is
14324 ; also used in source.
14325 (define_insn "*ctz<mode>2_falsedep"
14326 [(set (match_operand:SWI48 0 "register_operand" "=r")
14327 (ctz:SWI48
14328 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14329 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14330 UNSPEC_INSN_FALSE_DEP)
14331 (clobber (reg:CC FLAGS_REG))]
14332 ""
14333 {
14334 if (TARGET_BMI)
14335 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14336 else if (TARGET_GENERIC)
14337 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
14338 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
14339 else
14340 gcc_unreachable ();
14341 }
14342 [(set_attr "type" "alu1")
14343 (set_attr "prefix_0f" "1")
14344 (set_attr "prefix_rep" "1")
14345 (set_attr "mode" "<MODE>")])
14346
14347 (define_insn_and_split "*ctzsi2_zext"
14348 [(set (match_operand:DI 0 "register_operand" "=r")
14349 (and:DI
14350 (subreg:DI
14351 (ctz:SI
14352 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14353 (const_int 63)))
14354 (clobber (reg:CC FLAGS_REG))]
14355 "TARGET_BMI && TARGET_64BIT"
14356 "tzcnt{l}\t{%1, %k0|%k0, %1}"
14357 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14358 && optimize_function_for_speed_p (cfun)
14359 && !reg_mentioned_p (operands[0], operands[1])"
14360 [(parallel
14361 [(set (match_dup 0)
14362 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
14363 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14364 (clobber (reg:CC FLAGS_REG))])]
14365 "ix86_expand_clear (operands[0]);"
14366 [(set_attr "type" "alu1")
14367 (set_attr "prefix_0f" "1")
14368 (set_attr "prefix_rep" "1")
14369 (set_attr "mode" "SI")])
14370
14371 ; False dependency happens when destination is only updated by tzcnt,
14372 ; lzcnt or popcnt. There is no false dependency when destination is
14373 ; also used in source.
14374 (define_insn "*ctzsi2_zext_falsedep"
14375 [(set (match_operand:DI 0 "register_operand" "=r")
14376 (and:DI
14377 (subreg:DI
14378 (ctz:SI
14379 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14380 (const_int 63)))
14381 (unspec [(match_operand:DI 2 "register_operand" "0")]
14382 UNSPEC_INSN_FALSE_DEP)
14383 (clobber (reg:CC FLAGS_REG))]
14384 "TARGET_BMI && TARGET_64BIT"
14385 "tzcnt{l}\t{%1, %k0|%k0, %1}"
14386 [(set_attr "type" "alu1")
14387 (set_attr "prefix_0f" "1")
14388 (set_attr "prefix_rep" "1")
14389 (set_attr "mode" "SI")])
14390
14391 (define_insn "bsr_rex64"
14392 [(set (match_operand:DI 0 "register_operand" "=r")
14393 (minus:DI (const_int 63)
14394 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14395 (clobber (reg:CC FLAGS_REG))]
14396 "TARGET_64BIT"
14397 "bsr{q}\t{%1, %0|%0, %1}"
14398 [(set_attr "type" "alu1")
14399 (set_attr "prefix_0f" "1")
14400 (set_attr "znver1_decode" "vector")
14401 (set_attr "mode" "DI")])
14402
14403 (define_insn "bsr"
14404 [(set (match_operand:SI 0 "register_operand" "=r")
14405 (minus:SI (const_int 31)
14406 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14407 (clobber (reg:CC FLAGS_REG))]
14408 ""
14409 "bsr{l}\t{%1, %0|%0, %1}"
14410 [(set_attr "type" "alu1")
14411 (set_attr "prefix_0f" "1")
14412 (set_attr "znver1_decode" "vector")
14413 (set_attr "mode" "SI")])
14414
14415 (define_insn "*bsrhi"
14416 [(set (match_operand:HI 0 "register_operand" "=r")
14417 (minus:HI (const_int 15)
14418 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14419 (clobber (reg:CC FLAGS_REG))]
14420 ""
14421 "bsr{w}\t{%1, %0|%0, %1}"
14422 [(set_attr "type" "alu1")
14423 (set_attr "prefix_0f" "1")
14424 (set_attr "znver1_decode" "vector")
14425 (set_attr "mode" "HI")])
14426
14427 (define_expand "clz<mode>2"
14428 [(parallel
14429 [(set (match_operand:SWI48 0 "register_operand")
14430 (minus:SWI48
14431 (match_dup 2)
14432 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
14433 (clobber (reg:CC FLAGS_REG))])
14434 (parallel
14435 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
14436 (clobber (reg:CC FLAGS_REG))])]
14437 ""
14438 {
14439 if (TARGET_LZCNT)
14440 {
14441 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
14442 DONE;
14443 }
14444 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
14445 })
14446
14447 (define_insn_and_split "clz<mode>2_lzcnt"
14448 [(set (match_operand:SWI48 0 "register_operand" "=r")
14449 (clz:SWI48
14450 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14451 (clobber (reg:CC FLAGS_REG))]
14452 "TARGET_LZCNT"
14453 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
14454 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14455 && optimize_function_for_speed_p (cfun)
14456 && !reg_mentioned_p (operands[0], operands[1])"
14457 [(parallel
14458 [(set (match_dup 0)
14459 (clz:SWI48 (match_dup 1)))
14460 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14461 (clobber (reg:CC FLAGS_REG))])]
14462 "ix86_expand_clear (operands[0]);"
14463 [(set_attr "prefix_rep" "1")
14464 (set_attr "type" "bitmanip")
14465 (set_attr "mode" "<MODE>")])
14466
14467 ; False dependency happens when destination is only updated by tzcnt,
14468 ; lzcnt or popcnt. There is no false dependency when destination is
14469 ; also used in source.
14470 (define_insn "*clz<mode>2_lzcnt_falsedep"
14471 [(set (match_operand:SWI48 0 "register_operand" "=r")
14472 (clz:SWI48
14473 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14474 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14475 UNSPEC_INSN_FALSE_DEP)
14476 (clobber (reg:CC FLAGS_REG))]
14477 "TARGET_LZCNT"
14478 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
14479 [(set_attr "prefix_rep" "1")
14480 (set_attr "type" "bitmanip")
14481 (set_attr "mode" "<MODE>")])
14482
14483 (define_insn_and_split "*clzsi2_lzcnt_zext"
14484 [(set (match_operand:DI 0 "register_operand" "=r")
14485 (and:DI
14486 (subreg:DI
14487 (clz:SI
14488 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14489 (const_int 63)))
14490 (clobber (reg:CC FLAGS_REG))]
14491 "TARGET_LZCNT && TARGET_64BIT"
14492 "lzcnt{l}\t{%1, %k0|%k0, %1}"
14493 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14494 && optimize_function_for_speed_p (cfun)
14495 && !reg_mentioned_p (operands[0], operands[1])"
14496 [(parallel
14497 [(set (match_dup 0)
14498 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
14499 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14500 (clobber (reg:CC FLAGS_REG))])]
14501 "ix86_expand_clear (operands[0]);"
14502 [(set_attr "prefix_rep" "1")
14503 (set_attr "type" "bitmanip")
14504 (set_attr "mode" "SI")])
14505
14506 ; False dependency happens when destination is only updated by tzcnt,
14507 ; lzcnt or popcnt. There is no false dependency when destination is
14508 ; also used in source.
14509 (define_insn "*clzsi2_lzcnt_zext_falsedep"
14510 [(set (match_operand:DI 0 "register_operand" "=r")
14511 (and:DI
14512 (subreg:DI
14513 (clz:SI
14514 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
14515 (const_int 63)))
14516 (unspec [(match_operand:DI 2 "register_operand" "0")]
14517 UNSPEC_INSN_FALSE_DEP)
14518 (clobber (reg:CC FLAGS_REG))]
14519 "TARGET_LZCNT"
14520 "lzcnt{l}\t{%1, %k0|%k0, %1}"
14521 [(set_attr "prefix_rep" "1")
14522 (set_attr "type" "bitmanip")
14523 (set_attr "mode" "SI")])
14524
14525 (define_int_iterator LT_ZCNT
14526 [(UNSPEC_TZCNT "TARGET_BMI")
14527 (UNSPEC_LZCNT "TARGET_LZCNT")])
14528
14529 (define_int_attr lt_zcnt
14530 [(UNSPEC_TZCNT "tzcnt")
14531 (UNSPEC_LZCNT "lzcnt")])
14532
14533 (define_int_attr lt_zcnt_type
14534 [(UNSPEC_TZCNT "alu1")
14535 (UNSPEC_LZCNT "bitmanip")])
14536
14537 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
14538 ;; provides operand size as output when source operand is zero.
14539
14540 (define_insn_and_split "<lt_zcnt>_<mode>"
14541 [(set (match_operand:SWI48 0 "register_operand" "=r")
14542 (unspec:SWI48
14543 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14544 (clobber (reg:CC FLAGS_REG))]
14545 ""
14546 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14547 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14548 && optimize_function_for_speed_p (cfun)
14549 && !reg_mentioned_p (operands[0], operands[1])"
14550 [(parallel
14551 [(set (match_dup 0)
14552 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
14553 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14554 (clobber (reg:CC FLAGS_REG))])]
14555 "ix86_expand_clear (operands[0]);"
14556 [(set_attr "type" "<lt_zcnt_type>")
14557 (set_attr "prefix_0f" "1")
14558 (set_attr "prefix_rep" "1")
14559 (set_attr "mode" "<MODE>")])
14560
14561 ; False dependency happens when destination is only updated by tzcnt,
14562 ; lzcnt or popcnt. There is no false dependency when destination is
14563 ; also used in source.
14564 (define_insn "*<lt_zcnt>_<mode>_falsedep"
14565 [(set (match_operand:SWI48 0 "register_operand" "=r")
14566 (unspec:SWI48
14567 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14568 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14569 UNSPEC_INSN_FALSE_DEP)
14570 (clobber (reg:CC FLAGS_REG))]
14571 ""
14572 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14573 [(set_attr "type" "<lt_zcnt_type>")
14574 (set_attr "prefix_0f" "1")
14575 (set_attr "prefix_rep" "1")
14576 (set_attr "mode" "<MODE>")])
14577
14578 (define_insn "<lt_zcnt>_hi"
14579 [(set (match_operand:HI 0 "register_operand" "=r")
14580 (unspec:HI
14581 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14582 (clobber (reg:CC FLAGS_REG))]
14583 ""
14584 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
14585 [(set_attr "type" "<lt_zcnt_type>")
14586 (set_attr "prefix_0f" "1")
14587 (set_attr "prefix_rep" "1")
14588 (set_attr "mode" "HI")])
14589
14590 ;; BMI instructions.
14591
14592 (define_insn "bmi_bextr_<mode>"
14593 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
14594 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14595 (match_operand:SWI48 2 "register_operand" "r,r")]
14596 UNSPEC_BEXTR))
14597 (clobber (reg:CC FLAGS_REG))]
14598 "TARGET_BMI"
14599 "bextr\t{%2, %1, %0|%0, %1, %2}"
14600 [(set_attr "type" "bitmanip")
14601 (set_attr "btver2_decode" "direct, double")
14602 (set_attr "mode" "<MODE>")])
14603
14604 (define_insn "*bmi_bextr_<mode>_ccz"
14605 [(set (reg:CCZ FLAGS_REG)
14606 (compare:CCZ
14607 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14608 (match_operand:SWI48 2 "register_operand" "r,r")]
14609 UNSPEC_BEXTR)
14610 (const_int 0)))
14611 (clobber (match_scratch:SWI48 0 "=r,r"))]
14612 "TARGET_BMI"
14613 "bextr\t{%2, %1, %0|%0, %1, %2}"
14614 [(set_attr "type" "bitmanip")
14615 (set_attr "btver2_decode" "direct, double")
14616 (set_attr "mode" "<MODE>")])
14617
14618 (define_insn "*bmi_blsi_<mode>"
14619 [(set (match_operand:SWI48 0 "register_operand" "=r")
14620 (and:SWI48
14621 (neg:SWI48
14622 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14623 (match_dup 1)))
14624 (clobber (reg:CC FLAGS_REG))]
14625 "TARGET_BMI"
14626 "blsi\t{%1, %0|%0, %1}"
14627 [(set_attr "type" "bitmanip")
14628 (set_attr "btver2_decode" "double")
14629 (set_attr "mode" "<MODE>")])
14630
14631 (define_insn "*bmi_blsi_<mode>_cmp"
14632 [(set (reg FLAGS_REG)
14633 (compare
14634 (and:SWI48
14635 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14636 (match_dup 1))
14637 (const_int 0)))
14638 (set (match_operand:SWI48 0 "register_operand" "=r")
14639 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
14640 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
14641 "blsi\t{%1, %0|%0, %1}"
14642 [(set_attr "type" "bitmanip")
14643 (set_attr "btver2_decode" "double")
14644 (set_attr "mode" "<MODE>")])
14645
14646 (define_insn "*bmi_blsi_<mode>_ccno"
14647 [(set (reg FLAGS_REG)
14648 (compare
14649 (and:SWI48
14650 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14651 (match_dup 1))
14652 (const_int 0)))
14653 (clobber (match_scratch:SWI48 0 "=r"))]
14654 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
14655 "blsi\t{%1, %0|%0, %1}"
14656 [(set_attr "type" "bitmanip")
14657 (set_attr "btver2_decode" "double")
14658 (set_attr "mode" "<MODE>")])
14659
14660 (define_insn "*bmi_blsmsk_<mode>"
14661 [(set (match_operand:SWI48 0 "register_operand" "=r")
14662 (xor:SWI48
14663 (plus:SWI48
14664 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14665 (const_int -1))
14666 (match_dup 1)))
14667 (clobber (reg:CC FLAGS_REG))]
14668 "TARGET_BMI"
14669 "blsmsk\t{%1, %0|%0, %1}"
14670 [(set_attr "type" "bitmanip")
14671 (set_attr "btver2_decode" "double")
14672 (set_attr "mode" "<MODE>")])
14673
14674 (define_insn "*bmi_blsr_<mode>"
14675 [(set (match_operand:SWI48 0 "register_operand" "=r")
14676 (and:SWI48
14677 (plus:SWI48
14678 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14679 (const_int -1))
14680 (match_dup 1)))
14681 (clobber (reg:CC FLAGS_REG))]
14682 "TARGET_BMI"
14683 "blsr\t{%1, %0|%0, %1}"
14684 [(set_attr "type" "bitmanip")
14685 (set_attr "btver2_decode" "double")
14686 (set_attr "mode" "<MODE>")])
14687
14688 (define_insn "*bmi_blsr_<mode>_cmp"
14689 [(set (reg:CCZ FLAGS_REG)
14690 (compare:CCZ
14691 (and:SWI48
14692 (plus:SWI48
14693 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14694 (const_int -1))
14695 (match_dup 1))
14696 (const_int 0)))
14697 (set (match_operand:SWI48 0 "register_operand" "=r")
14698 (and:SWI48
14699 (plus:SWI48
14700 (match_dup 1)
14701 (const_int -1))
14702 (match_dup 1)))]
14703 "TARGET_BMI"
14704 "blsr\t{%1, %0|%0, %1}"
14705 [(set_attr "type" "bitmanip")
14706 (set_attr "btver2_decode" "double")
14707 (set_attr "mode" "<MODE>")])
14708
14709 (define_insn "*bmi_blsr_<mode>_ccz"
14710 [(set (reg:CCZ FLAGS_REG)
14711 (compare:CCZ
14712 (and:SWI48
14713 (plus:SWI48
14714 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14715 (const_int -1))
14716 (match_dup 1))
14717 (const_int 0)))
14718 (clobber (match_scratch:SWI48 0 "=r"))]
14719 "TARGET_BMI"
14720 "blsr\t{%1, %0|%0, %1}"
14721 [(set_attr "type" "bitmanip")
14722 (set_attr "btver2_decode" "double")
14723 (set_attr "mode" "<MODE>")])
14724
14725 ;; BMI2 instructions.
14726 (define_expand "bmi2_bzhi_<mode>3"
14727 [(parallel
14728 [(set (match_operand:SWI48 0 "register_operand")
14729 (if_then_else:SWI48
14730 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
14731 (const_int 255))
14732 (const_int 0))
14733 (zero_extract:SWI48
14734 (match_operand:SWI48 1 "nonimmediate_operand")
14735 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
14736 (match_dup 3))
14737 (const_int 0))
14738 (const_int 0)))
14739 (clobber (reg:CC FLAGS_REG))])]
14740 "TARGET_BMI2"
14741 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
14742
14743 (define_insn "*bmi2_bzhi_<mode>3"
14744 [(set (match_operand:SWI48 0 "register_operand" "=r")
14745 (if_then_else:SWI48
14746 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
14747 (const_int 255))
14748 (const_int 0))
14749 (zero_extract:SWI48
14750 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14751 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
14752 (match_operand:SWI48 3 "const_int_operand" "n"))
14753 (const_int 0))
14754 (const_int 0)))
14755 (clobber (reg:CC FLAGS_REG))]
14756 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14757 "bzhi\t{%2, %1, %0|%0, %1, %2}"
14758 [(set_attr "type" "bitmanip")
14759 (set_attr "prefix" "vex")
14760 (set_attr "mode" "<MODE>")])
14761
14762 (define_insn "*bmi2_bzhi_<mode>3_1"
14763 [(set (match_operand:SWI48 0 "register_operand" "=r")
14764 (if_then_else:SWI48
14765 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
14766 (zero_extract:SWI48
14767 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14768 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
14769 (match_operand:SWI48 3 "const_int_operand" "n"))
14770 (const_int 0))
14771 (const_int 0)))
14772 (clobber (reg:CC FLAGS_REG))]
14773 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14774 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14775 [(set_attr "type" "bitmanip")
14776 (set_attr "prefix" "vex")
14777 (set_attr "mode" "<MODE>")])
14778
14779 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
14780 [(set (reg:CCZ FLAGS_REG)
14781 (compare:CCZ
14782 (if_then_else:SWI48
14783 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
14784 (zero_extract:SWI48
14785 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14786 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
14787 (match_operand:SWI48 3 "const_int_operand" "n"))
14788 (const_int 0))
14789 (const_int 0))
14790 (const_int 0)))
14791 (clobber (match_scratch:SWI48 0 "=r"))]
14792 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14793 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14794 [(set_attr "type" "bitmanip")
14795 (set_attr "prefix" "vex")
14796 (set_attr "mode" "<MODE>")])
14797
14798 (define_insn "*bmi2_bzhi_<mode>3_2"
14799 [(set (match_operand:SWI48 0 "register_operand" "=r")
14800 (and:SWI48
14801 (plus:SWI48
14802 (ashift:SWI48 (const_int 1)
14803 (match_operand:QI 2 "register_operand" "r"))
14804 (const_int -1))
14805 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14806 (clobber (reg:CC FLAGS_REG))]
14807 "TARGET_BMI2"
14808 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14809 [(set_attr "type" "bitmanip")
14810 (set_attr "prefix" "vex")
14811 (set_attr "mode" "<MODE>")])
14812
14813 (define_insn "*bmi2_bzhi_<mode>3_3"
14814 [(set (match_operand:SWI48 0 "register_operand" "=r")
14815 (and:SWI48
14816 (not:SWI48
14817 (ashift:SWI48 (const_int -1)
14818 (match_operand:QI 2 "register_operand" "r")))
14819 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14820 (clobber (reg:CC FLAGS_REG))]
14821 "TARGET_BMI2"
14822 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14823 [(set_attr "type" "bitmanip")
14824 (set_attr "prefix" "vex")
14825 (set_attr "mode" "<MODE>")])
14826
14827 (define_insn "bmi2_pdep_<mode>3"
14828 [(set (match_operand:SWI48 0 "register_operand" "=r")
14829 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14830 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14831 UNSPEC_PDEP))]
14832 "TARGET_BMI2"
14833 "pdep\t{%2, %1, %0|%0, %1, %2}"
14834 [(set_attr "type" "bitmanip")
14835 (set_attr "prefix" "vex")
14836 (set_attr "mode" "<MODE>")])
14837
14838 (define_insn "bmi2_pext_<mode>3"
14839 [(set (match_operand:SWI48 0 "register_operand" "=r")
14840 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14841 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14842 UNSPEC_PEXT))]
14843 "TARGET_BMI2"
14844 "pext\t{%2, %1, %0|%0, %1, %2}"
14845 [(set_attr "type" "bitmanip")
14846 (set_attr "prefix" "vex")
14847 (set_attr "mode" "<MODE>")])
14848
14849 ;; TBM instructions.
14850 (define_insn "@tbm_bextri_<mode>"
14851 [(set (match_operand:SWI48 0 "register_operand" "=r")
14852 (zero_extract:SWI48
14853 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14854 (match_operand 2 "const_0_to_255_operand" "N")
14855 (match_operand 3 "const_0_to_255_operand" "N")))
14856 (clobber (reg:CC FLAGS_REG))]
14857 "TARGET_TBM"
14858 {
14859 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
14860 return "bextr\t{%2, %1, %0|%0, %1, %2}";
14861 }
14862 [(set_attr "type" "bitmanip")
14863 (set_attr "mode" "<MODE>")])
14864
14865 (define_insn "*tbm_blcfill_<mode>"
14866 [(set (match_operand:SWI48 0 "register_operand" "=r")
14867 (and:SWI48
14868 (plus:SWI48
14869 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14870 (const_int 1))
14871 (match_dup 1)))
14872 (clobber (reg:CC FLAGS_REG))]
14873 "TARGET_TBM"
14874 "blcfill\t{%1, %0|%0, %1}"
14875 [(set_attr "type" "bitmanip")
14876 (set_attr "mode" "<MODE>")])
14877
14878 (define_insn "*tbm_blci_<mode>"
14879 [(set (match_operand:SWI48 0 "register_operand" "=r")
14880 (ior:SWI48
14881 (not:SWI48
14882 (plus:SWI48
14883 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14884 (const_int 1)))
14885 (match_dup 1)))
14886 (clobber (reg:CC FLAGS_REG))]
14887 "TARGET_TBM"
14888 "blci\t{%1, %0|%0, %1}"
14889 [(set_attr "type" "bitmanip")
14890 (set_attr "mode" "<MODE>")])
14891
14892 (define_insn "*tbm_blcic_<mode>"
14893 [(set (match_operand:SWI48 0 "register_operand" "=r")
14894 (and:SWI48
14895 (plus:SWI48
14896 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14897 (const_int 1))
14898 (not:SWI48
14899 (match_dup 1))))
14900 (clobber (reg:CC FLAGS_REG))]
14901 "TARGET_TBM"
14902 "blcic\t{%1, %0|%0, %1}"
14903 [(set_attr "type" "bitmanip")
14904 (set_attr "mode" "<MODE>")])
14905
14906 (define_insn "*tbm_blcmsk_<mode>"
14907 [(set (match_operand:SWI48 0 "register_operand" "=r")
14908 (xor:SWI48
14909 (plus:SWI48
14910 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14911 (const_int 1))
14912 (match_dup 1)))
14913 (clobber (reg:CC FLAGS_REG))]
14914 "TARGET_TBM"
14915 "blcmsk\t{%1, %0|%0, %1}"
14916 [(set_attr "type" "bitmanip")
14917 (set_attr "mode" "<MODE>")])
14918
14919 (define_insn "*tbm_blcs_<mode>"
14920 [(set (match_operand:SWI48 0 "register_operand" "=r")
14921 (ior:SWI48
14922 (plus:SWI48
14923 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14924 (const_int 1))
14925 (match_dup 1)))
14926 (clobber (reg:CC FLAGS_REG))]
14927 "TARGET_TBM"
14928 "blcs\t{%1, %0|%0, %1}"
14929 [(set_attr "type" "bitmanip")
14930 (set_attr "mode" "<MODE>")])
14931
14932 (define_insn "*tbm_blsfill_<mode>"
14933 [(set (match_operand:SWI48 0 "register_operand" "=r")
14934 (ior:SWI48
14935 (plus:SWI48
14936 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14937 (const_int -1))
14938 (match_dup 1)))
14939 (clobber (reg:CC FLAGS_REG))]
14940 "TARGET_TBM"
14941 "blsfill\t{%1, %0|%0, %1}"
14942 [(set_attr "type" "bitmanip")
14943 (set_attr "mode" "<MODE>")])
14944
14945 (define_insn "*tbm_blsic_<mode>"
14946 [(set (match_operand:SWI48 0 "register_operand" "=r")
14947 (ior:SWI48
14948 (plus:SWI48
14949 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14950 (const_int -1))
14951 (not:SWI48
14952 (match_dup 1))))
14953 (clobber (reg:CC FLAGS_REG))]
14954 "TARGET_TBM"
14955 "blsic\t{%1, %0|%0, %1}"
14956 [(set_attr "type" "bitmanip")
14957 (set_attr "mode" "<MODE>")])
14958
14959 (define_insn "*tbm_t1mskc_<mode>"
14960 [(set (match_operand:SWI48 0 "register_operand" "=r")
14961 (ior:SWI48
14962 (plus:SWI48
14963 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14964 (const_int 1))
14965 (not:SWI48
14966 (match_dup 1))))
14967 (clobber (reg:CC FLAGS_REG))]
14968 "TARGET_TBM"
14969 "t1mskc\t{%1, %0|%0, %1}"
14970 [(set_attr "type" "bitmanip")
14971 (set_attr "mode" "<MODE>")])
14972
14973 (define_insn "*tbm_tzmsk_<mode>"
14974 [(set (match_operand:SWI48 0 "register_operand" "=r")
14975 (and:SWI48
14976 (plus:SWI48
14977 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14978 (const_int -1))
14979 (not:SWI48
14980 (match_dup 1))))
14981 (clobber (reg:CC FLAGS_REG))]
14982 "TARGET_TBM"
14983 "tzmsk\t{%1, %0|%0, %1}"
14984 [(set_attr "type" "bitmanip")
14985 (set_attr "mode" "<MODE>")])
14986
14987 (define_insn_and_split "popcount<mode>2"
14988 [(set (match_operand:SWI48 0 "register_operand" "=r")
14989 (popcount:SWI48
14990 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14991 (clobber (reg:CC FLAGS_REG))]
14992 "TARGET_POPCNT"
14993 {
14994 #if TARGET_MACHO
14995 return "popcnt\t{%1, %0|%0, %1}";
14996 #else
14997 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14998 #endif
14999 }
15000 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
15001 && optimize_function_for_speed_p (cfun)
15002 && !reg_mentioned_p (operands[0], operands[1])"
15003 [(parallel
15004 [(set (match_dup 0)
15005 (popcount:SWI48 (match_dup 1)))
15006 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
15007 (clobber (reg:CC FLAGS_REG))])]
15008 "ix86_expand_clear (operands[0]);"
15009 [(set_attr "prefix_rep" "1")
15010 (set_attr "type" "bitmanip")
15011 (set_attr "mode" "<MODE>")])
15012
15013 ; False dependency happens when destination is only updated by tzcnt,
15014 ; lzcnt or popcnt. There is no false dependency when destination is
15015 ; also used in source.
15016 (define_insn "*popcount<mode>2_falsedep"
15017 [(set (match_operand:SWI48 0 "register_operand" "=r")
15018 (popcount:SWI48
15019 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
15020 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
15021 UNSPEC_INSN_FALSE_DEP)
15022 (clobber (reg:CC FLAGS_REG))]
15023 "TARGET_POPCNT"
15024 {
15025 #if TARGET_MACHO
15026 return "popcnt\t{%1, %0|%0, %1}";
15027 #else
15028 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15029 #endif
15030 }
15031 [(set_attr "prefix_rep" "1")
15032 (set_attr "type" "bitmanip")
15033 (set_attr "mode" "<MODE>")])
15034
15035 (define_insn_and_split "*popcountsi2_zext"
15036 [(set (match_operand:DI 0 "register_operand" "=r")
15037 (and:DI
15038 (subreg:DI
15039 (popcount:SI
15040 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
15041 (const_int 63)))
15042 (clobber (reg:CC FLAGS_REG))]
15043 "TARGET_POPCNT && TARGET_64BIT"
15044 {
15045 #if TARGET_MACHO
15046 return "popcnt\t{%1, %k0|%k0, %1}";
15047 #else
15048 return "popcnt{l}\t{%1, %k0|%k0, %1}";
15049 #endif
15050 }
15051 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
15052 && optimize_function_for_speed_p (cfun)
15053 && !reg_mentioned_p (operands[0], operands[1])"
15054 [(parallel
15055 [(set (match_dup 0)
15056 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
15057 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
15058 (clobber (reg:CC FLAGS_REG))])]
15059 "ix86_expand_clear (operands[0]);"
15060 [(set_attr "prefix_rep" "1")
15061 (set_attr "type" "bitmanip")
15062 (set_attr "mode" "SI")])
15063
15064 ; False dependency happens when destination is only updated by tzcnt,
15065 ; lzcnt or popcnt. There is no false dependency when destination is
15066 ; also used in source.
15067 (define_insn "*popcountsi2_zext_falsedep"
15068 [(set (match_operand:DI 0 "register_operand" "=r")
15069 (and:DI
15070 (subreg:DI
15071 (popcount:SI
15072 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
15073 (const_int 63)))
15074 (unspec [(match_operand:DI 2 "register_operand" "0")]
15075 UNSPEC_INSN_FALSE_DEP)
15076 (clobber (reg:CC FLAGS_REG))]
15077 "TARGET_POPCNT && TARGET_64BIT"
15078 {
15079 #if TARGET_MACHO
15080 return "popcnt\t{%1, %k0|%k0, %1}";
15081 #else
15082 return "popcnt{l}\t{%1, %k0|%k0, %1}";
15083 #endif
15084 }
15085 [(set_attr "prefix_rep" "1")
15086 (set_attr "type" "bitmanip")
15087 (set_attr "mode" "SI")])
15088
15089 (define_insn_and_split "*popcounthi2_1"
15090 [(set (match_operand:SI 0 "register_operand")
15091 (popcount:SI
15092 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
15093 (clobber (reg:CC FLAGS_REG))]
15094 "TARGET_POPCNT
15095 && ix86_pre_reload_split ()"
15096 "#"
15097 "&& 1"
15098 [(const_int 0)]
15099 {
15100 rtx tmp = gen_reg_rtx (HImode);
15101
15102 emit_insn (gen_popcounthi2 (tmp, operands[1]));
15103 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
15104 DONE;
15105 })
15106
15107 (define_insn "popcounthi2"
15108 [(set (match_operand:HI 0 "register_operand" "=r")
15109 (popcount:HI
15110 (match_operand:HI 1 "nonimmediate_operand" "rm")))
15111 (clobber (reg:CC FLAGS_REG))]
15112 "TARGET_POPCNT"
15113 {
15114 #if TARGET_MACHO
15115 return "popcnt\t{%1, %0|%0, %1}";
15116 #else
15117 return "popcnt{w}\t{%1, %0|%0, %1}";
15118 #endif
15119 }
15120 [(set_attr "prefix_rep" "1")
15121 (set_attr "type" "bitmanip")
15122 (set_attr "mode" "HI")])
15123
15124 (define_expand "bswapdi2"
15125 [(set (match_operand:DI 0 "register_operand")
15126 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
15127 "TARGET_64BIT"
15128 {
15129 if (!TARGET_MOVBE)
15130 operands[1] = force_reg (DImode, operands[1]);
15131 })
15132
15133 (define_expand "bswapsi2"
15134 [(set (match_operand:SI 0 "register_operand")
15135 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
15136 ""
15137 {
15138 if (TARGET_MOVBE)
15139 ;
15140 else if (TARGET_BSWAP)
15141 operands[1] = force_reg (SImode, operands[1]);
15142 else
15143 {
15144 rtx x = operands[0];
15145
15146 emit_move_insn (x, operands[1]);
15147 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15148 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15149 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15150 DONE;
15151 }
15152 })
15153
15154 (define_insn "*bswap<mode>2_movbe"
15155 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
15156 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
15157 "TARGET_MOVBE
15158 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15159 "@
15160 bswap\t%0
15161 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
15162 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
15163 [(set_attr "type" "bitmanip,imov,imov")
15164 (set_attr "modrm" "0,1,1")
15165 (set_attr "prefix_0f" "*,1,1")
15166 (set_attr "prefix_extra" "*,1,1")
15167 (set_attr "mode" "<MODE>")])
15168
15169 (define_insn "*bswap<mode>2"
15170 [(set (match_operand:SWI48 0 "register_operand" "=r")
15171 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
15172 "TARGET_BSWAP"
15173 "bswap\t%0"
15174 [(set_attr "type" "bitmanip")
15175 (set_attr "modrm" "0")
15176 (set_attr "mode" "<MODE>")])
15177
15178 (define_expand "bswaphi2"
15179 [(set (match_operand:HI 0 "register_operand")
15180 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
15181 "TARGET_MOVBE")
15182
15183 (define_insn "*bswaphi2_movbe"
15184 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
15185 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
15186 "TARGET_MOVBE
15187 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15188 "@
15189 xchg{b}\t{%h0, %b0|%b0, %h0}
15190 movbe{w}\t{%1, %0|%0, %1}
15191 movbe{w}\t{%1, %0|%0, %1}"
15192 [(set_attr "type" "imov")
15193 (set_attr "modrm" "*,1,1")
15194 (set_attr "prefix_0f" "*,1,1")
15195 (set_attr "prefix_extra" "*,1,1")
15196 (set_attr "pent_pair" "np,*,*")
15197 (set_attr "athlon_decode" "vector,*,*")
15198 (set_attr "amdfam10_decode" "double,*,*")
15199 (set_attr "bdver1_decode" "double,*,*")
15200 (set_attr "mode" "QI,HI,HI")])
15201
15202 (define_peephole2
15203 [(set (match_operand:HI 0 "general_reg_operand")
15204 (bswap:HI (match_dup 0)))]
15205 "TARGET_MOVBE
15206 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
15207 && peep2_regno_dead_p (0, FLAGS_REG)"
15208 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
15209 (clobber (reg:CC FLAGS_REG))])])
15210
15211 (define_insn "bswaphi_lowpart"
15212 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15213 (bswap:HI (match_dup 0)))
15214 (clobber (reg:CC FLAGS_REG))]
15215 ""
15216 "@
15217 xchg{b}\t{%h0, %b0|%b0, %h0}
15218 rol{w}\t{$8, %0|%0, 8}"
15219 [(set (attr "preferred_for_size")
15220 (cond [(eq_attr "alternative" "0")
15221 (symbol_ref "true")]
15222 (symbol_ref "false")))
15223 (set (attr "preferred_for_speed")
15224 (cond [(eq_attr "alternative" "0")
15225 (symbol_ref "TARGET_USE_XCHGB")]
15226 (symbol_ref "!TARGET_USE_XCHGB")))
15227 (set_attr "length" "2,4")
15228 (set_attr "mode" "QI,HI")])
15229
15230 (define_expand "paritydi2"
15231 [(set (match_operand:DI 0 "register_operand")
15232 (parity:DI (match_operand:DI 1 "register_operand")))]
15233 "! TARGET_POPCNT"
15234 {
15235 rtx scratch = gen_reg_rtx (QImode);
15236 rtx hipart1 = gen_reg_rtx (SImode);
15237 rtx lopart1 = gen_reg_rtx (SImode);
15238 rtx xor1 = gen_reg_rtx (SImode);
15239 rtx shift2 = gen_reg_rtx (SImode);
15240 rtx hipart2 = gen_reg_rtx (HImode);
15241 rtx lopart2 = gen_reg_rtx (HImode);
15242 rtx xor2 = gen_reg_rtx (HImode);
15243
15244 if (TARGET_64BIT)
15245 {
15246 rtx shift1 = gen_reg_rtx (DImode);
15247 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
15248 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
15249 }
15250 else
15251 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
15252
15253 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
15254 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
15255
15256 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
15257 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
15258 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
15259 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
15260
15261 emit_insn (gen_parityhi2_cmp (xor2));
15262
15263 ix86_expand_setcc (scratch, ORDERED,
15264 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
15265
15266 if (TARGET_64BIT)
15267 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15268 else
15269 {
15270 rtx tmp = gen_reg_rtx (SImode);
15271
15272 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15273 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15274 }
15275 DONE;
15276 })
15277
15278 (define_expand "paritysi2"
15279 [(set (match_operand:SI 0 "register_operand")
15280 (parity:SI (match_operand:SI 1 "register_operand")))]
15281 "! TARGET_POPCNT"
15282 {
15283 rtx scratch = gen_reg_rtx (QImode);
15284 rtx shift = gen_reg_rtx (SImode);
15285 rtx hipart = gen_reg_rtx (HImode);
15286 rtx lopart = gen_reg_rtx (HImode);
15287 rtx tmp = gen_reg_rtx (HImode);
15288
15289 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
15290 emit_move_insn (hipart, gen_lowpart (HImode, shift));
15291 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
15292 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
15293
15294 emit_insn (gen_parityhi2_cmp (tmp));
15295
15296 ix86_expand_setcc (scratch, ORDERED,
15297 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
15298
15299 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15300 DONE;
15301 })
15302
15303 (define_expand "parityhi2"
15304 [(set (match_operand:HI 0 "register_operand")
15305 (parity:HI (match_operand:HI 1 "register_operand")))]
15306 "! TARGET_POPCNT"
15307 {
15308 rtx scratch = gen_reg_rtx (QImode);
15309
15310 emit_insn (gen_parityhi2_cmp (operands[1]));
15311
15312 ix86_expand_setcc (scratch, ORDERED,
15313 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
15314
15315 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
15316 DONE;
15317 })
15318
15319 (define_expand "parityqi2"
15320 [(set (match_operand:QI 0 "register_operand")
15321 (parity:QI (match_operand:QI 1 "register_operand")))]
15322 "! TARGET_POPCNT"
15323 {
15324 emit_insn (gen_parityqi2_cmp (operands[1]));
15325
15326 ix86_expand_setcc (operands[0], ORDERED,
15327 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
15328 DONE;
15329 })
15330
15331 (define_insn "parityhi2_cmp"
15332 [(set (reg:CC FLAGS_REG)
15333 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
15334 UNSPEC_PARITY))
15335 (clobber (match_dup 0))]
15336 ""
15337 "xor{b}\t{%h0, %b0|%b0, %h0}"
15338 [(set_attr "length" "2")
15339 (set_attr "mode" "QI")])
15340
15341 (define_insn "parityqi2_cmp"
15342 [(set (reg:CC FLAGS_REG)
15343 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
15344 UNSPEC_PARITY))]
15345 ""
15346 "test{b}\t%0, %0"
15347 [(set_attr "mode" "QI")])
15348
15349 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
15350 (define_peephole2
15351 [(set (match_operand:HI 0 "register_operand")
15352 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
15353 (parallel [(set (reg:CC FLAGS_REG)
15354 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
15355 (clobber (match_dup 0))])]
15356 ""
15357 [(set (reg:CC FLAGS_REG)
15358 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
15359
15360 ;; Eliminate QImode popcount&1 using parity flag
15361 (define_peephole2
15362 [(set (match_operand:SI 0 "register_operand")
15363 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
15364 (parallel [(set (match_operand:SI 2 "register_operand")
15365 (popcount:SI (match_dup 0)))
15366 (clobber (reg:CC FLAGS_REG))])
15367 (set (reg:CCZ FLAGS_REG)
15368 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
15369 (const_int 1))
15370 (const_int 0)))
15371 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
15372 [(reg:CCZ FLAGS_REG)
15373 (const_int 0)])
15374 (label_ref (match_operand 5))
15375 (pc)))]
15376 "REGNO (operands[2]) == REGNO (operands[3])
15377 && peep2_reg_dead_p (3, operands[0])
15378 && peep2_reg_dead_p (3, operands[2])
15379 && peep2_regno_dead_p (4, FLAGS_REG)"
15380 [(set (reg:CC FLAGS_REG)
15381 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
15382 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
15383 (const_int 0)])
15384 (label_ref (match_dup 5))
15385 (pc)))]
15386 {
15387 operands[4] = shallow_copy_rtx (operands[4]);
15388 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
15389 })
15390
15391 ;; Eliminate HImode popcount&1 using parity flag
15392 (define_peephole2
15393 [(match_scratch:HI 0 "Q")
15394 (parallel [(set (match_operand:HI 1 "register_operand")
15395 (popcount:HI
15396 (match_operand:HI 2 "nonimmediate_operand")))
15397 (clobber (reg:CC FLAGS_REG))])
15398 (set (match_operand 3 "register_operand")
15399 (zero_extend (match_dup 1)))
15400 (set (reg:CCZ FLAGS_REG)
15401 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
15402 (const_int 1))
15403 (const_int 0)))
15404 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
15405 [(reg:CCZ FLAGS_REG)
15406 (const_int 0)])
15407 (label_ref (match_operand 6))
15408 (pc)))]
15409 "REGNO (operands[3]) == REGNO (operands[4])
15410 && peep2_reg_dead_p (3, operands[1])
15411 && peep2_reg_dead_p (3, operands[3])
15412 && peep2_regno_dead_p (4, FLAGS_REG)"
15413 [(set (match_dup 0) (match_dup 2))
15414 (parallel [(set (reg:CC FLAGS_REG)
15415 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
15416 (clobber (match_dup 0))])
15417 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
15418 (const_int 0)])
15419 (label_ref (match_dup 6))
15420 (pc)))]
15421 {
15422 operands[5] = shallow_copy_rtx (operands[5]);
15423 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
15424 })
15425
15426 \f
15427 ;; Thread-local storage patterns for ELF.
15428 ;;
15429 ;; Note that these code sequences must appear exactly as shown
15430 ;; in order to allow linker relaxation.
15431
15432 (define_insn "*tls_global_dynamic_32_gnu"
15433 [(set (match_operand:SI 0 "register_operand" "=a")
15434 (unspec:SI
15435 [(match_operand:SI 1 "register_operand" "Yb")
15436 (match_operand 2 "tls_symbolic_operand")
15437 (match_operand 3 "constant_call_address_operand" "Bz")
15438 (reg:SI SP_REG)]
15439 UNSPEC_TLS_GD))
15440 (clobber (match_scratch:SI 4 "=d"))
15441 (clobber (match_scratch:SI 5 "=c"))
15442 (clobber (reg:CC FLAGS_REG))]
15443 "!TARGET_64BIT && TARGET_GNU_TLS"
15444 {
15445 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15446 output_asm_insn
15447 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
15448 else
15449 output_asm_insn
15450 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
15451 if (TARGET_SUN_TLS)
15452 #ifdef HAVE_AS_IX86_TLSGDPLT
15453 return "call\t%a2@tlsgdplt";
15454 #else
15455 return "call\t%p3@plt";
15456 #endif
15457 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15458 return "call\t%P3";
15459 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
15460 }
15461 [(set_attr "type" "multi")
15462 (set_attr "length" "12")])
15463
15464 (define_expand "tls_global_dynamic_32"
15465 [(parallel
15466 [(set (match_operand:SI 0 "register_operand")
15467 (unspec:SI [(match_operand:SI 2 "register_operand")
15468 (match_operand 1 "tls_symbolic_operand")
15469 (match_operand 3 "constant_call_address_operand")
15470 (reg:SI SP_REG)]
15471 UNSPEC_TLS_GD))
15472 (clobber (scratch:SI))
15473 (clobber (scratch:SI))
15474 (clobber (reg:CC FLAGS_REG))])]
15475 ""
15476 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
15477
15478 (define_insn "*tls_global_dynamic_64_<mode>"
15479 [(set (match_operand:P 0 "register_operand" "=a")
15480 (call:P
15481 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
15482 (match_operand 3)))
15483 (unspec:P [(match_operand 1 "tls_symbolic_operand")
15484 (reg:P SP_REG)]
15485 UNSPEC_TLS_GD)]
15486 "TARGET_64BIT"
15487 {
15488 if (!TARGET_X32)
15489 /* The .loc directive has effect for 'the immediately following assembly
15490 instruction'. So for a sequence:
15491 .loc f l
15492 .byte x
15493 insn1
15494 the 'immediately following assembly instruction' is insn1.
15495 We want to emit an insn prefix here, but if we use .byte (as shown in
15496 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
15497 inside the insn sequence, rather than to the start. After relaxation
15498 of the sequence by the linker, the .loc might point inside an insn.
15499 Use data16 prefix instead, which doesn't have this problem. */
15500 fputs ("\tdata16", asm_out_file);
15501 output_asm_insn
15502 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
15503 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15504 fputs (ASM_SHORT "0x6666\n", asm_out_file);
15505 else
15506 fputs (ASM_BYTE "0x66\n", asm_out_file);
15507 fputs ("\trex64\n", asm_out_file);
15508 if (TARGET_SUN_TLS)
15509 return "call\t%p2@plt";
15510 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15511 return "call\t%P2";
15512 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
15513 }
15514 [(set_attr "type" "multi")
15515 (set (attr "length")
15516 (symbol_ref "TARGET_X32 ? 15 : 16"))])
15517
15518 (define_insn "*tls_global_dynamic_64_largepic"
15519 [(set (match_operand:DI 0 "register_operand" "=a")
15520 (call:DI
15521 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
15522 (match_operand:DI 3 "immediate_operand" "i")))
15523 (match_operand 4)))
15524 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
15525 (reg:DI SP_REG)]
15526 UNSPEC_TLS_GD)]
15527 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
15528 && GET_CODE (operands[3]) == CONST
15529 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
15530 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
15531 {
15532 output_asm_insn
15533 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
15534 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
15535 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
15536 return "call\t{*%%rax|rax}";
15537 }
15538 [(set_attr "type" "multi")
15539 (set_attr "length" "22")])
15540
15541 (define_expand "@tls_global_dynamic_64_<mode>"
15542 [(parallel
15543 [(set (match_operand:P 0 "register_operand")
15544 (call:P
15545 (mem:QI (match_operand 2))
15546 (const_int 0)))
15547 (unspec:P [(match_operand 1 "tls_symbolic_operand")
15548 (reg:P SP_REG)]
15549 UNSPEC_TLS_GD)])]
15550 "TARGET_64BIT"
15551 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
15552
15553 (define_insn "*tls_local_dynamic_base_32_gnu"
15554 [(set (match_operand:SI 0 "register_operand" "=a")
15555 (unspec:SI
15556 [(match_operand:SI 1 "register_operand" "Yb")
15557 (match_operand 2 "constant_call_address_operand" "Bz")
15558 (reg:SI SP_REG)]
15559 UNSPEC_TLS_LD_BASE))
15560 (clobber (match_scratch:SI 3 "=d"))
15561 (clobber (match_scratch:SI 4 "=c"))
15562 (clobber (reg:CC FLAGS_REG))]
15563 "!TARGET_64BIT && TARGET_GNU_TLS"
15564 {
15565 output_asm_insn
15566 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
15567 if (TARGET_SUN_TLS)
15568 {
15569 if (HAVE_AS_IX86_TLSLDMPLT)
15570 return "call\t%&@tlsldmplt";
15571 else
15572 return "call\t%p2@plt";
15573 }
15574 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15575 return "call\t%P2";
15576 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
15577 }
15578 [(set_attr "type" "multi")
15579 (set_attr "length" "11")])
15580
15581 (define_expand "tls_local_dynamic_base_32"
15582 [(parallel
15583 [(set (match_operand:SI 0 "register_operand")
15584 (unspec:SI
15585 [(match_operand:SI 1 "register_operand")
15586 (match_operand 2 "constant_call_address_operand")
15587 (reg:SI SP_REG)]
15588 UNSPEC_TLS_LD_BASE))
15589 (clobber (scratch:SI))
15590 (clobber (scratch:SI))
15591 (clobber (reg:CC FLAGS_REG))])]
15592 ""
15593 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
15594
15595 (define_insn "*tls_local_dynamic_base_64_<mode>"
15596 [(set (match_operand:P 0 "register_operand" "=a")
15597 (call:P
15598 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
15599 (match_operand 2)))
15600 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
15601 "TARGET_64BIT"
15602 {
15603 output_asm_insn
15604 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
15605 if (TARGET_SUN_TLS)
15606 return "call\t%p1@plt";
15607 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15608 return "call\t%P1";
15609 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
15610 }
15611 [(set_attr "type" "multi")
15612 (set_attr "length" "12")])
15613
15614 (define_insn "*tls_local_dynamic_base_64_largepic"
15615 [(set (match_operand:DI 0 "register_operand" "=a")
15616 (call:DI
15617 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
15618 (match_operand:DI 2 "immediate_operand" "i")))
15619 (match_operand 3)))
15620 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
15621 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
15622 && GET_CODE (operands[2]) == CONST
15623 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
15624 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
15625 {
15626 output_asm_insn
15627 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
15628 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
15629 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
15630 return "call\t{*%%rax|rax}";
15631 }
15632 [(set_attr "type" "multi")
15633 (set_attr "length" "22")])
15634
15635 (define_expand "@tls_local_dynamic_base_64_<mode>"
15636 [(parallel
15637 [(set (match_operand:P 0 "register_operand")
15638 (call:P
15639 (mem:QI (match_operand 1))
15640 (const_int 0)))
15641 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
15642 "TARGET_64BIT"
15643 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
15644
15645 ;; Local dynamic of a single variable is a lose. Show combine how
15646 ;; to convert that back to global dynamic.
15647
15648 (define_insn_and_split "*tls_local_dynamic_32_once"
15649 [(set (match_operand:SI 0 "register_operand" "=a")
15650 (plus:SI
15651 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15652 (match_operand 2 "constant_call_address_operand" "Bz")
15653 (reg:SI SP_REG)]
15654 UNSPEC_TLS_LD_BASE)
15655 (const:SI (unspec:SI
15656 [(match_operand 3 "tls_symbolic_operand")]
15657 UNSPEC_DTPOFF))))
15658 (clobber (match_scratch:SI 4 "=d"))
15659 (clobber (match_scratch:SI 5 "=c"))
15660 (clobber (reg:CC FLAGS_REG))]
15661 ""
15662 "#"
15663 ""
15664 [(parallel
15665 [(set (match_dup 0)
15666 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
15667 (reg:SI SP_REG)]
15668 UNSPEC_TLS_GD))
15669 (clobber (match_dup 4))
15670 (clobber (match_dup 5))
15671 (clobber (reg:CC FLAGS_REG))])])
15672
15673 ;; Load and add the thread base pointer from %<tp_seg>:0.
15674 (define_expand "get_thread_pointer<mode>"
15675 [(set (match_operand:PTR 0 "register_operand")
15676 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
15677 ""
15678 {
15679 /* targetm is not visible in the scope of the condition. */
15680 if (!targetm.have_tls)
15681 error ("%<__builtin_thread_pointer%> is not supported on this target");
15682 })
15683
15684 (define_insn_and_split "*load_tp_<mode>"
15685 [(set (match_operand:PTR 0 "register_operand" "=r")
15686 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
15687 ""
15688 "#"
15689 ""
15690 [(set (match_dup 0)
15691 (match_dup 1))]
15692 {
15693 addr_space_t as = DEFAULT_TLS_SEG_REG;
15694
15695 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
15696 set_mem_addr_space (operands[1], as);
15697 })
15698
15699 (define_insn_and_split "*load_tp_x32_zext"
15700 [(set (match_operand:DI 0 "register_operand" "=r")
15701 (zero_extend:DI
15702 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
15703 "TARGET_X32"
15704 "#"
15705 ""
15706 [(set (match_dup 0)
15707 (zero_extend:DI (match_dup 1)))]
15708 {
15709 addr_space_t as = DEFAULT_TLS_SEG_REG;
15710
15711 operands[1] = gen_const_mem (SImode, const0_rtx);
15712 set_mem_addr_space (operands[1], as);
15713 })
15714
15715 (define_insn_and_split "*add_tp_<mode>"
15716 [(set (match_operand:PTR 0 "register_operand" "=r")
15717 (plus:PTR
15718 (unspec:PTR [(const_int 0)] UNSPEC_TP)
15719 (match_operand:PTR 1 "register_operand" "0")))
15720 (clobber (reg:CC FLAGS_REG))]
15721 ""
15722 "#"
15723 ""
15724 [(parallel
15725 [(set (match_dup 0)
15726 (plus:PTR (match_dup 1) (match_dup 2)))
15727 (clobber (reg:CC FLAGS_REG))])]
15728 {
15729 addr_space_t as = DEFAULT_TLS_SEG_REG;
15730
15731 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
15732 set_mem_addr_space (operands[2], as);
15733 })
15734
15735 (define_insn_and_split "*add_tp_x32_zext"
15736 [(set (match_operand:DI 0 "register_operand" "=r")
15737 (zero_extend:DI
15738 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15739 (match_operand:SI 1 "register_operand" "0"))))
15740 (clobber (reg:CC FLAGS_REG))]
15741 "TARGET_X32"
15742 "#"
15743 ""
15744 [(parallel
15745 [(set (match_dup 0)
15746 (zero_extend:DI
15747 (plus:SI (match_dup 1) (match_dup 2))))
15748 (clobber (reg:CC FLAGS_REG))])]
15749 {
15750 addr_space_t as = DEFAULT_TLS_SEG_REG;
15751
15752 operands[2] = gen_const_mem (SImode, const0_rtx);
15753 set_mem_addr_space (operands[2], as);
15754 })
15755
15756 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
15757 ;; %rax as destination of the initial executable code sequence.
15758 (define_insn "tls_initial_exec_64_sun"
15759 [(set (match_operand:DI 0 "register_operand" "=a")
15760 (unspec:DI
15761 [(match_operand 1 "tls_symbolic_operand")]
15762 UNSPEC_TLS_IE_SUN))
15763 (clobber (reg:CC FLAGS_REG))]
15764 "TARGET_64BIT && TARGET_SUN_TLS"
15765 {
15766 output_asm_insn
15767 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
15768 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
15769 }
15770 [(set_attr "type" "multi")])
15771
15772 ;; GNU2 TLS patterns can be split.
15773
15774 (define_expand "tls_dynamic_gnu2_32"
15775 [(set (match_dup 3)
15776 (plus:SI (match_operand:SI 2 "register_operand")
15777 (const:SI
15778 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
15779 UNSPEC_TLSDESC))))
15780 (parallel
15781 [(set (match_operand:SI 0 "register_operand")
15782 (unspec:SI [(match_dup 1) (match_dup 3)
15783 (match_dup 2) (reg:SI SP_REG)]
15784 UNSPEC_TLSDESC))
15785 (clobber (reg:CC FLAGS_REG))])]
15786 "!TARGET_64BIT && TARGET_GNU2_TLS"
15787 {
15788 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15789 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15790 })
15791
15792 (define_insn "*tls_dynamic_gnu2_lea_32"
15793 [(set (match_operand:SI 0 "register_operand" "=r")
15794 (plus:SI (match_operand:SI 1 "register_operand" "b")
15795 (const:SI
15796 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
15797 UNSPEC_TLSDESC))))]
15798 "!TARGET_64BIT && TARGET_GNU2_TLS"
15799 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
15800 [(set_attr "type" "lea")
15801 (set_attr "mode" "SI")
15802 (set_attr "length" "6")
15803 (set_attr "length_address" "4")])
15804
15805 (define_insn "*tls_dynamic_gnu2_call_32"
15806 [(set (match_operand:SI 0 "register_operand" "=a")
15807 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
15808 (match_operand:SI 2 "register_operand" "0")
15809 ;; we have to make sure %ebx still points to the GOT
15810 (match_operand:SI 3 "register_operand" "b")
15811 (reg:SI SP_REG)]
15812 UNSPEC_TLSDESC))
15813 (clobber (reg:CC FLAGS_REG))]
15814 "!TARGET_64BIT && TARGET_GNU2_TLS"
15815 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15816 [(set_attr "type" "call")
15817 (set_attr "length" "2")
15818 (set_attr "length_address" "0")])
15819
15820 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15821 [(set (match_operand:SI 0 "register_operand" "=&a")
15822 (plus:SI
15823 (unspec:SI [(match_operand 3 "tls_modbase_operand")
15824 (match_operand:SI 4)
15825 (match_operand:SI 2 "register_operand" "b")
15826 (reg:SI SP_REG)]
15827 UNSPEC_TLSDESC)
15828 (const:SI (unspec:SI
15829 [(match_operand 1 "tls_symbolic_operand")]
15830 UNSPEC_DTPOFF))))
15831 (clobber (reg:CC FLAGS_REG))]
15832 "!TARGET_64BIT && TARGET_GNU2_TLS"
15833 "#"
15834 ""
15835 [(set (match_dup 0) (match_dup 5))]
15836 {
15837 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15838 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15839 })
15840
15841 (define_expand "@tls_dynamic_gnu2_64_<mode>"
15842 [(set (match_dup 2)
15843 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
15844 UNSPEC_TLSDESC))
15845 (parallel
15846 [(set (match_operand:PTR 0 "register_operand")
15847 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
15848 UNSPEC_TLSDESC))
15849 (clobber (reg:CC FLAGS_REG))])]
15850 "TARGET_64BIT && TARGET_GNU2_TLS"
15851 {
15852 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
15853 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15854 })
15855
15856 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
15857 [(set (match_operand:PTR 0 "register_operand" "=r")
15858 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
15859 UNSPEC_TLSDESC))]
15860 "TARGET_64BIT && TARGET_GNU2_TLS"
15861 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
15862 [(set_attr "type" "lea")
15863 (set_attr "mode" "<MODE>")
15864 (set_attr "length" "7")
15865 (set_attr "length_address" "4")])
15866
15867 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
15868 [(set (match_operand:PTR 0 "register_operand" "=a")
15869 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
15870 (match_operand:PTR 2 "register_operand" "0")
15871 (reg:PTR SP_REG)]
15872 UNSPEC_TLSDESC))
15873 (clobber (reg:CC FLAGS_REG))]
15874 "TARGET_64BIT && TARGET_GNU2_TLS"
15875 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15876 [(set_attr "type" "call")
15877 (set_attr "length" "2")
15878 (set_attr "length_address" "0")])
15879
15880 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
15881 [(set (match_operand:PTR 0 "register_operand" "=&a")
15882 (plus:PTR
15883 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
15884 (match_operand:PTR 3)
15885 (reg:PTR SP_REG)]
15886 UNSPEC_TLSDESC)
15887 (const:PTR (unspec:PTR
15888 [(match_operand 1 "tls_symbolic_operand")]
15889 UNSPEC_DTPOFF))))
15890 (clobber (reg:CC FLAGS_REG))]
15891 "TARGET_64BIT && TARGET_GNU2_TLS"
15892 "#"
15893 ""
15894 [(set (match_dup 0) (match_dup 4))]
15895 {
15896 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
15897 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
15898 })
15899
15900 (define_split
15901 [(match_operand 0 "tls_address_pattern")]
15902 "TARGET_TLS_DIRECT_SEG_REFS"
15903 [(match_dup 0)]
15904 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
15905
15906 \f
15907 ;; These patterns match the binary 387 instructions for addM3, subM3,
15908 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15909 ;; SFmode. The first is the normal insn, the second the same insn but
15910 ;; with one operand a conversion, and the third the same insn but with
15911 ;; the other operand a conversion. The conversion may be SFmode or
15912 ;; SImode if the target mode DFmode, but only SImode if the target mode
15913 ;; is SFmode.
15914
15915 ;; Gcc is slightly more smart about handling normal two address instructions
15916 ;; so use special patterns for add and mull.
15917
15918 (define_insn "*fop_xf_comm_i387"
15919 [(set (match_operand:XF 0 "register_operand" "=f")
15920 (match_operator:XF 3 "binary_fp_operator"
15921 [(match_operand:XF 1 "register_operand" "%0")
15922 (match_operand:XF 2 "register_operand" "f")]))]
15923 "TARGET_80387
15924 && COMMUTATIVE_ARITH_P (operands[3])"
15925 "* return output_387_binary_op (insn, operands);"
15926 [(set (attr "type")
15927 (if_then_else (match_operand:XF 3 "mult_operator")
15928 (const_string "fmul")
15929 (const_string "fop")))
15930 (set_attr "mode" "XF")])
15931
15932 (define_insn "*fop_<mode>_comm"
15933 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
15934 (match_operator:MODEF 3 "binary_fp_operator"
15935 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
15936 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
15937 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15938 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15939 && COMMUTATIVE_ARITH_P (operands[3])
15940 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15941 "* return output_387_binary_op (insn, operands);"
15942 [(set (attr "type")
15943 (if_then_else (eq_attr "alternative" "1,2")
15944 (if_then_else (match_operand:MODEF 3 "mult_operator")
15945 (const_string "ssemul")
15946 (const_string "sseadd"))
15947 (if_then_else (match_operand:MODEF 3 "mult_operator")
15948 (const_string "fmul")
15949 (const_string "fop"))))
15950 (set_attr "isa" "*,noavx,avx")
15951 (set_attr "prefix" "orig,orig,vex")
15952 (set_attr "mode" "<MODE>")
15953 (set (attr "enabled")
15954 (if_then_else
15955 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15956 (if_then_else
15957 (eq_attr "alternative" "0")
15958 (symbol_ref "TARGET_MIX_SSE_I387
15959 && X87_ENABLE_ARITH (<MODE>mode)")
15960 (const_string "*"))
15961 (if_then_else
15962 (eq_attr "alternative" "0")
15963 (symbol_ref "true")
15964 (symbol_ref "false"))))])
15965
15966 (define_insn "*rcpsf2_sse"
15967 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
15968 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
15969 UNSPEC_RCP))]
15970 "TARGET_SSE && TARGET_SSE_MATH"
15971 "@
15972 %vrcpss\t{%d1, %0|%0, %d1}
15973 %vrcpss\t{%d1, %0|%0, %d1}
15974 %vrcpss\t{%1, %d0|%d0, %1}"
15975 [(set_attr "type" "sse")
15976 (set_attr "atom_sse_attr" "rcp")
15977 (set_attr "btver2_sse_attr" "rcp")
15978 (set_attr "prefix" "maybe_vex")
15979 (set_attr "mode" "SF")
15980 (set_attr "avx_partial_xmm_update" "false,false,true")
15981 (set (attr "preferred_for_speed")
15982 (cond [(match_test "TARGET_AVX")
15983 (symbol_ref "true")
15984 (eq_attr "alternative" "1,2")
15985 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
15986 ]
15987 (symbol_ref "true")))])
15988
15989 (define_insn "*fop_xf_1_i387"
15990 [(set (match_operand:XF 0 "register_operand" "=f,f")
15991 (match_operator:XF 3 "binary_fp_operator"
15992 [(match_operand:XF 1 "register_operand" "0,f")
15993 (match_operand:XF 2 "register_operand" "f,0")]))]
15994 "TARGET_80387
15995 && !COMMUTATIVE_ARITH_P (operands[3])"
15996 "* return output_387_binary_op (insn, operands);"
15997 [(set (attr "type")
15998 (if_then_else (match_operand:XF 3 "div_operator")
15999 (const_string "fdiv")
16000 (const_string "fop")))
16001 (set_attr "mode" "XF")])
16002
16003 (define_insn "*fop_<mode>_1"
16004 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
16005 (match_operator:MODEF 3 "binary_fp_operator"
16006 [(match_operand:MODEF 1
16007 "x87nonimm_ssenomem_operand" "0,fm,0,v")
16008 (match_operand:MODEF 2
16009 "nonimmediate_operand" "fm,0,xm,vm")]))]
16010 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16011 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
16012 && !COMMUTATIVE_ARITH_P (operands[3])
16013 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16014 "* return output_387_binary_op (insn, operands);"
16015 [(set (attr "type")
16016 (if_then_else (eq_attr "alternative" "2,3")
16017 (if_then_else (match_operand:MODEF 3 "div_operator")
16018 (const_string "ssediv")
16019 (const_string "sseadd"))
16020 (if_then_else (match_operand:MODEF 3 "div_operator")
16021 (const_string "fdiv")
16022 (const_string "fop"))))
16023 (set_attr "isa" "*,*,noavx,avx")
16024 (set_attr "prefix" "orig,orig,orig,vex")
16025 (set_attr "mode" "<MODE>")
16026 (set (attr "enabled")
16027 (if_then_else
16028 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
16029 (if_then_else
16030 (eq_attr "alternative" "0,1")
16031 (symbol_ref "TARGET_MIX_SSE_I387
16032 && X87_ENABLE_ARITH (<MODE>mode)")
16033 (const_string "*"))
16034 (if_then_else
16035 (eq_attr "alternative" "0,1")
16036 (symbol_ref "true")
16037 (symbol_ref "false"))))])
16038
16039 (define_insn "*fop_<X87MODEF:mode>_2_i387"
16040 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16041 (match_operator:X87MODEF 3 "binary_fp_operator"
16042 [(float:X87MODEF
16043 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
16044 (match_operand:X87MODEF 2 "register_operand" "0")]))]
16045 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
16046 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16047 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
16048 || optimize_function_for_size_p (cfun))"
16049 "* return output_387_binary_op (insn, operands);"
16050 [(set (attr "type")
16051 (cond [(match_operand:X87MODEF 3 "mult_operator")
16052 (const_string "fmul")
16053 (match_operand:X87MODEF 3 "div_operator")
16054 (const_string "fdiv")
16055 ]
16056 (const_string "fop")))
16057 (set_attr "fp_int_src" "true")
16058 (set_attr "mode" "<SWI24:MODE>")])
16059
16060 (define_insn "*fop_<X87MODEF:mode>_3_i387"
16061 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16062 (match_operator:X87MODEF 3 "binary_fp_operator"
16063 [(match_operand:X87MODEF 1 "register_operand" "0")
16064 (float:X87MODEF
16065 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
16066 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
16067 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16068 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
16069 || optimize_function_for_size_p (cfun))"
16070 "* return output_387_binary_op (insn, operands);"
16071 [(set (attr "type")
16072 (cond [(match_operand:X87MODEF 3 "mult_operator")
16073 (const_string "fmul")
16074 (match_operand:X87MODEF 3 "div_operator")
16075 (const_string "fdiv")
16076 ]
16077 (const_string "fop")))
16078 (set_attr "fp_int_src" "true")
16079 (set_attr "mode" "<SWI24:MODE>")])
16080
16081 (define_insn "*fop_xf_4_i387"
16082 [(set (match_operand:XF 0 "register_operand" "=f,f")
16083 (match_operator:XF 3 "binary_fp_operator"
16084 [(float_extend:XF
16085 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16086 (match_operand:XF 2 "register_operand" "0,f")]))]
16087 "TARGET_80387"
16088 "* return output_387_binary_op (insn, operands);"
16089 [(set (attr "type")
16090 (cond [(match_operand:XF 3 "mult_operator")
16091 (const_string "fmul")
16092 (match_operand:XF 3 "div_operator")
16093 (const_string "fdiv")
16094 ]
16095 (const_string "fop")))
16096 (set_attr "mode" "<MODE>")])
16097
16098 (define_insn "*fop_df_4_i387"
16099 [(set (match_operand:DF 0 "register_operand" "=f,f")
16100 (match_operator:DF 3 "binary_fp_operator"
16101 [(float_extend:DF
16102 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16103 (match_operand:DF 2 "register_operand" "0,f")]))]
16104 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16105 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16106 "* return output_387_binary_op (insn, operands);"
16107 [(set (attr "type")
16108 (cond [(match_operand:DF 3 "mult_operator")
16109 (const_string "fmul")
16110 (match_operand:DF 3 "div_operator")
16111 (const_string "fdiv")
16112 ]
16113 (const_string "fop")))
16114 (set_attr "mode" "SF")])
16115
16116 (define_insn "*fop_xf_5_i387"
16117 [(set (match_operand:XF 0 "register_operand" "=f,f")
16118 (match_operator:XF 3 "binary_fp_operator"
16119 [(match_operand:XF 1 "register_operand" "0,f")
16120 (float_extend:XF
16121 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16122 "TARGET_80387"
16123 "* return output_387_binary_op (insn, operands);"
16124 [(set (attr "type")
16125 (cond [(match_operand:XF 3 "mult_operator")
16126 (const_string "fmul")
16127 (match_operand:XF 3 "div_operator")
16128 (const_string "fdiv")
16129 ]
16130 (const_string "fop")))
16131 (set_attr "mode" "<MODE>")])
16132
16133 (define_insn "*fop_df_5_i387"
16134 [(set (match_operand:DF 0 "register_operand" "=f,f")
16135 (match_operator:DF 3 "binary_fp_operator"
16136 [(match_operand:DF 1 "register_operand" "0,f")
16137 (float_extend:DF
16138 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16139 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16140 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16141 "* return output_387_binary_op (insn, operands);"
16142 [(set (attr "type")
16143 (cond [(match_operand:DF 3 "mult_operator")
16144 (const_string "fmul")
16145 (match_operand:DF 3 "div_operator")
16146 (const_string "fdiv")
16147 ]
16148 (const_string "fop")))
16149 (set_attr "mode" "SF")])
16150
16151 (define_insn "*fop_xf_6_i387"
16152 [(set (match_operand:XF 0 "register_operand" "=f,f")
16153 (match_operator:XF 3 "binary_fp_operator"
16154 [(float_extend:XF
16155 (match_operand:MODEF 1 "register_operand" "0,f"))
16156 (float_extend:XF
16157 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16158 "TARGET_80387"
16159 "* return output_387_binary_op (insn, operands);"
16160 [(set (attr "type")
16161 (cond [(match_operand:XF 3 "mult_operator")
16162 (const_string "fmul")
16163 (match_operand:XF 3 "div_operator")
16164 (const_string "fdiv")
16165 ]
16166 (const_string "fop")))
16167 (set_attr "mode" "<MODE>")])
16168
16169 (define_insn "*fop_df_6_i387"
16170 [(set (match_operand:DF 0 "register_operand" "=f,f")
16171 (match_operator:DF 3 "binary_fp_operator"
16172 [(float_extend:DF
16173 (match_operand:SF 1 "register_operand" "0,f"))
16174 (float_extend:DF
16175 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16176 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16177 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16178 "* return output_387_binary_op (insn, operands);"
16179 [(set (attr "type")
16180 (cond [(match_operand:DF 3 "mult_operator")
16181 (const_string "fmul")
16182 (match_operand:DF 3 "div_operator")
16183 (const_string "fdiv")
16184 ]
16185 (const_string "fop")))
16186 (set_attr "mode" "SF")])
16187 \f
16188 ;; FPU special functions.
16189
16190 ;; This pattern implements a no-op XFmode truncation for
16191 ;; all fancy i386 XFmode math functions.
16192
16193 (define_insn "truncxf<mode>2_i387_noop_unspec"
16194 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
16195 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16196 UNSPEC_TRUNC_NOOP))]
16197 "TARGET_USE_FANCY_MATH_387"
16198 "* return output_387_reg_move (insn, operands);"
16199 [(set_attr "type" "fmov")
16200 (set_attr "mode" "<MODE>")])
16201
16202 (define_insn "sqrtxf2"
16203 [(set (match_operand:XF 0 "register_operand" "=f")
16204 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16205 "TARGET_USE_FANCY_MATH_387"
16206 "fsqrt"
16207 [(set_attr "type" "fpspc")
16208 (set_attr "mode" "XF")
16209 (set_attr "athlon_decode" "direct")
16210 (set_attr "amdfam10_decode" "direct")
16211 (set_attr "bdver1_decode" "direct")])
16212
16213 (define_insn "*rsqrtsf2_sse"
16214 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
16215 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
16216 UNSPEC_RSQRT))]
16217 "TARGET_SSE && TARGET_SSE_MATH"
16218 "@
16219 %vrsqrtss\t{%d1, %0|%0, %d1}
16220 %vrsqrtss\t{%d1, %0|%0, %d1}
16221 %vrsqrtss\t{%1, %d0|%d0, %1}"
16222 [(set_attr "type" "sse")
16223 (set_attr "atom_sse_attr" "rcp")
16224 (set_attr "btver2_sse_attr" "rcp")
16225 (set_attr "prefix" "maybe_vex")
16226 (set_attr "mode" "SF")
16227 (set_attr "avx_partial_xmm_update" "false,false,true")
16228 (set (attr "preferred_for_speed")
16229 (cond [(match_test "TARGET_AVX")
16230 (symbol_ref "true")
16231 (eq_attr "alternative" "1,2")
16232 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16233 ]
16234 (symbol_ref "true")))])
16235
16236 (define_expand "rsqrtsf2"
16237 [(set (match_operand:SF 0 "register_operand")
16238 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
16239 UNSPEC_RSQRT))]
16240 "TARGET_SSE && TARGET_SSE_MATH"
16241 {
16242 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16243 DONE;
16244 })
16245
16246 (define_insn "*sqrt<mode>2_sse"
16247 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
16248 (sqrt:MODEF
16249 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
16250 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16251 "@
16252 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
16253 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
16254 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
16255 [(set_attr "type" "sse")
16256 (set_attr "atom_sse_attr" "sqrt")
16257 (set_attr "btver2_sse_attr" "sqrt")
16258 (set_attr "prefix" "maybe_vex")
16259 (set_attr "avx_partial_xmm_update" "false,false,true")
16260 (set_attr "mode" "<MODE>")
16261 (set (attr "preferred_for_speed")
16262 (cond [(match_test "TARGET_AVX")
16263 (symbol_ref "true")
16264 (eq_attr "alternative" "1,2")
16265 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16266 ]
16267 (symbol_ref "true")))])
16268
16269 (define_expand "sqrt<mode>2"
16270 [(set (match_operand:MODEF 0 "register_operand")
16271 (sqrt:MODEF
16272 (match_operand:MODEF 1 "nonimmediate_operand")))]
16273 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16274 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16275 {
16276 if (<MODE>mode == SFmode
16277 && TARGET_SSE && TARGET_SSE_MATH
16278 && TARGET_RECIP_SQRT
16279 && !optimize_function_for_size_p (cfun)
16280 && flag_finite_math_only && !flag_trapping_math
16281 && flag_unsafe_math_optimizations)
16282 {
16283 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16284 DONE;
16285 }
16286
16287 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16288 {
16289 rtx op0 = gen_reg_rtx (XFmode);
16290 rtx op1 = gen_reg_rtx (XFmode);
16291
16292 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16293 emit_insn (gen_sqrtxf2 (op0, op1));
16294 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16295 DONE;
16296 }
16297 })
16298
16299 (define_expand "hypot<mode>3"
16300 [(use (match_operand:MODEF 0 "register_operand"))
16301 (use (match_operand:MODEF 1 "general_operand"))
16302 (use (match_operand:MODEF 2 "general_operand"))]
16303 "TARGET_USE_FANCY_MATH_387
16304 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16305 || TARGET_MIX_SSE_I387)
16306 && flag_finite_math_only
16307 && flag_unsafe_math_optimizations"
16308 {
16309 rtx op0 = gen_reg_rtx (XFmode);
16310 rtx op1 = gen_reg_rtx (XFmode);
16311 rtx op2 = gen_reg_rtx (XFmode);
16312
16313 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16314 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16315
16316 emit_insn (gen_mulxf3 (op1, op1, op1));
16317 emit_insn (gen_mulxf3 (op2, op2, op2));
16318 emit_insn (gen_addxf3 (op0, op2, op1));
16319 emit_insn (gen_sqrtxf2 (op0, op0));
16320
16321 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16322 DONE;
16323 })
16324
16325 (define_insn "x86_fnstsw_1"
16326 [(set (match_operand:HI 0 "register_operand" "=a")
16327 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
16328 "TARGET_80387"
16329 "fnstsw\t%0"
16330 [(set_attr "length" "2")
16331 (set_attr "mode" "SI")
16332 (set_attr "unit" "i387")])
16333
16334 (define_insn "fpremxf4_i387"
16335 [(set (match_operand:XF 0 "register_operand" "=f")
16336 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16337 (match_operand:XF 3 "register_operand" "1")]
16338 UNSPEC_FPREM_F))
16339 (set (match_operand:XF 1 "register_operand" "=f")
16340 (unspec:XF [(match_dup 2) (match_dup 3)]
16341 UNSPEC_FPREM_U))
16342 (set (reg:CCFP FPSR_REG)
16343 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16344 UNSPEC_C2_FLAG))]
16345 "TARGET_USE_FANCY_MATH_387
16346 && flag_finite_math_only"
16347 "fprem"
16348 [(set_attr "type" "fpspc")
16349 (set_attr "znver1_decode" "vector")
16350 (set_attr "mode" "XF")])
16351
16352 (define_expand "fmodxf3"
16353 [(use (match_operand:XF 0 "register_operand"))
16354 (use (match_operand:XF 1 "general_operand"))
16355 (use (match_operand:XF 2 "general_operand"))]
16356 "TARGET_USE_FANCY_MATH_387
16357 && flag_finite_math_only"
16358 {
16359 rtx_code_label *label = gen_label_rtx ();
16360
16361 rtx op1 = gen_reg_rtx (XFmode);
16362 rtx op2 = gen_reg_rtx (XFmode);
16363
16364 emit_move_insn (op2, operands[2]);
16365 emit_move_insn (op1, operands[1]);
16366
16367 emit_label (label);
16368 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16369 ix86_emit_fp_unordered_jump (label);
16370 LABEL_NUSES (label) = 1;
16371
16372 emit_move_insn (operands[0], op1);
16373 DONE;
16374 })
16375
16376 (define_expand "fmod<mode>3"
16377 [(use (match_operand:MODEF 0 "register_operand"))
16378 (use (match_operand:MODEF 1 "general_operand"))
16379 (use (match_operand:MODEF 2 "general_operand"))]
16380 "TARGET_USE_FANCY_MATH_387
16381 && flag_finite_math_only"
16382 {
16383 rtx (*gen_truncxf) (rtx, rtx);
16384
16385 rtx_code_label *label = gen_label_rtx ();
16386
16387 rtx op1 = gen_reg_rtx (XFmode);
16388 rtx op2 = gen_reg_rtx (XFmode);
16389
16390 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16391 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16392
16393 emit_label (label);
16394 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16395 ix86_emit_fp_unordered_jump (label);
16396 LABEL_NUSES (label) = 1;
16397
16398 /* Truncate the result properly for strict SSE math. */
16399 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16400 && !TARGET_MIX_SSE_I387)
16401 gen_truncxf = gen_truncxf<mode>2;
16402 else
16403 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
16404
16405 emit_insn (gen_truncxf (operands[0], op1));
16406 DONE;
16407 })
16408
16409 (define_insn "fprem1xf4_i387"
16410 [(set (match_operand:XF 0 "register_operand" "=f")
16411 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16412 (match_operand:XF 3 "register_operand" "1")]
16413 UNSPEC_FPREM1_F))
16414 (set (match_operand:XF 1 "register_operand" "=f")
16415 (unspec:XF [(match_dup 2) (match_dup 3)]
16416 UNSPEC_FPREM1_U))
16417 (set (reg:CCFP FPSR_REG)
16418 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16419 UNSPEC_C2_FLAG))]
16420 "TARGET_USE_FANCY_MATH_387
16421 && flag_finite_math_only"
16422 "fprem1"
16423 [(set_attr "type" "fpspc")
16424 (set_attr "znver1_decode" "vector")
16425 (set_attr "mode" "XF")])
16426
16427 (define_expand "remainderxf3"
16428 [(use (match_operand:XF 0 "register_operand"))
16429 (use (match_operand:XF 1 "general_operand"))
16430 (use (match_operand:XF 2 "general_operand"))]
16431 "TARGET_USE_FANCY_MATH_387
16432 && flag_finite_math_only"
16433 {
16434 rtx_code_label *label = gen_label_rtx ();
16435
16436 rtx op1 = gen_reg_rtx (XFmode);
16437 rtx op2 = gen_reg_rtx (XFmode);
16438
16439 emit_move_insn (op2, operands[2]);
16440 emit_move_insn (op1, operands[1]);
16441
16442 emit_label (label);
16443 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16444 ix86_emit_fp_unordered_jump (label);
16445 LABEL_NUSES (label) = 1;
16446
16447 emit_move_insn (operands[0], op1);
16448 DONE;
16449 })
16450
16451 (define_expand "remainder<mode>3"
16452 [(use (match_operand:MODEF 0 "register_operand"))
16453 (use (match_operand:MODEF 1 "general_operand"))
16454 (use (match_operand:MODEF 2 "general_operand"))]
16455 "TARGET_USE_FANCY_MATH_387
16456 && flag_finite_math_only"
16457 {
16458 rtx (*gen_truncxf) (rtx, rtx);
16459
16460 rtx_code_label *label = gen_label_rtx ();
16461
16462 rtx op1 = gen_reg_rtx (XFmode);
16463 rtx op2 = gen_reg_rtx (XFmode);
16464
16465 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16466 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16467
16468 emit_label (label);
16469
16470 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16471 ix86_emit_fp_unordered_jump (label);
16472 LABEL_NUSES (label) = 1;
16473
16474 /* Truncate the result properly for strict SSE math. */
16475 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16476 && !TARGET_MIX_SSE_I387)
16477 gen_truncxf = gen_truncxf<mode>2;
16478 else
16479 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
16480
16481 emit_insn (gen_truncxf (operands[0], op1));
16482 DONE;
16483 })
16484
16485 (define_int_iterator SINCOS
16486 [UNSPEC_SIN
16487 UNSPEC_COS])
16488
16489 (define_int_attr sincos
16490 [(UNSPEC_SIN "sin")
16491 (UNSPEC_COS "cos")])
16492
16493 (define_insn "<sincos>xf2"
16494 [(set (match_operand:XF 0 "register_operand" "=f")
16495 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16496 SINCOS))]
16497 "TARGET_USE_FANCY_MATH_387
16498 && flag_unsafe_math_optimizations"
16499 "f<sincos>"
16500 [(set_attr "type" "fpspc")
16501 (set_attr "znver1_decode" "vector")
16502 (set_attr "mode" "XF")])
16503
16504 (define_expand "<sincos><mode>2"
16505 [(set (match_operand:MODEF 0 "register_operand")
16506 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
16507 SINCOS))]
16508 "TARGET_USE_FANCY_MATH_387
16509 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16510 || TARGET_MIX_SSE_I387)
16511 && flag_unsafe_math_optimizations"
16512 {
16513 rtx op0 = gen_reg_rtx (XFmode);
16514 rtx op1 = gen_reg_rtx (XFmode);
16515
16516 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16517 emit_insn (gen_<sincos>xf2 (op0, op1));
16518 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16519 DONE;
16520 })
16521
16522 (define_insn "sincosxf3"
16523 [(set (match_operand:XF 0 "register_operand" "=f")
16524 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16525 UNSPEC_SINCOS_COS))
16526 (set (match_operand:XF 1 "register_operand" "=f")
16527 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16528 "TARGET_USE_FANCY_MATH_387
16529 && flag_unsafe_math_optimizations"
16530 "fsincos"
16531 [(set_attr "type" "fpspc")
16532 (set_attr "znver1_decode" "vector")
16533 (set_attr "mode" "XF")])
16534
16535 (define_expand "sincos<mode>3"
16536 [(use (match_operand:MODEF 0 "register_operand"))
16537 (use (match_operand:MODEF 1 "register_operand"))
16538 (use (match_operand:MODEF 2 "general_operand"))]
16539 "TARGET_USE_FANCY_MATH_387
16540 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16541 || TARGET_MIX_SSE_I387)
16542 && flag_unsafe_math_optimizations"
16543 {
16544 rtx op0 = gen_reg_rtx (XFmode);
16545 rtx op1 = gen_reg_rtx (XFmode);
16546 rtx op2 = gen_reg_rtx (XFmode);
16547
16548 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16549 emit_insn (gen_sincosxf3 (op0, op1, op2));
16550 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16551 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
16552 DONE;
16553 })
16554
16555 (define_insn "fptanxf4_i387"
16556 [(set (match_operand:SF 0 "register_operand" "=f")
16557 (match_operand:SF 3 "const1_operand"))
16558 (set (match_operand:XF 1 "register_operand" "=f")
16559 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16560 UNSPEC_TAN))]
16561 "TARGET_USE_FANCY_MATH_387
16562 && flag_unsafe_math_optimizations"
16563 "fptan"
16564 [(set_attr "type" "fpspc")
16565 (set_attr "znver1_decode" "vector")
16566 (set_attr "mode" "XF")])
16567
16568 (define_expand "tanxf2"
16569 [(use (match_operand:XF 0 "register_operand"))
16570 (use (match_operand:XF 1 "register_operand"))]
16571 "TARGET_USE_FANCY_MATH_387
16572 && flag_unsafe_math_optimizations"
16573 {
16574 rtx one = gen_reg_rtx (SFmode);
16575 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
16576 CONST1_RTX (SFmode)));
16577 DONE;
16578 })
16579
16580 (define_expand "tan<mode>2"
16581 [(use (match_operand:MODEF 0 "register_operand"))
16582 (use (match_operand:MODEF 1 "general_operand"))]
16583 "TARGET_USE_FANCY_MATH_387
16584 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16585 || TARGET_MIX_SSE_I387)
16586 && flag_unsafe_math_optimizations"
16587 {
16588 rtx op0 = gen_reg_rtx (XFmode);
16589 rtx op1 = gen_reg_rtx (XFmode);
16590
16591 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16592 emit_insn (gen_tanxf2 (op0, op1));
16593 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16594 DONE;
16595 })
16596
16597 (define_insn "atan2xf3"
16598 [(set (match_operand:XF 0 "register_operand" "=f")
16599 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16600 (match_operand:XF 1 "register_operand" "f")]
16601 UNSPEC_FPATAN))
16602 (clobber (match_scratch:XF 3 "=1"))]
16603 "TARGET_USE_FANCY_MATH_387
16604 && flag_unsafe_math_optimizations"
16605 "fpatan"
16606 [(set_attr "type" "fpspc")
16607 (set_attr "znver1_decode" "vector")
16608 (set_attr "mode" "XF")])
16609
16610 (define_expand "atan2<mode>3"
16611 [(use (match_operand:MODEF 0 "register_operand"))
16612 (use (match_operand:MODEF 1 "general_operand"))
16613 (use (match_operand:MODEF 2 "general_operand"))]
16614 "TARGET_USE_FANCY_MATH_387
16615 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16616 || TARGET_MIX_SSE_I387)
16617 && flag_unsafe_math_optimizations"
16618 {
16619 rtx op0 = gen_reg_rtx (XFmode);
16620 rtx op1 = gen_reg_rtx (XFmode);
16621 rtx op2 = gen_reg_rtx (XFmode);
16622
16623 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16624 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16625
16626 emit_insn (gen_atan2xf3 (op0, op1, op2));
16627 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16628 DONE;
16629 })
16630
16631 (define_expand "atanxf2"
16632 [(parallel [(set (match_operand:XF 0 "register_operand")
16633 (unspec:XF [(match_dup 2)
16634 (match_operand:XF 1 "register_operand")]
16635 UNSPEC_FPATAN))
16636 (clobber (scratch:XF))])]
16637 "TARGET_USE_FANCY_MATH_387
16638 && flag_unsafe_math_optimizations"
16639 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
16640
16641 (define_expand "atan<mode>2"
16642 [(use (match_operand:MODEF 0 "register_operand"))
16643 (use (match_operand:MODEF 1 "general_operand"))]
16644 "TARGET_USE_FANCY_MATH_387
16645 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16646 || TARGET_MIX_SSE_I387)
16647 && flag_unsafe_math_optimizations"
16648 {
16649 rtx op0 = gen_reg_rtx (XFmode);
16650 rtx op1 = gen_reg_rtx (XFmode);
16651
16652 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16653 emit_insn (gen_atanxf2 (op0, op1));
16654 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16655 DONE;
16656 })
16657
16658 (define_expand "asinxf2"
16659 [(set (match_dup 2)
16660 (mult:XF (match_operand:XF 1 "register_operand")
16661 (match_dup 1)))
16662 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16663 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16664 (parallel [(set (match_operand:XF 0 "register_operand")
16665 (unspec:XF [(match_dup 5) (match_dup 1)]
16666 UNSPEC_FPATAN))
16667 (clobber (scratch:XF))])]
16668 "TARGET_USE_FANCY_MATH_387
16669 && flag_unsafe_math_optimizations"
16670 {
16671 int i;
16672
16673 for (i = 2; i < 6; i++)
16674 operands[i] = gen_reg_rtx (XFmode);
16675
16676 emit_move_insn (operands[3], CONST1_RTX (XFmode));
16677 })
16678
16679 (define_expand "asin<mode>2"
16680 [(use (match_operand:MODEF 0 "register_operand"))
16681 (use (match_operand:MODEF 1 "general_operand"))]
16682 "TARGET_USE_FANCY_MATH_387
16683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16684 || TARGET_MIX_SSE_I387)
16685 && flag_unsafe_math_optimizations"
16686 {
16687 rtx op0 = gen_reg_rtx (XFmode);
16688 rtx op1 = gen_reg_rtx (XFmode);
16689
16690 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16691 emit_insn (gen_asinxf2 (op0, op1));
16692 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16693 DONE;
16694 })
16695
16696 (define_expand "acosxf2"
16697 [(set (match_dup 2)
16698 (mult:XF (match_operand:XF 1 "register_operand")
16699 (match_dup 1)))
16700 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16701 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16702 (parallel [(set (match_operand:XF 0 "register_operand")
16703 (unspec:XF [(match_dup 1) (match_dup 5)]
16704 UNSPEC_FPATAN))
16705 (clobber (scratch:XF))])]
16706 "TARGET_USE_FANCY_MATH_387
16707 && flag_unsafe_math_optimizations"
16708 {
16709 int i;
16710
16711 for (i = 2; i < 6; i++)
16712 operands[i] = gen_reg_rtx (XFmode);
16713
16714 emit_move_insn (operands[3], CONST1_RTX (XFmode));
16715 })
16716
16717 (define_expand "acos<mode>2"
16718 [(use (match_operand:MODEF 0 "register_operand"))
16719 (use (match_operand:MODEF 1 "general_operand"))]
16720 "TARGET_USE_FANCY_MATH_387
16721 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16722 || TARGET_MIX_SSE_I387)
16723 && flag_unsafe_math_optimizations"
16724 {
16725 rtx op0 = gen_reg_rtx (XFmode);
16726 rtx op1 = gen_reg_rtx (XFmode);
16727
16728 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16729 emit_insn (gen_acosxf2 (op0, op1));
16730 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16731 DONE;
16732 })
16733
16734 (define_expand "sinhxf2"
16735 [(use (match_operand:XF 0 "register_operand"))
16736 (use (match_operand:XF 1 "register_operand"))]
16737 "TARGET_USE_FANCY_MATH_387
16738 && flag_finite_math_only
16739 && flag_unsafe_math_optimizations"
16740 {
16741 ix86_emit_i387_sinh (operands[0], operands[1]);
16742 DONE;
16743 })
16744
16745 (define_expand "sinh<mode>2"
16746 [(use (match_operand:MODEF 0 "register_operand"))
16747 (use (match_operand:MODEF 1 "general_operand"))]
16748 "TARGET_USE_FANCY_MATH_387
16749 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16750 || TARGET_MIX_SSE_I387)
16751 && flag_finite_math_only
16752 && flag_unsafe_math_optimizations"
16753 {
16754 rtx op0 = gen_reg_rtx (XFmode);
16755 rtx op1 = gen_reg_rtx (XFmode);
16756
16757 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16758 emit_insn (gen_sinhxf2 (op0, op1));
16759 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16760 DONE;
16761 })
16762
16763 (define_expand "coshxf2"
16764 [(use (match_operand:XF 0 "register_operand"))
16765 (use (match_operand:XF 1 "register_operand"))]
16766 "TARGET_USE_FANCY_MATH_387
16767 && flag_unsafe_math_optimizations"
16768 {
16769 ix86_emit_i387_cosh (operands[0], operands[1]);
16770 DONE;
16771 })
16772
16773 (define_expand "cosh<mode>2"
16774 [(use (match_operand:MODEF 0 "register_operand"))
16775 (use (match_operand:MODEF 1 "general_operand"))]
16776 "TARGET_USE_FANCY_MATH_387
16777 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16778 || TARGET_MIX_SSE_I387)
16779 && flag_unsafe_math_optimizations"
16780 {
16781 rtx op0 = gen_reg_rtx (XFmode);
16782 rtx op1 = gen_reg_rtx (XFmode);
16783
16784 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16785 emit_insn (gen_coshxf2 (op0, op1));
16786 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16787 DONE;
16788 })
16789
16790 (define_expand "tanhxf2"
16791 [(use (match_operand:XF 0 "register_operand"))
16792 (use (match_operand:XF 1 "register_operand"))]
16793 "TARGET_USE_FANCY_MATH_387
16794 && flag_unsafe_math_optimizations"
16795 {
16796 ix86_emit_i387_tanh (operands[0], operands[1]);
16797 DONE;
16798 })
16799
16800 (define_expand "tanh<mode>2"
16801 [(use (match_operand:MODEF 0 "register_operand"))
16802 (use (match_operand:MODEF 1 "general_operand"))]
16803 "TARGET_USE_FANCY_MATH_387
16804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16805 || TARGET_MIX_SSE_I387)
16806 && flag_unsafe_math_optimizations"
16807 {
16808 rtx op0 = gen_reg_rtx (XFmode);
16809 rtx op1 = gen_reg_rtx (XFmode);
16810
16811 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16812 emit_insn (gen_tanhxf2 (op0, op1));
16813 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16814 DONE;
16815 })
16816
16817 (define_expand "asinhxf2"
16818 [(use (match_operand:XF 0 "register_operand"))
16819 (use (match_operand:XF 1 "register_operand"))]
16820 "TARGET_USE_FANCY_MATH_387
16821 && flag_finite_math_only
16822 && flag_unsafe_math_optimizations"
16823 {
16824 ix86_emit_i387_asinh (operands[0], operands[1]);
16825 DONE;
16826 })
16827
16828 (define_expand "asinh<mode>2"
16829 [(use (match_operand:MODEF 0 "register_operand"))
16830 (use (match_operand:MODEF 1 "general_operand"))]
16831 "TARGET_USE_FANCY_MATH_387
16832 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16833 || TARGET_MIX_SSE_I387)
16834 && flag_finite_math_only
16835 && flag_unsafe_math_optimizations"
16836 {
16837 rtx op0 = gen_reg_rtx (XFmode);
16838 rtx op1 = gen_reg_rtx (XFmode);
16839
16840 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16841 emit_insn (gen_asinhxf2 (op0, op1));
16842 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16843 DONE;
16844 })
16845
16846 (define_expand "acoshxf2"
16847 [(use (match_operand:XF 0 "register_operand"))
16848 (use (match_operand:XF 1 "register_operand"))]
16849 "TARGET_USE_FANCY_MATH_387
16850 && flag_unsafe_math_optimizations"
16851 {
16852 ix86_emit_i387_acosh (operands[0], operands[1]);
16853 DONE;
16854 })
16855
16856 (define_expand "acosh<mode>2"
16857 [(use (match_operand:MODEF 0 "register_operand"))
16858 (use (match_operand:MODEF 1 "general_operand"))]
16859 "TARGET_USE_FANCY_MATH_387
16860 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16861 || TARGET_MIX_SSE_I387)
16862 && flag_unsafe_math_optimizations"
16863 {
16864 rtx op0 = gen_reg_rtx (XFmode);
16865 rtx op1 = gen_reg_rtx (XFmode);
16866
16867 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16868 emit_insn (gen_acoshxf2 (op0, op1));
16869 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16870 DONE;
16871 })
16872
16873 (define_expand "atanhxf2"
16874 [(use (match_operand:XF 0 "register_operand"))
16875 (use (match_operand:XF 1 "register_operand"))]
16876 "TARGET_USE_FANCY_MATH_387
16877 && flag_unsafe_math_optimizations"
16878 {
16879 ix86_emit_i387_atanh (operands[0], operands[1]);
16880 DONE;
16881 })
16882
16883 (define_expand "atanh<mode>2"
16884 [(use (match_operand:MODEF 0 "register_operand"))
16885 (use (match_operand:MODEF 1 "general_operand"))]
16886 "TARGET_USE_FANCY_MATH_387
16887 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16888 || TARGET_MIX_SSE_I387)
16889 && flag_unsafe_math_optimizations"
16890 {
16891 rtx op0 = gen_reg_rtx (XFmode);
16892 rtx op1 = gen_reg_rtx (XFmode);
16893
16894 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16895 emit_insn (gen_atanhxf2 (op0, op1));
16896 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16897 DONE;
16898 })
16899
16900 (define_insn "fyl2xxf3_i387"
16901 [(set (match_operand:XF 0 "register_operand" "=f")
16902 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16903 (match_operand:XF 2 "register_operand" "f")]
16904 UNSPEC_FYL2X))
16905 (clobber (match_scratch:XF 3 "=2"))]
16906 "TARGET_USE_FANCY_MATH_387
16907 && flag_unsafe_math_optimizations"
16908 "fyl2x"
16909 [(set_attr "type" "fpspc")
16910 (set_attr "znver1_decode" "vector")
16911 (set_attr "mode" "XF")])
16912
16913 (define_expand "logxf2"
16914 [(parallel [(set (match_operand:XF 0 "register_operand")
16915 (unspec:XF [(match_operand:XF 1 "register_operand")
16916 (match_dup 2)] UNSPEC_FYL2X))
16917 (clobber (scratch:XF))])]
16918 "TARGET_USE_FANCY_MATH_387
16919 && flag_unsafe_math_optimizations"
16920 {
16921 operands[2]
16922 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
16923 })
16924
16925 (define_expand "log<mode>2"
16926 [(use (match_operand:MODEF 0 "register_operand"))
16927 (use (match_operand:MODEF 1 "general_operand"))]
16928 "TARGET_USE_FANCY_MATH_387
16929 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16930 || TARGET_MIX_SSE_I387)
16931 && flag_unsafe_math_optimizations"
16932 {
16933 rtx op0 = gen_reg_rtx (XFmode);
16934 rtx op1 = gen_reg_rtx (XFmode);
16935
16936 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16937 emit_insn (gen_logxf2 (op0, op1));
16938 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16939 DONE;
16940 })
16941
16942 (define_expand "log10xf2"
16943 [(parallel [(set (match_operand:XF 0 "register_operand")
16944 (unspec:XF [(match_operand:XF 1 "register_operand")
16945 (match_dup 2)] UNSPEC_FYL2X))
16946 (clobber (scratch:XF))])]
16947 "TARGET_USE_FANCY_MATH_387
16948 && flag_unsafe_math_optimizations"
16949 {
16950 operands[2]
16951 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
16952 })
16953
16954 (define_expand "log10<mode>2"
16955 [(use (match_operand:MODEF 0 "register_operand"))
16956 (use (match_operand:MODEF 1 "general_operand"))]
16957 "TARGET_USE_FANCY_MATH_387
16958 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16959 || TARGET_MIX_SSE_I387)
16960 && flag_unsafe_math_optimizations"
16961 {
16962 rtx op0 = gen_reg_rtx (XFmode);
16963 rtx op1 = gen_reg_rtx (XFmode);
16964
16965 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16966 emit_insn (gen_log10xf2 (op0, op1));
16967 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16968 DONE;
16969 })
16970
16971 (define_expand "log2xf2"
16972 [(parallel [(set (match_operand:XF 0 "register_operand")
16973 (unspec:XF [(match_operand:XF 1 "register_operand")
16974 (match_dup 2)] UNSPEC_FYL2X))
16975 (clobber (scratch:XF))])]
16976 "TARGET_USE_FANCY_MATH_387
16977 && flag_unsafe_math_optimizations"
16978 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
16979
16980 (define_expand "log2<mode>2"
16981 [(use (match_operand:MODEF 0 "register_operand"))
16982 (use (match_operand:MODEF 1 "general_operand"))]
16983 "TARGET_USE_FANCY_MATH_387
16984 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16985 || TARGET_MIX_SSE_I387)
16986 && flag_unsafe_math_optimizations"
16987 {
16988 rtx op0 = gen_reg_rtx (XFmode);
16989 rtx op1 = gen_reg_rtx (XFmode);
16990
16991 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16992 emit_insn (gen_log2xf2 (op0, op1));
16993 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16994 DONE;
16995 })
16996
16997 (define_insn "fyl2xp1xf3_i387"
16998 [(set (match_operand:XF 0 "register_operand" "=f")
16999 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17000 (match_operand:XF 2 "register_operand" "f")]
17001 UNSPEC_FYL2XP1))
17002 (clobber (match_scratch:XF 3 "=2"))]
17003 "TARGET_USE_FANCY_MATH_387
17004 && flag_unsafe_math_optimizations"
17005 "fyl2xp1"
17006 [(set_attr "type" "fpspc")
17007 (set_attr "znver1_decode" "vector")
17008 (set_attr "mode" "XF")])
17009
17010 (define_expand "log1pxf2"
17011 [(use (match_operand:XF 0 "register_operand"))
17012 (use (match_operand:XF 1 "register_operand"))]
17013 "TARGET_USE_FANCY_MATH_387
17014 && flag_unsafe_math_optimizations"
17015 {
17016 ix86_emit_i387_log1p (operands[0], operands[1]);
17017 DONE;
17018 })
17019
17020 (define_expand "log1p<mode>2"
17021 [(use (match_operand:MODEF 0 "register_operand"))
17022 (use (match_operand:MODEF 1 "general_operand"))]
17023 "TARGET_USE_FANCY_MATH_387
17024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17025 || TARGET_MIX_SSE_I387)
17026 && flag_unsafe_math_optimizations"
17027 {
17028 rtx op0 = gen_reg_rtx (XFmode);
17029 rtx op1 = gen_reg_rtx (XFmode);
17030
17031 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17032 emit_insn (gen_log1pxf2 (op0, op1));
17033 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17034 DONE;
17035 })
17036
17037 (define_insn "fxtractxf3_i387"
17038 [(set (match_operand:XF 0 "register_operand" "=f")
17039 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17040 UNSPEC_XTRACT_FRACT))
17041 (set (match_operand:XF 1 "register_operand" "=f")
17042 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17043 "TARGET_USE_FANCY_MATH_387
17044 && flag_unsafe_math_optimizations"
17045 "fxtract"
17046 [(set_attr "type" "fpspc")
17047 (set_attr "znver1_decode" "vector")
17048 (set_attr "mode" "XF")])
17049
17050 (define_expand "logbxf2"
17051 [(parallel [(set (match_dup 2)
17052 (unspec:XF [(match_operand:XF 1 "register_operand")]
17053 UNSPEC_XTRACT_FRACT))
17054 (set (match_operand:XF 0 "register_operand")
17055 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17056 "TARGET_USE_FANCY_MATH_387
17057 && flag_unsafe_math_optimizations"
17058 "operands[2] = gen_reg_rtx (XFmode);")
17059
17060 (define_expand "logb<mode>2"
17061 [(use (match_operand:MODEF 0 "register_operand"))
17062 (use (match_operand:MODEF 1 "general_operand"))]
17063 "TARGET_USE_FANCY_MATH_387
17064 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17065 || TARGET_MIX_SSE_I387)
17066 && flag_unsafe_math_optimizations"
17067 {
17068 rtx op0 = gen_reg_rtx (XFmode);
17069 rtx op1 = gen_reg_rtx (XFmode);
17070
17071 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17072 emit_insn (gen_logbxf2 (op0, op1));
17073 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17074 DONE;
17075 })
17076
17077 (define_expand "ilogbxf2"
17078 [(use (match_operand:SI 0 "register_operand"))
17079 (use (match_operand:XF 1 "register_operand"))]
17080 "TARGET_USE_FANCY_MATH_387
17081 && flag_unsafe_math_optimizations"
17082 {
17083 rtx op0, op1;
17084
17085 if (optimize_insn_for_size_p ())
17086 FAIL;
17087
17088 op0 = gen_reg_rtx (XFmode);
17089 op1 = gen_reg_rtx (XFmode);
17090
17091 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17092 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17093 DONE;
17094 })
17095
17096 (define_expand "ilogb<mode>2"
17097 [(use (match_operand:SI 0 "register_operand"))
17098 (use (match_operand:MODEF 1 "general_operand"))]
17099 "TARGET_USE_FANCY_MATH_387
17100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17101 || TARGET_MIX_SSE_I387)
17102 && flag_unsafe_math_optimizations"
17103 {
17104 rtx op0, op1, op2;
17105
17106 if (optimize_insn_for_size_p ())
17107 FAIL;
17108
17109 op0 = gen_reg_rtx (XFmode);
17110 op1 = gen_reg_rtx (XFmode);
17111 op2 = gen_reg_rtx (XFmode);
17112
17113 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
17114 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
17115 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17116 DONE;
17117 })
17118
17119 (define_insn "*f2xm1xf2_i387"
17120 [(set (match_operand:XF 0 "register_operand" "=f")
17121 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17122 UNSPEC_F2XM1))]
17123 "TARGET_USE_FANCY_MATH_387
17124 && flag_unsafe_math_optimizations"
17125 "f2xm1"
17126 [(set_attr "type" "fpspc")
17127 (set_attr "znver1_decode" "vector")
17128 (set_attr "mode" "XF")])
17129
17130 (define_insn "fscalexf4_i387"
17131 [(set (match_operand:XF 0 "register_operand" "=f")
17132 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17133 (match_operand:XF 3 "register_operand" "1")]
17134 UNSPEC_FSCALE_FRACT))
17135 (set (match_operand:XF 1 "register_operand" "=f")
17136 (unspec:XF [(match_dup 2) (match_dup 3)]
17137 UNSPEC_FSCALE_EXP))]
17138 "TARGET_USE_FANCY_MATH_387
17139 && flag_unsafe_math_optimizations"
17140 "fscale"
17141 [(set_attr "type" "fpspc")
17142 (set_attr "znver1_decode" "vector")
17143 (set_attr "mode" "XF")])
17144
17145 (define_expand "expNcorexf3"
17146 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
17147 (match_operand:XF 2 "register_operand")))
17148 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17149 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17150 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17151 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17152 (parallel [(set (match_operand:XF 0 "register_operand")
17153 (unspec:XF [(match_dup 8) (match_dup 4)]
17154 UNSPEC_FSCALE_FRACT))
17155 (set (match_dup 9)
17156 (unspec:XF [(match_dup 8) (match_dup 4)]
17157 UNSPEC_FSCALE_EXP))])]
17158 "TARGET_USE_FANCY_MATH_387
17159 && flag_unsafe_math_optimizations"
17160 {
17161 int i;
17162
17163 for (i = 3; i < 10; i++)
17164 operands[i] = gen_reg_rtx (XFmode);
17165
17166 emit_move_insn (operands[7], CONST1_RTX (XFmode));
17167 })
17168
17169 (define_expand "expxf2"
17170 [(use (match_operand:XF 0 "register_operand"))
17171 (use (match_operand:XF 1 "register_operand"))]
17172 "TARGET_USE_FANCY_MATH_387
17173 && flag_unsafe_math_optimizations"
17174 {
17175 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
17176
17177 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17178 DONE;
17179 })
17180
17181 (define_expand "exp<mode>2"
17182 [(use (match_operand:MODEF 0 "register_operand"))
17183 (use (match_operand:MODEF 1 "general_operand"))]
17184 "TARGET_USE_FANCY_MATH_387
17185 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17186 || TARGET_MIX_SSE_I387)
17187 && flag_unsafe_math_optimizations"
17188 {
17189 rtx op0 = gen_reg_rtx (XFmode);
17190 rtx op1 = gen_reg_rtx (XFmode);
17191
17192 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17193 emit_insn (gen_expxf2 (op0, op1));
17194 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17195 DONE;
17196 })
17197
17198 (define_expand "exp10xf2"
17199 [(use (match_operand:XF 0 "register_operand"))
17200 (use (match_operand:XF 1 "register_operand"))]
17201 "TARGET_USE_FANCY_MATH_387
17202 && flag_unsafe_math_optimizations"
17203 {
17204 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
17205
17206 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17207 DONE;
17208 })
17209
17210 (define_expand "exp10<mode>2"
17211 [(use (match_operand:MODEF 0 "register_operand"))
17212 (use (match_operand:MODEF 1 "general_operand"))]
17213 "TARGET_USE_FANCY_MATH_387
17214 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17215 || TARGET_MIX_SSE_I387)
17216 && flag_unsafe_math_optimizations"
17217 {
17218 rtx op0 = gen_reg_rtx (XFmode);
17219 rtx op1 = gen_reg_rtx (XFmode);
17220
17221 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17222 emit_insn (gen_exp10xf2 (op0, op1));
17223 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17224 DONE;
17225 })
17226
17227 (define_expand "exp2xf2"
17228 [(use (match_operand:XF 0 "register_operand"))
17229 (use (match_operand:XF 1 "register_operand"))]
17230 "TARGET_USE_FANCY_MATH_387
17231 && flag_unsafe_math_optimizations"
17232 {
17233 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
17234
17235 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17236 DONE;
17237 })
17238
17239 (define_expand "exp2<mode>2"
17240 [(use (match_operand:MODEF 0 "register_operand"))
17241 (use (match_operand:MODEF 1 "general_operand"))]
17242 "TARGET_USE_FANCY_MATH_387
17243 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17244 || TARGET_MIX_SSE_I387)
17245 && flag_unsafe_math_optimizations"
17246 {
17247 rtx op0 = gen_reg_rtx (XFmode);
17248 rtx op1 = gen_reg_rtx (XFmode);
17249
17250 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17251 emit_insn (gen_exp2xf2 (op0, op1));
17252 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17253 DONE;
17254 })
17255
17256 (define_expand "expm1xf2"
17257 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
17258 (match_dup 2)))
17259 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17260 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17261 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17262 (parallel [(set (match_dup 7)
17263 (unspec:XF [(match_dup 6) (match_dup 4)]
17264 UNSPEC_FSCALE_FRACT))
17265 (set (match_dup 8)
17266 (unspec:XF [(match_dup 6) (match_dup 4)]
17267 UNSPEC_FSCALE_EXP))])
17268 (parallel [(set (match_dup 10)
17269 (unspec:XF [(match_dup 9) (match_dup 8)]
17270 UNSPEC_FSCALE_FRACT))
17271 (set (match_dup 11)
17272 (unspec:XF [(match_dup 9) (match_dup 8)]
17273 UNSPEC_FSCALE_EXP))])
17274 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17275 (set (match_operand:XF 0 "register_operand")
17276 (plus:XF (match_dup 12) (match_dup 7)))]
17277 "TARGET_USE_FANCY_MATH_387
17278 && flag_unsafe_math_optimizations"
17279 {
17280 int i;
17281
17282 for (i = 2; i < 13; i++)
17283 operands[i] = gen_reg_rtx (XFmode);
17284
17285 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17286 emit_move_insn (operands[9], CONST1_RTX (XFmode));
17287 })
17288
17289 (define_expand "expm1<mode>2"
17290 [(use (match_operand:MODEF 0 "register_operand"))
17291 (use (match_operand:MODEF 1 "general_operand"))]
17292 "TARGET_USE_FANCY_MATH_387
17293 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17294 || TARGET_MIX_SSE_I387)
17295 && flag_unsafe_math_optimizations"
17296 {
17297 rtx op0 = gen_reg_rtx (XFmode);
17298 rtx op1 = gen_reg_rtx (XFmode);
17299
17300 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17301 emit_insn (gen_expm1xf2 (op0, op1));
17302 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17303 DONE;
17304 })
17305
17306 (define_expand "ldexpxf3"
17307 [(match_operand:XF 0 "register_operand")
17308 (match_operand:XF 1 "register_operand")
17309 (match_operand:SI 2 "register_operand")]
17310 "TARGET_USE_FANCY_MATH_387
17311 && flag_unsafe_math_optimizations"
17312 {
17313 rtx tmp1 = gen_reg_rtx (XFmode);
17314 rtx tmp2 = gen_reg_rtx (XFmode);
17315
17316 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
17317 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
17318 operands[1], tmp1));
17319 DONE;
17320 })
17321
17322 (define_expand "ldexp<mode>3"
17323 [(use (match_operand:MODEF 0 "register_operand"))
17324 (use (match_operand:MODEF 1 "general_operand"))
17325 (use (match_operand:SI 2 "register_operand"))]
17326 "TARGET_USE_FANCY_MATH_387
17327 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17328 || TARGET_MIX_SSE_I387)
17329 && flag_unsafe_math_optimizations"
17330 {
17331 rtx op0 = gen_reg_rtx (XFmode);
17332 rtx op1 = gen_reg_rtx (XFmode);
17333
17334 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17335 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17336 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17337 DONE;
17338 })
17339
17340 (define_expand "scalbxf3"
17341 [(parallel [(set (match_operand:XF 0 " register_operand")
17342 (unspec:XF [(match_operand:XF 1 "register_operand")
17343 (match_operand:XF 2 "register_operand")]
17344 UNSPEC_FSCALE_FRACT))
17345 (set (match_dup 3)
17346 (unspec:XF [(match_dup 1) (match_dup 2)]
17347 UNSPEC_FSCALE_EXP))])]
17348 "TARGET_USE_FANCY_MATH_387
17349 && flag_unsafe_math_optimizations"
17350 "operands[3] = gen_reg_rtx (XFmode);")
17351
17352 (define_expand "scalb<mode>3"
17353 [(use (match_operand:MODEF 0 "register_operand"))
17354 (use (match_operand:MODEF 1 "general_operand"))
17355 (use (match_operand:MODEF 2 "general_operand"))]
17356 "TARGET_USE_FANCY_MATH_387
17357 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17358 || TARGET_MIX_SSE_I387)
17359 && flag_unsafe_math_optimizations"
17360 {
17361 rtx op0 = gen_reg_rtx (XFmode);
17362 rtx op1 = gen_reg_rtx (XFmode);
17363 rtx op2 = gen_reg_rtx (XFmode);
17364
17365 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17366 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17367 emit_insn (gen_scalbxf3 (op0, op1, op2));
17368 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17369 DONE;
17370 })
17371
17372 (define_expand "significandxf2"
17373 [(parallel [(set (match_operand:XF 0 "register_operand")
17374 (unspec:XF [(match_operand:XF 1 "register_operand")]
17375 UNSPEC_XTRACT_FRACT))
17376 (set (match_dup 2)
17377 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17378 "TARGET_USE_FANCY_MATH_387
17379 && flag_unsafe_math_optimizations"
17380 "operands[2] = gen_reg_rtx (XFmode);")
17381
17382 (define_expand "significand<mode>2"
17383 [(use (match_operand:MODEF 0 "register_operand"))
17384 (use (match_operand:MODEF 1 "general_operand"))]
17385 "TARGET_USE_FANCY_MATH_387
17386 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17387 || TARGET_MIX_SSE_I387)
17388 && flag_unsafe_math_optimizations"
17389 {
17390 rtx op0 = gen_reg_rtx (XFmode);
17391 rtx op1 = gen_reg_rtx (XFmode);
17392
17393 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17394 emit_insn (gen_significandxf2 (op0, op1));
17395 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17396 DONE;
17397 })
17398 \f
17399
17400 (define_insn "sse4_1_round<mode>2"
17401 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,v,v")
17402 (unspec:MODEF
17403 [(match_operand:MODEF 1 "nonimmediate_operand" "0,x,m,v,m")
17404 (match_operand:SI 2 "const_0_to_15_operand" "n,n,n,n,n")]
17405 UNSPEC_ROUND))]
17406 "TARGET_SSE4_1"
17407 "@
17408 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
17409 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
17410 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
17411 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
17412 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17413 [(set_attr "type" "ssecvt")
17414 (set_attr "prefix_extra" "1,1,1,*,*")
17415 (set_attr "length_immediate" "*,*,*,1,1")
17416 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
17417 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
17418 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
17419 (set_attr "mode" "<MODE>")
17420 (set (attr "preferred_for_speed")
17421 (cond [(match_test "TARGET_AVX")
17422 (symbol_ref "true")
17423 (eq_attr "alternative" "1,2")
17424 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
17425 ]
17426 (symbol_ref "true")))])
17427
17428 (define_insn "rintxf2"
17429 [(set (match_operand:XF 0 "register_operand" "=f")
17430 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17431 UNSPEC_FRNDINT))]
17432 "TARGET_USE_FANCY_MATH_387"
17433 "frndint"
17434 [(set_attr "type" "fpspc")
17435 (set_attr "znver1_decode" "vector")
17436 (set_attr "mode" "XF")])
17437
17438 (define_expand "rint<mode>2"
17439 [(use (match_operand:MODEF 0 "register_operand"))
17440 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17441 "TARGET_USE_FANCY_MATH_387
17442 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17443 {
17444 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17445 {
17446 if (TARGET_SSE4_1)
17447 emit_insn (gen_sse4_1_round<mode>2
17448 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
17449 else
17450 ix86_expand_rint (operands[0], operands[1]);
17451 }
17452 else
17453 {
17454 rtx op0 = gen_reg_rtx (XFmode);
17455 rtx op1 = gen_reg_rtx (XFmode);
17456
17457 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17458 emit_insn (gen_rintxf2 (op0, op1));
17459 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17460 }
17461 DONE;
17462 })
17463
17464 (define_expand "nearbyintxf2"
17465 [(set (match_operand:XF 0 "register_operand")
17466 (unspec:XF [(match_operand:XF 1 "register_operand")]
17467 UNSPEC_FRNDINT))]
17468 "TARGET_USE_FANCY_MATH_387
17469 && !flag_trapping_math")
17470
17471 (define_expand "nearbyint<mode>2"
17472 [(use (match_operand:MODEF 0 "register_operand"))
17473 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17474 "(TARGET_USE_FANCY_MATH_387
17475 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17476 || TARGET_MIX_SSE_I387)
17477 && !flag_trapping_math)
17478 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
17479 {
17480 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
17481 emit_insn (gen_sse4_1_round<mode>2
17482 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
17483 | ROUND_NO_EXC)));
17484 else
17485 {
17486 rtx op0 = gen_reg_rtx (XFmode);
17487 rtx op1 = gen_reg_rtx (XFmode);
17488
17489 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17490 emit_insn (gen_nearbyintxf2 (op0, op1));
17491 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17492 }
17493 DONE;
17494 })
17495
17496 (define_expand "round<mode>2"
17497 [(match_operand:X87MODEF 0 "register_operand")
17498 (match_operand:X87MODEF 1 "nonimmediate_operand")]
17499 "(TARGET_USE_FANCY_MATH_387
17500 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17501 || TARGET_MIX_SSE_I387)
17502 && flag_unsafe_math_optimizations
17503 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
17504 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17505 && !flag_trapping_math && !flag_rounding_math)"
17506 {
17507 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17508 && !flag_trapping_math && !flag_rounding_math)
17509 {
17510 if (TARGET_SSE4_1)
17511 {
17512 operands[1] = force_reg (<MODE>mode, operands[1]);
17513 ix86_expand_round_sse4 (operands[0], operands[1]);
17514 }
17515 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17516 ix86_expand_round (operands[0], operands[1]);
17517 else
17518 ix86_expand_rounddf_32 (operands[0], operands[1]);
17519 }
17520 else
17521 {
17522 operands[1] = force_reg (<MODE>mode, operands[1]);
17523 ix86_emit_i387_round (operands[0], operands[1]);
17524 }
17525 DONE;
17526 })
17527
17528 (define_insn "lrintxfdi2"
17529 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
17530 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17531 UNSPEC_FIST))
17532 (clobber (match_scratch:XF 2 "=&f"))]
17533 "TARGET_USE_FANCY_MATH_387"
17534 "* return output_fix_trunc (insn, operands, false);"
17535 [(set_attr "type" "fpspc")
17536 (set_attr "mode" "DI")])
17537
17538 (define_insn "lrintxf<mode>2"
17539 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
17540 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17541 UNSPEC_FIST))]
17542 "TARGET_USE_FANCY_MATH_387"
17543 "* return output_fix_trunc (insn, operands, false);"
17544 [(set_attr "type" "fpspc")
17545 (set_attr "mode" "<MODE>")])
17546
17547 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
17548 [(set (match_operand:SWI48 0 "nonimmediate_operand")
17549 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17550 UNSPEC_FIX_NOTRUNC))]
17551 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
17552
17553 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
17554 [(match_operand:SWI248x 0 "nonimmediate_operand")
17555 (match_operand:X87MODEF 1 "register_operand")]
17556 "(TARGET_USE_FANCY_MATH_387
17557 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
17558 || TARGET_MIX_SSE_I387)
17559 && flag_unsafe_math_optimizations)
17560 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
17561 && <SWI248x:MODE>mode != HImode
17562 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
17563 && !flag_trapping_math && !flag_rounding_math)"
17564 {
17565 if (optimize_insn_for_size_p ())
17566 FAIL;
17567
17568 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
17569 && <SWI248x:MODE>mode != HImode
17570 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
17571 && !flag_trapping_math && !flag_rounding_math)
17572 ix86_expand_lround (operands[0], operands[1]);
17573 else
17574 ix86_emit_i387_round (operands[0], operands[1]);
17575 DONE;
17576 })
17577
17578 (define_int_iterator FRNDINT_ROUNDING
17579 [UNSPEC_FRNDINT_ROUNDEVEN
17580 UNSPEC_FRNDINT_FLOOR
17581 UNSPEC_FRNDINT_CEIL
17582 UNSPEC_FRNDINT_TRUNC])
17583
17584 (define_int_iterator FIST_ROUNDING
17585 [UNSPEC_FIST_FLOOR
17586 UNSPEC_FIST_CEIL])
17587
17588 ;; Base name for define_insn
17589 (define_int_attr rounding_insn
17590 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
17591 (UNSPEC_FRNDINT_FLOOR "floor")
17592 (UNSPEC_FRNDINT_CEIL "ceil")
17593 (UNSPEC_FRNDINT_TRUNC "btrunc")
17594 (UNSPEC_FIST_FLOOR "floor")
17595 (UNSPEC_FIST_CEIL "ceil")])
17596
17597 (define_int_attr rounding
17598 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
17599 (UNSPEC_FRNDINT_FLOOR "floor")
17600 (UNSPEC_FRNDINT_CEIL "ceil")
17601 (UNSPEC_FRNDINT_TRUNC "trunc")
17602 (UNSPEC_FIST_FLOOR "floor")
17603 (UNSPEC_FIST_CEIL "ceil")])
17604
17605 (define_int_attr ROUNDING
17606 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
17607 (UNSPEC_FRNDINT_FLOOR "FLOOR")
17608 (UNSPEC_FRNDINT_CEIL "CEIL")
17609 (UNSPEC_FRNDINT_TRUNC "TRUNC")
17610 (UNSPEC_FIST_FLOOR "FLOOR")
17611 (UNSPEC_FIST_CEIL "CEIL")])
17612
17613 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17614 (define_insn_and_split "frndintxf2_<rounding>"
17615 [(set (match_operand:XF 0 "register_operand")
17616 (unspec:XF [(match_operand:XF 1 "register_operand")]
17617 FRNDINT_ROUNDING))
17618 (clobber (reg:CC FLAGS_REG))]
17619 "TARGET_USE_FANCY_MATH_387
17620 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
17621 && ix86_pre_reload_split ()"
17622 "#"
17623 "&& 1"
17624 [(const_int 0)]
17625 {
17626 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17627
17628 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17629 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17630
17631 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
17632 operands[2], operands[3]));
17633 DONE;
17634 }
17635 [(set_attr "type" "frndint")
17636 (set_attr "i387_cw" "<rounding>")
17637 (set_attr "mode" "XF")])
17638
17639 (define_insn "frndintxf2_<rounding>_i387"
17640 [(set (match_operand:XF 0 "register_operand" "=f")
17641 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17642 FRNDINT_ROUNDING))
17643 (use (match_operand:HI 2 "memory_operand" "m"))
17644 (use (match_operand:HI 3 "memory_operand" "m"))]
17645 "TARGET_USE_FANCY_MATH_387
17646 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
17647 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17648 [(set_attr "type" "frndint")
17649 (set_attr "i387_cw" "<rounding>")
17650 (set_attr "mode" "XF")])
17651
17652 (define_expand "<rounding_insn>xf2"
17653 [(parallel [(set (match_operand:XF 0 "register_operand")
17654 (unspec:XF [(match_operand:XF 1 "register_operand")]
17655 FRNDINT_ROUNDING))
17656 (clobber (reg:CC FLAGS_REG))])]
17657 "TARGET_USE_FANCY_MATH_387
17658 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
17659
17660 (define_expand "<rounding_insn><mode>2"
17661 [(parallel [(set (match_operand:MODEF 0 "register_operand")
17662 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
17663 FRNDINT_ROUNDING))
17664 (clobber (reg:CC FLAGS_REG))])]
17665 "(TARGET_USE_FANCY_MATH_387
17666 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17667 || TARGET_MIX_SSE_I387)
17668 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
17669 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17670 && (TARGET_SSE4_1
17671 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
17672 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
17673 {
17674 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17675 && (TARGET_SSE4_1
17676 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
17677 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
17678 {
17679 if (TARGET_SSE4_1)
17680 emit_insn (gen_sse4_1_round<mode>2
17681 (operands[0], operands[1],
17682 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
17683 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17684 {
17685 if (ROUND_<ROUNDING> == ROUND_FLOOR)
17686 ix86_expand_floorceil (operands[0], operands[1], true);
17687 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17688 ix86_expand_floorceil (operands[0], operands[1], false);
17689 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17690 ix86_expand_trunc (operands[0], operands[1]);
17691 else
17692 gcc_unreachable ();
17693 }
17694 else
17695 {
17696 if (ROUND_<ROUNDING> == ROUND_FLOOR)
17697 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
17698 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17699 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
17700 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17701 ix86_expand_truncdf_32 (operands[0], operands[1]);
17702 else
17703 gcc_unreachable ();
17704 }
17705 }
17706 else
17707 {
17708 rtx op0 = gen_reg_rtx (XFmode);
17709 rtx op1 = gen_reg_rtx (XFmode);
17710
17711 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17712 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
17713 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17714 }
17715 DONE;
17716 })
17717
17718 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17719 (define_insn_and_split "*fist<mode>2_<rounding>_1"
17720 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17721 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17722 FIST_ROUNDING))
17723 (clobber (reg:CC FLAGS_REG))]
17724 "TARGET_USE_FANCY_MATH_387
17725 && flag_unsafe_math_optimizations
17726 && ix86_pre_reload_split ()"
17727 "#"
17728 "&& 1"
17729 [(const_int 0)]
17730 {
17731 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17732
17733 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17734 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17735
17736 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
17737 operands[2], operands[3]));
17738 DONE;
17739 }
17740 [(set_attr "type" "fistp")
17741 (set_attr "i387_cw" "<rounding>")
17742 (set_attr "mode" "<MODE>")])
17743
17744 (define_insn "fistdi2_<rounding>"
17745 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
17746 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17747 FIST_ROUNDING))
17748 (use (match_operand:HI 2 "memory_operand" "m"))
17749 (use (match_operand:HI 3 "memory_operand" "m"))
17750 (clobber (match_scratch:XF 4 "=&f"))]
17751 "TARGET_USE_FANCY_MATH_387
17752 && flag_unsafe_math_optimizations"
17753 "* return output_fix_trunc (insn, operands, false);"
17754 [(set_attr "type" "fistp")
17755 (set_attr "i387_cw" "<rounding>")
17756 (set_attr "mode" "DI")])
17757
17758 (define_insn "fist<mode>2_<rounding>"
17759 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
17760 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17761 FIST_ROUNDING))
17762 (use (match_operand:HI 2 "memory_operand" "m"))
17763 (use (match_operand:HI 3 "memory_operand" "m"))]
17764 "TARGET_USE_FANCY_MATH_387
17765 && flag_unsafe_math_optimizations"
17766 "* return output_fix_trunc (insn, operands, false);"
17767 [(set_attr "type" "fistp")
17768 (set_attr "i387_cw" "<rounding>")
17769 (set_attr "mode" "<MODE>")])
17770
17771 (define_expand "l<rounding_insn>xf<mode>2"
17772 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17773 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17774 FIST_ROUNDING))
17775 (clobber (reg:CC FLAGS_REG))])]
17776 "TARGET_USE_FANCY_MATH_387
17777 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17778 && flag_unsafe_math_optimizations")
17779
17780 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
17781 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
17782 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17783 FIST_ROUNDING))
17784 (clobber (reg:CC FLAGS_REG))])]
17785 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17786 && (TARGET_SSE4_1 || !flag_trapping_math)"
17787 {
17788 if (TARGET_SSE4_1)
17789 {
17790 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
17791
17792 emit_insn (gen_sse4_1_round<MODEF:mode>2
17793 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
17794 | ROUND_NO_EXC)));
17795 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
17796 (operands[0], tmp));
17797 }
17798 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
17799 ix86_expand_lfloorceil (operands[0], operands[1], true);
17800 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17801 ix86_expand_lfloorceil (operands[0], operands[1], false);
17802 else
17803 gcc_unreachable ();
17804
17805 DONE;
17806 })
17807
17808 (define_insn "fxam<mode>2_i387"
17809 [(set (match_operand:HI 0 "register_operand" "=a")
17810 (unspec:HI
17811 [(match_operand:X87MODEF 1 "register_operand" "f")]
17812 UNSPEC_FXAM))]
17813 "TARGET_USE_FANCY_MATH_387"
17814 "fxam\n\tfnstsw\t%0"
17815 [(set_attr "type" "multi")
17816 (set_attr "length" "4")
17817 (set_attr "unit" "i387")
17818 (set_attr "mode" "<MODE>")])
17819
17820 (define_expand "signbittf2"
17821 [(use (match_operand:SI 0 "register_operand"))
17822 (use (match_operand:TF 1 "register_operand"))]
17823 "TARGET_SSE"
17824 {
17825 if (TARGET_SSE4_1)
17826 {
17827 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17828 rtx scratch = gen_reg_rtx (QImode);
17829
17830 emit_insn (gen_ptesttf2 (operands[1], mask));
17831 ix86_expand_setcc (scratch, NE,
17832 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17833
17834 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17835 }
17836 else
17837 {
17838 emit_insn (gen_sse_movmskps (operands[0],
17839 gen_lowpart (V4SFmode, operands[1])));
17840 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17841 }
17842 DONE;
17843 })
17844
17845 (define_expand "signbitxf2"
17846 [(use (match_operand:SI 0 "register_operand"))
17847 (use (match_operand:XF 1 "register_operand"))]
17848 "TARGET_USE_FANCY_MATH_387"
17849 {
17850 rtx scratch = gen_reg_rtx (HImode);
17851
17852 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17853 emit_insn (gen_andsi3 (operands[0],
17854 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17855 DONE;
17856 })
17857
17858 (define_insn "movmsk_df"
17859 [(set (match_operand:SI 0 "register_operand" "=r")
17860 (unspec:SI
17861 [(match_operand:DF 1 "register_operand" "x")]
17862 UNSPEC_MOVMSK))]
17863 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17864 "%vmovmskpd\t{%1, %0|%0, %1}"
17865 [(set_attr "type" "ssemov")
17866 (set_attr "prefix" "maybe_vex")
17867 (set_attr "mode" "DF")])
17868
17869 ;; Use movmskpd in SSE mode to avoid store forwarding stall
17870 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
17871 (define_expand "signbitdf2"
17872 [(use (match_operand:SI 0 "register_operand"))
17873 (use (match_operand:DF 1 "register_operand"))]
17874 "TARGET_USE_FANCY_MATH_387
17875 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17876 {
17877 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17878 {
17879 emit_insn (gen_movmsk_df (operands[0], operands[1]));
17880 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17881 }
17882 else
17883 {
17884 rtx scratch = gen_reg_rtx (HImode);
17885
17886 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17887 emit_insn (gen_andsi3 (operands[0],
17888 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17889 }
17890 DONE;
17891 })
17892
17893 (define_expand "signbitsf2"
17894 [(use (match_operand:SI 0 "register_operand"))
17895 (use (match_operand:SF 1 "register_operand"))]
17896 "TARGET_USE_FANCY_MATH_387
17897 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17898 {
17899 rtx scratch = gen_reg_rtx (HImode);
17900
17901 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17902 emit_insn (gen_andsi3 (operands[0],
17903 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17904 DONE;
17905 })
17906 \f
17907 ;; Block operation instructions
17908
17909 (define_insn "cld"
17910 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17911 ""
17912 "cld"
17913 [(set_attr "length" "1")
17914 (set_attr "length_immediate" "0")
17915 (set_attr "modrm" "0")])
17916
17917 (define_expand "cpymem<mode>"
17918 [(use (match_operand:BLK 0 "memory_operand"))
17919 (use (match_operand:BLK 1 "memory_operand"))
17920 (use (match_operand:SWI48 2 "nonmemory_operand"))
17921 (use (match_operand:SWI48 3 "const_int_operand"))
17922 (use (match_operand:SI 4 "const_int_operand"))
17923 (use (match_operand:SI 5 "const_int_operand"))
17924 (use (match_operand:SI 6 ""))
17925 (use (match_operand:SI 7 ""))
17926 (use (match_operand:SI 8 ""))]
17927 ""
17928 {
17929 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
17930 operands[2], NULL, operands[3],
17931 operands[4], operands[5],
17932 operands[6], operands[7],
17933 operands[8], false))
17934 DONE;
17935 else
17936 FAIL;
17937 })
17938
17939 ;; Most CPUs don't like single string operations
17940 ;; Handle this case here to simplify previous expander.
17941
17942 (define_expand "strmov"
17943 [(set (match_dup 4) (match_operand 3 "memory_operand"))
17944 (set (match_operand 1 "memory_operand") (match_dup 4))
17945 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17946 (clobber (reg:CC FLAGS_REG))])
17947 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17948 (clobber (reg:CC FLAGS_REG))])]
17949 ""
17950 {
17951 /* Can't use this for non-default address spaces. */
17952 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17953 FAIL;
17954
17955 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
17956
17957 /* If .md ever supports :P for Pmode, these can be directly
17958 in the pattern above. */
17959 operands[5] = plus_constant (Pmode, operands[0], piece_size);
17960 operands[6] = plus_constant (Pmode, operands[2], piece_size);
17961
17962 /* Can't use this if the user has appropriated esi or edi. */
17963 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17964 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17965 {
17966 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17967 operands[2], operands[3],
17968 operands[5], operands[6]));
17969 DONE;
17970 }
17971
17972 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17973 })
17974
17975 (define_expand "strmov_singleop"
17976 [(parallel [(set (match_operand 1 "memory_operand")
17977 (match_operand 3 "memory_operand"))
17978 (set (match_operand 0 "register_operand")
17979 (match_operand 4))
17980 (set (match_operand 2 "register_operand")
17981 (match_operand 5))])]
17982 ""
17983 {
17984 if (TARGET_CLD)
17985 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17986 })
17987
17988 (define_insn "*strmovdi_rex_1"
17989 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17990 (mem:DI (match_operand:P 3 "register_operand" "1")))
17991 (set (match_operand:P 0 "register_operand" "=D")
17992 (plus:P (match_dup 2)
17993 (const_int 8)))
17994 (set (match_operand:P 1 "register_operand" "=S")
17995 (plus:P (match_dup 3)
17996 (const_int 8)))]
17997 "TARGET_64BIT
17998 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17999 && ix86_check_no_addr_space (insn)"
18000 "%^movsq"
18001 [(set_attr "type" "str")
18002 (set_attr "memory" "both")
18003 (set_attr "mode" "DI")])
18004
18005 (define_insn "*strmovsi_1"
18006 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
18007 (mem:SI (match_operand:P 3 "register_operand" "1")))
18008 (set (match_operand:P 0 "register_operand" "=D")
18009 (plus:P (match_dup 2)
18010 (const_int 4)))
18011 (set (match_operand:P 1 "register_operand" "=S")
18012 (plus:P (match_dup 3)
18013 (const_int 4)))]
18014 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
18015 && ix86_check_no_addr_space (insn)"
18016 "%^movs{l|d}"
18017 [(set_attr "type" "str")
18018 (set_attr "memory" "both")
18019 (set_attr "mode" "SI")])
18020
18021 (define_insn "*strmovhi_1"
18022 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
18023 (mem:HI (match_operand:P 3 "register_operand" "1")))
18024 (set (match_operand:P 0 "register_operand" "=D")
18025 (plus:P (match_dup 2)
18026 (const_int 2)))
18027 (set (match_operand:P 1 "register_operand" "=S")
18028 (plus:P (match_dup 3)
18029 (const_int 2)))]
18030 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
18031 && ix86_check_no_addr_space (insn)"
18032 "%^movsw"
18033 [(set_attr "type" "str")
18034 (set_attr "memory" "both")
18035 (set_attr "mode" "HI")])
18036
18037 (define_insn "*strmovqi_1"
18038 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
18039 (mem:QI (match_operand:P 3 "register_operand" "1")))
18040 (set (match_operand:P 0 "register_operand" "=D")
18041 (plus:P (match_dup 2)
18042 (const_int 1)))
18043 (set (match_operand:P 1 "register_operand" "=S")
18044 (plus:P (match_dup 3)
18045 (const_int 1)))]
18046 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
18047 && ix86_check_no_addr_space (insn)"
18048 "%^movsb"
18049 [(set_attr "type" "str")
18050 (set_attr "memory" "both")
18051 (set (attr "prefix_rex")
18052 (if_then_else
18053 (match_test "<P:MODE>mode == DImode")
18054 (const_string "0")
18055 (const_string "*")))
18056 (set_attr "mode" "QI")])
18057
18058 (define_expand "rep_mov"
18059 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
18060 (set (match_operand 0 "register_operand")
18061 (match_operand 5))
18062 (set (match_operand 2 "register_operand")
18063 (match_operand 6))
18064 (set (match_operand 1 "memory_operand")
18065 (match_operand 3 "memory_operand"))
18066 (use (match_dup 4))])]
18067 ""
18068 {
18069 if (TARGET_CLD)
18070 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18071 })
18072
18073 (define_insn "*rep_movdi_rex64"
18074 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
18075 (set (match_operand:P 0 "register_operand" "=D")
18076 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
18077 (const_int 3))
18078 (match_operand:P 3 "register_operand" "0")))
18079 (set (match_operand:P 1 "register_operand" "=S")
18080 (plus:P (ashift:P (match_dup 5) (const_int 3))
18081 (match_operand:P 4 "register_operand" "1")))
18082 (set (mem:BLK (match_dup 3))
18083 (mem:BLK (match_dup 4)))
18084 (use (match_dup 5))]
18085 "TARGET_64BIT
18086 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18087 && ix86_check_no_addr_space (insn)"
18088 "%^rep{%;} movsq"
18089 [(set_attr "type" "str")
18090 (set_attr "prefix_rep" "1")
18091 (set_attr "memory" "both")
18092 (set_attr "mode" "DI")])
18093
18094 (define_insn "*rep_movsi"
18095 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
18096 (set (match_operand:P 0 "register_operand" "=D")
18097 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
18098 (const_int 2))
18099 (match_operand:P 3 "register_operand" "0")))
18100 (set (match_operand:P 1 "register_operand" "=S")
18101 (plus:P (ashift:P (match_dup 5) (const_int 2))
18102 (match_operand:P 4 "register_operand" "1")))
18103 (set (mem:BLK (match_dup 3))
18104 (mem:BLK (match_dup 4)))
18105 (use (match_dup 5))]
18106 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18107 && ix86_check_no_addr_space (insn)"
18108 "%^rep{%;} movs{l|d}"
18109 [(set_attr "type" "str")
18110 (set_attr "prefix_rep" "1")
18111 (set_attr "memory" "both")
18112 (set_attr "mode" "SI")])
18113
18114 (define_insn "*rep_movqi"
18115 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
18116 (set (match_operand:P 0 "register_operand" "=D")
18117 (plus:P (match_operand:P 3 "register_operand" "0")
18118 (match_operand:P 5 "register_operand" "2")))
18119 (set (match_operand:P 1 "register_operand" "=S")
18120 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
18121 (set (mem:BLK (match_dup 3))
18122 (mem:BLK (match_dup 4)))
18123 (use (match_dup 5))]
18124 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18125 && ix86_check_no_addr_space (insn)"
18126 "%^rep{%;} movsb"
18127 [(set_attr "type" "str")
18128 (set_attr "prefix_rep" "1")
18129 (set_attr "memory" "both")
18130 (set_attr "mode" "QI")])
18131
18132 (define_expand "setmem<mode>"
18133 [(use (match_operand:BLK 0 "memory_operand"))
18134 (use (match_operand:SWI48 1 "nonmemory_operand"))
18135 (use (match_operand:QI 2 "nonmemory_operand"))
18136 (use (match_operand 3 "const_int_operand"))
18137 (use (match_operand:SI 4 "const_int_operand"))
18138 (use (match_operand:SI 5 "const_int_operand"))
18139 (use (match_operand:SI 6 ""))
18140 (use (match_operand:SI 7 ""))
18141 (use (match_operand:SI 8 ""))]
18142 ""
18143 {
18144 if (ix86_expand_set_or_cpymem (operands[0], NULL,
18145 operands[1], operands[2],
18146 operands[3], operands[4],
18147 operands[5], operands[6],
18148 operands[7], operands[8], true))
18149 DONE;
18150 else
18151 FAIL;
18152 })
18153
18154 ;; Most CPUs don't like single string operations
18155 ;; Handle this case here to simplify previous expander.
18156
18157 (define_expand "strset"
18158 [(set (match_operand 1 "memory_operand")
18159 (match_operand 2 "register_operand"))
18160 (parallel [(set (match_operand 0 "register_operand")
18161 (match_dup 3))
18162 (clobber (reg:CC FLAGS_REG))])]
18163 ""
18164 {
18165 /* Can't use this for non-default address spaces. */
18166 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
18167 FAIL;
18168
18169 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18170 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18171
18172 /* If .md ever supports :P for Pmode, this can be directly
18173 in the pattern above. */
18174 operands[3] = plus_constant (Pmode, operands[0],
18175 GET_MODE_SIZE (GET_MODE (operands[2])));
18176
18177 /* Can't use this if the user has appropriated eax or edi. */
18178 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18179 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
18180 {
18181 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18182 operands[3]));
18183 DONE;
18184 }
18185 })
18186
18187 (define_expand "strset_singleop"
18188 [(parallel [(set (match_operand 1 "memory_operand")
18189 (match_operand 2 "register_operand"))
18190 (set (match_operand 0 "register_operand")
18191 (match_operand 3))
18192 (unspec [(const_int 0)] UNSPEC_STOS)])]
18193 ""
18194 {
18195 if (TARGET_CLD)
18196 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18197 })
18198
18199 (define_insn "*strsetdi_rex_1"
18200 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
18201 (match_operand:DI 2 "register_operand" "a"))
18202 (set (match_operand:P 0 "register_operand" "=D")
18203 (plus:P (match_dup 1)
18204 (const_int 8)))
18205 (unspec [(const_int 0)] UNSPEC_STOS)]
18206 "TARGET_64BIT
18207 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
18208 && ix86_check_no_addr_space (insn)"
18209 "%^stosq"
18210 [(set_attr "type" "str")
18211 (set_attr "memory" "store")
18212 (set_attr "mode" "DI")])
18213
18214 (define_insn "*strsetsi_1"
18215 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
18216 (match_operand:SI 2 "register_operand" "a"))
18217 (set (match_operand:P 0 "register_operand" "=D")
18218 (plus:P (match_dup 1)
18219 (const_int 4)))
18220 (unspec [(const_int 0)] UNSPEC_STOS)]
18221 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
18222 && ix86_check_no_addr_space (insn)"
18223 "%^stos{l|d}"
18224 [(set_attr "type" "str")
18225 (set_attr "memory" "store")
18226 (set_attr "mode" "SI")])
18227
18228 (define_insn "*strsethi_1"
18229 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
18230 (match_operand:HI 2 "register_operand" "a"))
18231 (set (match_operand:P 0 "register_operand" "=D")
18232 (plus:P (match_dup 1)
18233 (const_int 2)))
18234 (unspec [(const_int 0)] UNSPEC_STOS)]
18235 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
18236 && ix86_check_no_addr_space (insn)"
18237 "%^stosw"
18238 [(set_attr "type" "str")
18239 (set_attr "memory" "store")
18240 (set_attr "mode" "HI")])
18241
18242 (define_insn "*strsetqi_1"
18243 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
18244 (match_operand:QI 2 "register_operand" "a"))
18245 (set (match_operand:P 0 "register_operand" "=D")
18246 (plus:P (match_dup 1)
18247 (const_int 1)))
18248 (unspec [(const_int 0)] UNSPEC_STOS)]
18249 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
18250 && ix86_check_no_addr_space (insn)"
18251 "%^stosb"
18252 [(set_attr "type" "str")
18253 (set_attr "memory" "store")
18254 (set (attr "prefix_rex")
18255 (if_then_else
18256 (match_test "<P:MODE>mode == DImode")
18257 (const_string "0")
18258 (const_string "*")))
18259 (set_attr "mode" "QI")])
18260
18261 (define_expand "rep_stos"
18262 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
18263 (set (match_operand 0 "register_operand")
18264 (match_operand 4))
18265 (set (match_operand 2 "memory_operand") (const_int 0))
18266 (use (match_operand 3 "register_operand"))
18267 (use (match_dup 1))])]
18268 ""
18269 {
18270 if (TARGET_CLD)
18271 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18272 })
18273
18274 (define_insn "*rep_stosdi_rex64"
18275 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
18276 (set (match_operand:P 0 "register_operand" "=D")
18277 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
18278 (const_int 3))
18279 (match_operand:P 3 "register_operand" "0")))
18280 (set (mem:BLK (match_dup 3))
18281 (const_int 0))
18282 (use (match_operand:DI 2 "register_operand" "a"))
18283 (use (match_dup 4))]
18284 "TARGET_64BIT
18285 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18286 && ix86_check_no_addr_space (insn)"
18287 "%^rep{%;} stosq"
18288 [(set_attr "type" "str")
18289 (set_attr "prefix_rep" "1")
18290 (set_attr "memory" "store")
18291 (set_attr "mode" "DI")])
18292
18293 (define_insn "*rep_stossi"
18294 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
18295 (set (match_operand:P 0 "register_operand" "=D")
18296 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
18297 (const_int 2))
18298 (match_operand:P 3 "register_operand" "0")))
18299 (set (mem:BLK (match_dup 3))
18300 (const_int 0))
18301 (use (match_operand:SI 2 "register_operand" "a"))
18302 (use (match_dup 4))]
18303 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18304 && ix86_check_no_addr_space (insn)"
18305 "%^rep{%;} stos{l|d}"
18306 [(set_attr "type" "str")
18307 (set_attr "prefix_rep" "1")
18308 (set_attr "memory" "store")
18309 (set_attr "mode" "SI")])
18310
18311 (define_insn "*rep_stosqi"
18312 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
18313 (set (match_operand:P 0 "register_operand" "=D")
18314 (plus:P (match_operand:P 3 "register_operand" "0")
18315 (match_operand:P 4 "register_operand" "1")))
18316 (set (mem:BLK (match_dup 3))
18317 (const_int 0))
18318 (use (match_operand:QI 2 "register_operand" "a"))
18319 (use (match_dup 4))]
18320 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18321 && ix86_check_no_addr_space (insn)"
18322 "%^rep{%;} stosb"
18323 [(set_attr "type" "str")
18324 (set_attr "prefix_rep" "1")
18325 (set_attr "memory" "store")
18326 (set (attr "prefix_rex")
18327 (if_then_else
18328 (match_test "<P:MODE>mode == DImode")
18329 (const_string "0")
18330 (const_string "*")))
18331 (set_attr "mode" "QI")])
18332
18333 (define_expand "cmpmemsi"
18334 [(set (match_operand:SI 0 "register_operand" "")
18335 (compare:SI (match_operand:BLK 1 "memory_operand" "")
18336 (match_operand:BLK 2 "memory_operand" "") ) )
18337 (use (match_operand 3 "general_operand"))
18338 (use (match_operand 4 "immediate_operand"))]
18339 ""
18340 {
18341 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
18342 operands[2], operands[3],
18343 operands[4], false))
18344 DONE;
18345 else
18346 FAIL;
18347 })
18348
18349 (define_expand "cmpstrnsi"
18350 [(set (match_operand:SI 0 "register_operand")
18351 (compare:SI (match_operand:BLK 1 "general_operand")
18352 (match_operand:BLK 2 "general_operand")))
18353 (use (match_operand 3 "general_operand"))
18354 (use (match_operand 4 "immediate_operand"))]
18355 ""
18356 {
18357 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
18358 operands[2], operands[3],
18359 operands[4], true))
18360 DONE;
18361 else
18362 FAIL;
18363 })
18364
18365 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18366
18367 (define_expand "cmpintqi"
18368 [(set (match_dup 1)
18369 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18370 (set (match_dup 2)
18371 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18372 (parallel [(set (match_operand:QI 0 "register_operand")
18373 (minus:QI (match_dup 1)
18374 (match_dup 2)))
18375 (clobber (reg:CC FLAGS_REG))])]
18376 ""
18377 {
18378 operands[1] = gen_reg_rtx (QImode);
18379 operands[2] = gen_reg_rtx (QImode);
18380 })
18381
18382 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18383 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18384
18385 (define_expand "cmpstrnqi_nz_1"
18386 [(parallel [(set (reg:CC FLAGS_REG)
18387 (compare:CC (match_operand 4 "memory_operand")
18388 (match_operand 5 "memory_operand")))
18389 (use (match_operand 2 "register_operand"))
18390 (use (match_operand:SI 3 "immediate_operand"))
18391 (clobber (match_operand 0 "register_operand"))
18392 (clobber (match_operand 1 "register_operand"))
18393 (clobber (match_dup 2))])]
18394 ""
18395 {
18396 if (TARGET_CLD)
18397 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18398 })
18399
18400 (define_insn "*cmpstrnqi_nz_1"
18401 [(set (reg:CC FLAGS_REG)
18402 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
18403 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
18404 (use (match_operand:P 6 "register_operand" "2"))
18405 (use (match_operand:SI 3 "immediate_operand" "i"))
18406 (clobber (match_operand:P 0 "register_operand" "=S"))
18407 (clobber (match_operand:P 1 "register_operand" "=D"))
18408 (clobber (match_operand:P 2 "register_operand" "=c"))]
18409 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18410 && ix86_check_no_addr_space (insn)"
18411 "%^repz{%;} cmpsb"
18412 [(set_attr "type" "str")
18413 (set_attr "mode" "QI")
18414 (set (attr "prefix_rex")
18415 (if_then_else
18416 (match_test "<P:MODE>mode == DImode")
18417 (const_string "0")
18418 (const_string "*")))
18419 (set_attr "prefix_rep" "1")])
18420
18421 ;; The same, but the count is not known to not be zero.
18422
18423 (define_expand "cmpstrnqi_1"
18424 [(parallel [(set (reg:CC FLAGS_REG)
18425 (if_then_else:CC (ne (match_operand 2 "register_operand")
18426 (const_int 0))
18427 (compare:CC (match_operand 4 "memory_operand")
18428 (match_operand 5 "memory_operand"))
18429 (const_int 0)))
18430 (use (match_operand:SI 3 "immediate_operand"))
18431 (use (reg:CC FLAGS_REG))
18432 (clobber (match_operand 0 "register_operand"))
18433 (clobber (match_operand 1 "register_operand"))
18434 (clobber (match_dup 2))])]
18435 ""
18436 {
18437 if (TARGET_CLD)
18438 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18439 })
18440
18441 (define_insn "*cmpstrnqi_1"
18442 [(set (reg:CC FLAGS_REG)
18443 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
18444 (const_int 0))
18445 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
18446 (mem:BLK (match_operand:P 5 "register_operand" "1")))
18447 (const_int 0)))
18448 (use (match_operand:SI 3 "immediate_operand" "i"))
18449 (use (reg:CC FLAGS_REG))
18450 (clobber (match_operand:P 0 "register_operand" "=S"))
18451 (clobber (match_operand:P 1 "register_operand" "=D"))
18452 (clobber (match_operand:P 2 "register_operand" "=c"))]
18453 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18454 && ix86_check_no_addr_space (insn)"
18455 "%^repz{%;} cmpsb"
18456 [(set_attr "type" "str")
18457 (set_attr "mode" "QI")
18458 (set (attr "prefix_rex")
18459 (if_then_else
18460 (match_test "<P:MODE>mode == DImode")
18461 (const_string "0")
18462 (const_string "*")))
18463 (set_attr "prefix_rep" "1")])
18464
18465 (define_expand "strlen<mode>"
18466 [(set (match_operand:P 0 "register_operand")
18467 (unspec:P [(match_operand:BLK 1 "general_operand")
18468 (match_operand:QI 2 "immediate_operand")
18469 (match_operand 3 "immediate_operand")]
18470 UNSPEC_SCAS))]
18471 ""
18472 {
18473 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18474 DONE;
18475 else
18476 FAIL;
18477 })
18478
18479 (define_expand "strlenqi_1"
18480 [(parallel [(set (match_operand 0 "register_operand")
18481 (match_operand 2))
18482 (clobber (match_operand 1 "register_operand"))
18483 (clobber (reg:CC FLAGS_REG))])]
18484 ""
18485 {
18486 if (TARGET_CLD)
18487 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18488 })
18489
18490 (define_insn "*strlenqi_1"
18491 [(set (match_operand:P 0 "register_operand" "=&c")
18492 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
18493 (match_operand:QI 2 "register_operand" "a")
18494 (match_operand:P 3 "immediate_operand" "i")
18495 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
18496 (clobber (match_operand:P 1 "register_operand" "=D"))
18497 (clobber (reg:CC FLAGS_REG))]
18498 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18499 && ix86_check_no_addr_space (insn)"
18500 "%^repnz{%;} scasb"
18501 [(set_attr "type" "str")
18502 (set_attr "mode" "QI")
18503 (set (attr "prefix_rex")
18504 (if_then_else
18505 (match_test "<P:MODE>mode == DImode")
18506 (const_string "0")
18507 (const_string "*")))
18508 (set_attr "prefix_rep" "1")])
18509
18510 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18511 ;; handled in combine, but it is not currently up to the task.
18512 ;; When used for their truth value, the cmpstrn* expanders generate
18513 ;; code like this:
18514 ;;
18515 ;; repz cmpsb
18516 ;; seta %al
18517 ;; setb %dl
18518 ;; cmpb %al, %dl
18519 ;; jcc label
18520 ;;
18521 ;; The intermediate three instructions are unnecessary.
18522
18523 ;; This one handles cmpstrn*_nz_1...
18524 (define_peephole2
18525 [(parallel[
18526 (set (reg:CC FLAGS_REG)
18527 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18528 (mem:BLK (match_operand 5 "register_operand"))))
18529 (use (match_operand 6 "register_operand"))
18530 (use (match_operand:SI 3 "immediate_operand"))
18531 (clobber (match_operand 0 "register_operand"))
18532 (clobber (match_operand 1 "register_operand"))
18533 (clobber (match_operand 2 "register_operand"))])
18534 (set (match_operand:QI 7 "register_operand")
18535 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18536 (set (match_operand:QI 8 "register_operand")
18537 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18538 (set (reg FLAGS_REG)
18539 (compare (match_dup 7) (match_dup 8)))
18540 ]
18541 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18542 [(parallel[
18543 (set (reg:CC FLAGS_REG)
18544 (compare:CC (mem:BLK (match_dup 4))
18545 (mem:BLK (match_dup 5))))
18546 (use (match_dup 6))
18547 (use (match_dup 3))
18548 (clobber (match_dup 0))
18549 (clobber (match_dup 1))
18550 (clobber (match_dup 2))])])
18551
18552 ;; ...and this one handles cmpstrn*_1.
18553 (define_peephole2
18554 [(parallel[
18555 (set (reg:CC FLAGS_REG)
18556 (if_then_else:CC (ne (match_operand 6 "register_operand")
18557 (const_int 0))
18558 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18559 (mem:BLK (match_operand 5 "register_operand")))
18560 (const_int 0)))
18561 (use (match_operand:SI 3 "immediate_operand"))
18562 (use (reg:CC FLAGS_REG))
18563 (clobber (match_operand 0 "register_operand"))
18564 (clobber (match_operand 1 "register_operand"))
18565 (clobber (match_operand 2 "register_operand"))])
18566 (set (match_operand:QI 7 "register_operand")
18567 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18568 (set (match_operand:QI 8 "register_operand")
18569 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18570 (set (reg FLAGS_REG)
18571 (compare (match_dup 7) (match_dup 8)))
18572 ]
18573 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18574 [(parallel[
18575 (set (reg:CC FLAGS_REG)
18576 (if_then_else:CC (ne (match_dup 6)
18577 (const_int 0))
18578 (compare:CC (mem:BLK (match_dup 4))
18579 (mem:BLK (match_dup 5)))
18580 (const_int 0)))
18581 (use (match_dup 3))
18582 (use (reg:CC FLAGS_REG))
18583 (clobber (match_dup 0))
18584 (clobber (match_dup 1))
18585 (clobber (match_dup 2))])])
18586 \f
18587 ;; Conditional move instructions.
18588
18589 (define_expand "mov<mode>cc"
18590 [(set (match_operand:SWIM 0 "register_operand")
18591 (if_then_else:SWIM (match_operand 1 "comparison_operator")
18592 (match_operand:SWIM 2 "<general_operand>")
18593 (match_operand:SWIM 3 "<general_operand>")))]
18594 ""
18595 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18596
18597 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18598 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18599 ;; So just document what we're doing explicitly.
18600
18601 (define_expand "x86_mov<mode>cc_0_m1"
18602 [(parallel
18603 [(set (match_operand:SWI48 0 "register_operand")
18604 (if_then_else:SWI48
18605 (match_operator:SWI48 2 "ix86_carry_flag_operator"
18606 [(match_operand 1 "flags_reg_operand")
18607 (const_int 0)])
18608 (const_int -1)
18609 (const_int 0)))
18610 (clobber (reg:CC FLAGS_REG))])])
18611
18612 (define_insn "*x86_mov<mode>cc_0_m1"
18613 [(set (match_operand:SWI48 0 "register_operand" "=r")
18614 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18615 [(reg FLAGS_REG) (const_int 0)])
18616 (const_int -1)
18617 (const_int 0)))
18618 (clobber (reg:CC FLAGS_REG))]
18619 ""
18620 "sbb{<imodesuffix>}\t%0, %0"
18621 [(set_attr "type" "alu1")
18622 (set_attr "use_carry" "1")
18623 (set_attr "pent_pair" "pu")
18624 (set_attr "mode" "<MODE>")
18625 (set_attr "length_immediate" "0")])
18626
18627 (define_insn "*x86_mov<mode>cc_0_m1_se"
18628 [(set (match_operand:SWI48 0 "register_operand" "=r")
18629 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18630 [(reg FLAGS_REG) (const_int 0)])
18631 (const_int 1)
18632 (const_int 0)))
18633 (clobber (reg:CC FLAGS_REG))]
18634 ""
18635 "sbb{<imodesuffix>}\t%0, %0"
18636 [(set_attr "type" "alu1")
18637 (set_attr "use_carry" "1")
18638 (set_attr "pent_pair" "pu")
18639 (set_attr "mode" "<MODE>")
18640 (set_attr "length_immediate" "0")])
18641
18642 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18643 [(set (match_operand:SWI 0 "register_operand" "=<r>")
18644 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
18645 [(reg FLAGS_REG) (const_int 0)])))
18646 (clobber (reg:CC FLAGS_REG))]
18647 ""
18648 "sbb{<imodesuffix>}\t%0, %0"
18649 [(set_attr "type" "alu1")
18650 (set_attr "use_carry" "1")
18651 (set_attr "pent_pair" "pu")
18652 (set_attr "mode" "<MODE>")
18653 (set_attr "length_immediate" "0")])
18654
18655 (define_split
18656 [(set (match_operand:SWI48 0 "register_operand")
18657 (neg:SWI48
18658 (leu:SWI48
18659 (match_operand 1 "int_nonimmediate_operand")
18660 (match_operand 2 "const_int_operand"))))]
18661 "x86_64_immediate_operand (operands[2], VOIDmode)
18662 && INTVAL (operands[2]) != -1
18663 && INTVAL (operands[2]) != 2147483647"
18664 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
18665 (set (match_dup 0)
18666 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
18667 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
18668
18669 (define_split
18670 [(set (match_operand:SWI 0 "register_operand")
18671 (neg:SWI
18672 (eq:SWI
18673 (match_operand 1 "int_nonimmediate_operand")
18674 (const_int 0))))]
18675 ""
18676 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
18677 (set (match_dup 0)
18678 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
18679
18680 (define_split
18681 [(set (match_operand:SWI 0 "register_operand")
18682 (neg:SWI
18683 (ne:SWI
18684 (match_operand 1 "int_nonimmediate_operand")
18685 (const_int 0))))]
18686 ""
18687 [(set (reg:CCC FLAGS_REG)
18688 (ne:CCC (match_dup 1) (const_int 0)))
18689 (set (match_dup 0)
18690 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
18691
18692 (define_insn "*mov<mode>cc_noc"
18693 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18694 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18695 [(reg FLAGS_REG) (const_int 0)])
18696 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18697 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18698 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18699 "@
18700 cmov%O2%C1\t{%2, %0|%0, %2}
18701 cmov%O2%c1\t{%3, %0|%0, %3}"
18702 [(set_attr "type" "icmov")
18703 (set_attr "mode" "<MODE>")])
18704
18705 (define_insn "*movsicc_noc_zext"
18706 [(set (match_operand:DI 0 "register_operand" "=r,r")
18707 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18708 [(reg FLAGS_REG) (const_int 0)])
18709 (zero_extend:DI
18710 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
18711 (zero_extend:DI
18712 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
18713 "TARGET_64BIT
18714 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18715 "@
18716 cmov%O2%C1\t{%2, %k0|%k0, %2}
18717 cmov%O2%c1\t{%3, %k0|%k0, %3}"
18718 [(set_attr "type" "icmov")
18719 (set_attr "mode" "SI")])
18720
18721 ;; Don't do conditional moves with memory inputs. This splitter helps
18722 ;; register starved x86_32 by forcing inputs into registers before reload.
18723 (define_split
18724 [(set (match_operand:SWI248 0 "register_operand")
18725 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18726 [(reg FLAGS_REG) (const_int 0)])
18727 (match_operand:SWI248 2 "nonimmediate_operand")
18728 (match_operand:SWI248 3 "nonimmediate_operand")))]
18729 "!TARGET_64BIT && TARGET_CMOVE
18730 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18731 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18732 && can_create_pseudo_p ()
18733 && optimize_insn_for_speed_p ()"
18734 [(set (match_dup 0)
18735 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18736 {
18737 if (MEM_P (operands[2]))
18738 operands[2] = force_reg (<MODE>mode, operands[2]);
18739 if (MEM_P (operands[3]))
18740 operands[3] = force_reg (<MODE>mode, operands[3]);
18741 })
18742
18743 (define_insn "*movqicc_noc"
18744 [(set (match_operand:QI 0 "register_operand" "=r,r")
18745 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18746 [(reg FLAGS_REG) (const_int 0)])
18747 (match_operand:QI 2 "register_operand" "r,0")
18748 (match_operand:QI 3 "register_operand" "0,r")))]
18749 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18750 "#"
18751 [(set_attr "type" "icmov")
18752 (set_attr "mode" "QI")])
18753
18754 (define_split
18755 [(set (match_operand:SWI12 0 "register_operand")
18756 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18757 [(reg FLAGS_REG) (const_int 0)])
18758 (match_operand:SWI12 2 "register_operand")
18759 (match_operand:SWI12 3 "register_operand")))]
18760 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18761 && reload_completed"
18762 [(set (match_dup 0)
18763 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18764 {
18765 operands[0] = gen_lowpart (SImode, operands[0]);
18766 operands[2] = gen_lowpart (SImode, operands[2]);
18767 operands[3] = gen_lowpart (SImode, operands[3]);
18768 })
18769
18770 ;; Don't do conditional moves with memory inputs
18771 (define_peephole2
18772 [(match_scratch:SWI248 4 "r")
18773 (set (match_operand:SWI248 0 "register_operand")
18774 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18775 [(reg FLAGS_REG) (const_int 0)])
18776 (match_operand:SWI248 2 "nonimmediate_operand")
18777 (match_operand:SWI248 3 "nonimmediate_operand")))]
18778 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18779 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18780 && optimize_insn_for_speed_p ()"
18781 [(set (match_dup 4) (match_dup 5))
18782 (set (match_dup 0)
18783 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18784 {
18785 if (MEM_P (operands[2]))
18786 {
18787 operands[5] = operands[2];
18788 operands[2] = operands[4];
18789 }
18790 else if (MEM_P (operands[3]))
18791 {
18792 operands[5] = operands[3];
18793 operands[3] = operands[4];
18794 }
18795 else
18796 gcc_unreachable ();
18797 })
18798
18799 (define_peephole2
18800 [(match_scratch:SI 4 "r")
18801 (set (match_operand:DI 0 "register_operand")
18802 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18803 [(reg FLAGS_REG) (const_int 0)])
18804 (zero_extend:DI
18805 (match_operand:SI 2 "nonimmediate_operand"))
18806 (zero_extend:DI
18807 (match_operand:SI 3 "nonimmediate_operand"))))]
18808 "TARGET_64BIT
18809 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18810 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18811 && optimize_insn_for_speed_p ()"
18812 [(set (match_dup 4) (match_dup 5))
18813 (set (match_dup 0)
18814 (if_then_else:DI (match_dup 1)
18815 (zero_extend:DI (match_dup 2))
18816 (zero_extend:DI (match_dup 3))))]
18817 {
18818 if (MEM_P (operands[2]))
18819 {
18820 operands[5] = operands[2];
18821 operands[2] = operands[4];
18822 }
18823 else if (MEM_P (operands[3]))
18824 {
18825 operands[5] = operands[3];
18826 operands[3] = operands[4];
18827 }
18828 else
18829 gcc_unreachable ();
18830 })
18831
18832 (define_expand "mov<mode>cc"
18833 [(set (match_operand:X87MODEF 0 "register_operand")
18834 (if_then_else:X87MODEF
18835 (match_operand 1 "comparison_operator")
18836 (match_operand:X87MODEF 2 "register_operand")
18837 (match_operand:X87MODEF 3 "register_operand")))]
18838 "(TARGET_80387 && TARGET_CMOVE)
18839 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18840 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18841
18842 (define_insn "*movxfcc_1"
18843 [(set (match_operand:XF 0 "register_operand" "=f,f")
18844 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18845 [(reg FLAGS_REG) (const_int 0)])
18846 (match_operand:XF 2 "register_operand" "f,0")
18847 (match_operand:XF 3 "register_operand" "0,f")))]
18848 "TARGET_80387 && TARGET_CMOVE"
18849 "@
18850 fcmov%F1\t{%2, %0|%0, %2}
18851 fcmov%f1\t{%3, %0|%0, %3}"
18852 [(set_attr "type" "fcmov")
18853 (set_attr "mode" "XF")])
18854
18855 (define_insn "*movdfcc_1"
18856 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18857 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18858 [(reg FLAGS_REG) (const_int 0)])
18859 (match_operand:DF 2 "nonimmediate_operand"
18860 "f ,0,rm,0 ,rm,0")
18861 (match_operand:DF 3 "nonimmediate_operand"
18862 "0 ,f,0 ,rm,0, rm")))]
18863 "TARGET_80387 && TARGET_CMOVE
18864 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18865 "@
18866 fcmov%F1\t{%2, %0|%0, %2}
18867 fcmov%f1\t{%3, %0|%0, %3}
18868 #
18869 #
18870 cmov%O2%C1\t{%2, %0|%0, %2}
18871 cmov%O2%c1\t{%3, %0|%0, %3}"
18872 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18873 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18874 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18875
18876 (define_split
18877 [(set (match_operand:DF 0 "general_reg_operand")
18878 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18879 [(reg FLAGS_REG) (const_int 0)])
18880 (match_operand:DF 2 "nonimmediate_operand")
18881 (match_operand:DF 3 "nonimmediate_operand")))]
18882 "!TARGET_64BIT && reload_completed"
18883 [(set (match_dup 2)
18884 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18885 (set (match_dup 3)
18886 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18887 {
18888 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18889 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18890 })
18891
18892 (define_insn "*movsfcc_1_387"
18893 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18894 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18895 [(reg FLAGS_REG) (const_int 0)])
18896 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18897 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18898 "TARGET_80387 && TARGET_CMOVE
18899 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18900 "@
18901 fcmov%F1\t{%2, %0|%0, %2}
18902 fcmov%f1\t{%3, %0|%0, %3}
18903 cmov%O2%C1\t{%2, %0|%0, %2}
18904 cmov%O2%c1\t{%3, %0|%0, %3}"
18905 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18906 (set_attr "mode" "SF,SF,SI,SI")])
18907
18908 ;; Don't do conditional moves with memory inputs. This splitter helps
18909 ;; register starved x86_32 by forcing inputs into registers before reload.
18910 (define_split
18911 [(set (match_operand:MODEF 0 "register_operand")
18912 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18913 [(reg FLAGS_REG) (const_int 0)])
18914 (match_operand:MODEF 2 "nonimmediate_operand")
18915 (match_operand:MODEF 3 "nonimmediate_operand")))]
18916 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18917 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18918 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18919 && can_create_pseudo_p ()
18920 && optimize_insn_for_speed_p ()"
18921 [(set (match_dup 0)
18922 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18923 {
18924 if (MEM_P (operands[2]))
18925 operands[2] = force_reg (<MODE>mode, operands[2]);
18926 if (MEM_P (operands[3]))
18927 operands[3] = force_reg (<MODE>mode, operands[3]);
18928 })
18929
18930 ;; Don't do conditional moves with memory inputs
18931 (define_peephole2
18932 [(match_scratch:MODEF 4 "r")
18933 (set (match_operand:MODEF 0 "general_reg_operand")
18934 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18935 [(reg FLAGS_REG) (const_int 0)])
18936 (match_operand:MODEF 2 "nonimmediate_operand")
18937 (match_operand:MODEF 3 "nonimmediate_operand")))]
18938 "(<MODE>mode != DFmode || TARGET_64BIT)
18939 && TARGET_80387 && TARGET_CMOVE
18940 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18941 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18942 && optimize_insn_for_speed_p ()"
18943 [(set (match_dup 4) (match_dup 5))
18944 (set (match_dup 0)
18945 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18946 {
18947 if (MEM_P (operands[2]))
18948 {
18949 operands[5] = operands[2];
18950 operands[2] = operands[4];
18951 }
18952 else if (MEM_P (operands[3]))
18953 {
18954 operands[5] = operands[3];
18955 operands[3] = operands[4];
18956 }
18957 else
18958 gcc_unreachable ();
18959 })
18960
18961 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18962 ;; the scalar versions to have only XMM registers as operands.
18963
18964 ;; XOP conditional move
18965 (define_insn "*xop_pcmov_<mode>"
18966 [(set (match_operand:MODEF 0 "register_operand" "=x")
18967 (if_then_else:MODEF
18968 (match_operand:MODEF 1 "register_operand" "x")
18969 (match_operand:MODEF 2 "register_operand" "x")
18970 (match_operand:MODEF 3 "register_operand" "x")))]
18971 "TARGET_XOP"
18972 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18973 [(set_attr "type" "sse4arg")])
18974
18975 ;; These versions of the min/max patterns are intentionally ignorant of
18976 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18977 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18978 ;; are undefined in this condition, we're certain this is correct.
18979
18980 (define_insn "<code><mode>3"
18981 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18982 (smaxmin:MODEF
18983 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18984 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18985 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18986 "@
18987 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18988 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18989 [(set_attr "isa" "noavx,avx")
18990 (set_attr "prefix" "orig,vex")
18991 (set_attr "type" "sseadd")
18992 (set_attr "mode" "<MODE>")])
18993
18994 ;; These versions of the min/max patterns implement exactly the operations
18995 ;; min = (op1 < op2 ? op1 : op2)
18996 ;; max = (!(op1 < op2) ? op1 : op2)
18997 ;; Their operands are not commutative, and thus they may be used in the
18998 ;; presence of -0.0 and NaN.
18999
19000 (define_insn "*ieee_s<ieee_maxmin><mode>3"
19001 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
19002 (unspec:MODEF
19003 [(match_operand:MODEF 1 "register_operand" "0,v")
19004 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
19005 IEEE_MAXMIN))]
19006 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19007 "@
19008 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
19009 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
19010 [(set_attr "isa" "noavx,avx")
19011 (set_attr "prefix" "orig,maybe_evex")
19012 (set_attr "type" "sseadd")
19013 (set_attr "mode" "<MODE>")])
19014
19015 ;; Make two stack loads independent:
19016 ;; fld aa fld aa
19017 ;; fld %st(0) -> fld bb
19018 ;; fmul bb fmul %st(1), %st
19019 ;;
19020 ;; Actually we only match the last two instructions for simplicity.
19021
19022 (define_peephole2
19023 [(set (match_operand 0 "fp_register_operand")
19024 (match_operand 1 "fp_register_operand"))
19025 (set (match_dup 0)
19026 (match_operator 2 "binary_fp_operator"
19027 [(match_dup 0)
19028 (match_operand 3 "memory_operand")]))]
19029 "REGNO (operands[0]) != REGNO (operands[1])"
19030 [(set (match_dup 0) (match_dup 3))
19031 (set (match_dup 0)
19032 (match_op_dup 2
19033 [(match_dup 5) (match_dup 4)]))]
19034 {
19035 operands[4] = operands[0];
19036 operands[5] = operands[1];
19037
19038 /* The % modifier is not operational anymore in peephole2's, so we have to
19039 swap the operands manually in the case of addition and multiplication. */
19040 if (COMMUTATIVE_ARITH_P (operands[2]))
19041 std::swap (operands[4], operands[5]);
19042 })
19043
19044 (define_peephole2
19045 [(set (match_operand 0 "fp_register_operand")
19046 (match_operand 1 "fp_register_operand"))
19047 (set (match_dup 0)
19048 (match_operator 2 "binary_fp_operator"
19049 [(match_operand 3 "memory_operand")
19050 (match_dup 0)]))]
19051 "REGNO (operands[0]) != REGNO (operands[1])"
19052 [(set (match_dup 0) (match_dup 3))
19053 (set (match_dup 0)
19054 (match_op_dup 2
19055 [(match_dup 4) (match_dup 5)]))]
19056 {
19057 operands[4] = operands[0];
19058 operands[5] = operands[1];
19059
19060 /* The % modifier is not operational anymore in peephole2's, so we have to
19061 swap the operands manually in the case of addition and multiplication. */
19062 if (COMMUTATIVE_ARITH_P (operands[2]))
19063 std::swap (operands[4], operands[5]);
19064 })
19065
19066 ;; Conditional addition patterns
19067 (define_expand "add<mode>cc"
19068 [(match_operand:SWI 0 "register_operand")
19069 (match_operand 1 "ordered_comparison_operator")
19070 (match_operand:SWI 2 "register_operand")
19071 (match_operand:SWI 3 "const_int_operand")]
19072 ""
19073 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19074
19075 ;; min/max patterns
19076
19077 (define_code_attr maxmin_rel
19078 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
19079
19080 (define_expand "<code><mode>3"
19081 [(parallel
19082 [(set (match_operand:SDWIM 0 "register_operand")
19083 (maxmin:SDWIM
19084 (match_operand:SDWIM 1 "register_operand")
19085 (match_operand:SDWIM 2 "general_operand")))
19086 (clobber (reg:CC FLAGS_REG))])]
19087 "TARGET_CMOVE
19088 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
19089
19090 (define_insn_and_split "*<code><dwi>3_doubleword"
19091 [(set (match_operand:<DWI> 0 "register_operand")
19092 (maxmin:<DWI>
19093 (match_operand:<DWI> 1 "register_operand")
19094 (match_operand:<DWI> 2 "general_operand")))
19095 (clobber (reg:CC FLAGS_REG))]
19096 "TARGET_CMOVE
19097 && ix86_pre_reload_split ()"
19098 "#"
19099 "&& 1"
19100 [(set (match_dup 0)
19101 (if_then_else:DWIH (match_dup 6)
19102 (match_dup 1)
19103 (match_dup 2)))
19104 (set (match_dup 3)
19105 (if_then_else:DWIH (match_dup 6)
19106 (match_dup 4)
19107 (match_dup 5)))]
19108 {
19109 operands[2] = force_reg (<DWI>mode, operands[2]);
19110
19111 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
19112
19113 rtx cmplo[2] = { operands[1], operands[2] };
19114 rtx cmphi[2] = { operands[4], operands[5] };
19115
19116 enum rtx_code code = <maxmin_rel>;
19117
19118 switch (code)
19119 {
19120 case LE: case LEU:
19121 std::swap (cmplo[0], cmplo[1]);
19122 std::swap (cmphi[0], cmphi[1]);
19123 code = swap_condition (code);
19124 /* FALLTHRU */
19125
19126 case GE: case GEU:
19127 {
19128 bool uns = (code == GEU);
19129 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
19130 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
19131
19132 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
19133
19134 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
19135 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
19136
19137 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
19138 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
19139
19140 break;
19141 }
19142
19143 default:
19144 gcc_unreachable ();
19145 }
19146 })
19147
19148 (define_insn_and_split "*<code><mode>3_1"
19149 [(set (match_operand:SWI 0 "register_operand")
19150 (maxmin:SWI
19151 (match_operand:SWI 1 "register_operand")
19152 (match_operand:SWI 2 "general_operand")))
19153 (clobber (reg:CC FLAGS_REG))]
19154 "TARGET_CMOVE
19155 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
19156 && ix86_pre_reload_split ()"
19157 "#"
19158 "&& 1"
19159 [(set (match_dup 0)
19160 (if_then_else:SWI (match_dup 3)
19161 (match_dup 1)
19162 (match_dup 2)))]
19163 {
19164 machine_mode mode = <MODE>mode;
19165 rtx cmp_op = operands[2];
19166
19167 operands[2] = force_reg (mode, cmp_op);
19168
19169 enum rtx_code code = <maxmin_rel>;
19170
19171 if (cmp_op == const1_rtx)
19172 {
19173 /* Convert smax (x, 1) into (x > 0 ? x : 1).
19174 Convert umax (x, 1) into (x != 0 ? x : 1).
19175 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
19176 cmp_op = const0_rtx;
19177 if (code == GE)
19178 code = GT;
19179 else if (code == GEU)
19180 code = NE;
19181 }
19182 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
19183 else if (cmp_op == constm1_rtx && code == LE)
19184 {
19185 cmp_op = const0_rtx;
19186 code = LT;
19187 }
19188 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
19189 else if (cmp_op == constm1_rtx && code == GE)
19190 cmp_op = const0_rtx;
19191 else if (cmp_op != const0_rtx)
19192 cmp_op = operands[2];
19193
19194 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
19195 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
19196
19197 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
19198 emit_insn (gen_rtx_SET (flags, tmp));
19199
19200 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
19201 })
19202
19203 ;; Avoid clearing a register between a flags setting comparison and its use,
19204 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
19205 (define_peephole2
19206 [(set (reg FLAGS_REG) (match_operand 0))
19207 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
19208 "peep2_regno_dead_p (0, FLAGS_REG)
19209 && !reg_overlap_mentioned_p (operands[1], operands[0])"
19210 [(set (match_dup 2) (match_dup 0))]
19211 {
19212 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
19213 ix86_expand_clear (operands[1]);
19214 })
19215
19216 ;; Reload dislikes loading constants directly into class_likely_spilled
19217 ;; hard registers. Try to tidy things up here.
19218 (define_peephole2
19219 [(set (match_operand:SWI 0 "general_reg_operand")
19220 (match_operand:SWI 1 "x86_64_general_operand"))
19221 (set (match_operand:SWI 2 "general_reg_operand")
19222 (match_dup 0))]
19223 "peep2_reg_dead_p (2, operands[0])"
19224 [(set (match_dup 2) (match_dup 1))])
19225 \f
19226 ;; Misc patterns (?)
19227
19228 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19229 ;; Otherwise there will be nothing to keep
19230 ;;
19231 ;; [(set (reg ebp) (reg esp))]
19232 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19233 ;; (clobber (eflags)]
19234 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19235 ;;
19236 ;; in proper program order.
19237
19238 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
19239 [(set (match_operand:P 0 "register_operand" "=r,r")
19240 (plus:P (match_operand:P 1 "register_operand" "0,r")
19241 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
19242 (clobber (reg:CC FLAGS_REG))
19243 (clobber (mem:BLK (scratch)))]
19244 ""
19245 {
19246 switch (get_attr_type (insn))
19247 {
19248 case TYPE_IMOV:
19249 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
19250
19251 case TYPE_ALU:
19252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
19253 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
19254 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
19255
19256 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
19257
19258 default:
19259 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19260 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
19261 }
19262 }
19263 [(set (attr "type")
19264 (cond [(and (eq_attr "alternative" "0")
19265 (not (match_test "TARGET_OPT_AGU")))
19266 (const_string "alu")
19267 (match_operand:<MODE> 2 "const0_operand")
19268 (const_string "imov")
19269 ]
19270 (const_string "lea")))
19271 (set (attr "length_immediate")
19272 (cond [(eq_attr "type" "imov")
19273 (const_string "0")
19274 (and (eq_attr "type" "alu")
19275 (match_operand 2 "const128_operand"))
19276 (const_string "1")
19277 ]
19278 (const_string "*")))
19279 (set_attr "mode" "<MODE>")])
19280
19281 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
19282 [(set (match_operand:P 0 "register_operand" "=r")
19283 (minus:P (match_operand:P 1 "register_operand" "0")
19284 (match_operand:P 2 "register_operand" "r")))
19285 (clobber (reg:CC FLAGS_REG))
19286 (clobber (mem:BLK (scratch)))]
19287 ""
19288 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
19289 [(set_attr "type" "alu")
19290 (set_attr "mode" "<MODE>")])
19291
19292 (define_insn "@allocate_stack_worker_probe_<mode>"
19293 [(set (match_operand:P 0 "register_operand" "=a")
19294 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
19295 UNSPECV_STACK_PROBE))
19296 (clobber (reg:CC FLAGS_REG))]
19297 "ix86_target_stack_probe ()"
19298 "call\t___chkstk_ms"
19299 [(set_attr "type" "multi")
19300 (set_attr "length" "5")])
19301
19302 (define_expand "allocate_stack"
19303 [(match_operand 0 "register_operand")
19304 (match_operand 1 "general_operand")]
19305 "ix86_target_stack_probe ()"
19306 {
19307 rtx x;
19308
19309 #ifndef CHECK_STACK_LIMIT
19310 #define CHECK_STACK_LIMIT 0
19311 #endif
19312
19313 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19314 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19315 x = operands[1];
19316 else
19317 {
19318 x = copy_to_mode_reg (Pmode, operands[1]);
19319
19320 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
19321 }
19322
19323 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
19324 stack_pointer_rtx, 0, OPTAB_DIRECT);
19325
19326 if (x != stack_pointer_rtx)
19327 emit_move_insn (stack_pointer_rtx, x);
19328
19329 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19330 DONE;
19331 })
19332
19333 (define_expand "probe_stack"
19334 [(match_operand 0 "memory_operand")]
19335 ""
19336 {
19337 emit_insn (gen_probe_stack_1
19338 (word_mode, operands[0], const0_rtx));
19339 DONE;
19340 })
19341
19342 ;; Use OR for stack probes, this is shorter.
19343 (define_insn "@probe_stack_1_<mode>"
19344 [(set (match_operand:W 0 "memory_operand" "=m")
19345 (unspec:W [(match_operand:W 1 "const0_operand")]
19346 UNSPEC_PROBE_STACK))
19347 (clobber (reg:CC FLAGS_REG))]
19348 ""
19349 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
19350 [(set_attr "type" "alu1")
19351 (set_attr "mode" "<MODE>")
19352 (set_attr "length_immediate" "1")])
19353
19354 (define_insn "@adjust_stack_and_probe_<mode>"
19355 [(set (match_operand:P 0 "register_operand" "=r")
19356 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
19357 UNSPECV_PROBE_STACK_RANGE))
19358 (set (reg:P SP_REG)
19359 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
19360 (clobber (reg:CC FLAGS_REG))
19361 (clobber (mem:BLK (scratch)))]
19362 ""
19363 "* return output_adjust_stack_and_probe (operands[0]);"
19364 [(set_attr "type" "multi")])
19365
19366 (define_insn "@probe_stack_range_<mode>"
19367 [(set (match_operand:P 0 "register_operand" "=r")
19368 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
19369 (match_operand:P 2 "const_int_operand" "n")]
19370 UNSPECV_PROBE_STACK_RANGE))
19371 (clobber (reg:CC FLAGS_REG))]
19372 ""
19373 "* return output_probe_stack_range (operands[0], operands[2]);"
19374 [(set_attr "type" "multi")])
19375
19376 (define_expand "builtin_setjmp_receiver"
19377 [(label_ref (match_operand 0))]
19378 "!TARGET_64BIT && flag_pic"
19379 {
19380 #if TARGET_MACHO
19381 if (TARGET_MACHO)
19382 {
19383 rtx xops[3];
19384 rtx_code_label *label_rtx = gen_label_rtx ();
19385 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19386 xops[0] = xops[1] = pic_offset_table_rtx;
19387 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
19388 ix86_expand_binary_operator (MINUS, SImode, xops);
19389 }
19390 else
19391 #endif
19392 emit_insn (gen_set_got (pic_offset_table_rtx));
19393 DONE;
19394 })
19395
19396 (define_expand "save_stack_nonlocal"
19397 [(set (match_operand 0 "memory_operand")
19398 (match_operand 1 "register_operand"))]
19399 ""
19400 {
19401 rtx stack_slot;
19402
19403 if (flag_cf_protection & CF_RETURN)
19404 {
19405 /* Copy shadow stack pointer to the first slot
19406 and stack pointer to the second slot. */
19407 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
19408 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
19409
19410 rtx reg_ssp = force_reg (word_mode, const0_rtx);
19411 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
19412 emit_move_insn (ssp_slot, reg_ssp);
19413 }
19414 else
19415 stack_slot = adjust_address (operands[0], Pmode, 0);
19416 emit_move_insn (stack_slot, operands[1]);
19417 DONE;
19418 })
19419
19420 (define_expand "restore_stack_nonlocal"
19421 [(set (match_operand 0 "register_operand" "")
19422 (match_operand 1 "memory_operand" ""))]
19423 ""
19424 {
19425 rtx stack_slot;
19426
19427 if (flag_cf_protection & CF_RETURN)
19428 {
19429 /* Restore shadow stack pointer from the first slot
19430 and stack pointer from the second slot. */
19431 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
19432 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
19433
19434 /* Get the current shadow stack pointer. The code below will check if
19435 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
19436 is a NOP. */
19437 rtx reg_ssp = force_reg (word_mode, const0_rtx);
19438 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
19439
19440 /* Compare through subtraction the saved and the current ssp
19441 to decide if ssp has to be adjusted. */
19442 reg_ssp = expand_simple_binop (word_mode, MINUS,
19443 reg_ssp, ssp_slot,
19444 reg_ssp, 1, OPTAB_DIRECT);
19445
19446 /* Compare and jump over adjustment code. */
19447 rtx noadj_label = gen_label_rtx ();
19448 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
19449 word_mode, 1, noadj_label);
19450
19451 /* Compute the number of frames to adjust. */
19452 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
19453 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
19454 NULL_RTX, 1);
19455
19456 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
19457 GEN_INT (exact_log2 (UNITS_PER_WORD)),
19458 reg_adj, 1, OPTAB_DIRECT);
19459
19460 /* Check if number of frames <= 255 so no loop is needed. */
19461 rtx inc_label = gen_label_rtx ();
19462 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
19463 ptr_mode, 1, inc_label);
19464
19465 /* Adjust the ssp in a loop. */
19466 rtx loop_label = gen_label_rtx ();
19467 emit_label (loop_label);
19468 LABEL_NUSES (loop_label) = 1;
19469
19470 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
19471 emit_insn (gen_incssp (word_mode, reg_255));
19472
19473 reg_adj = expand_simple_binop (ptr_mode, MINUS,
19474 reg_adj, GEN_INT (255),
19475 reg_adj, 1, OPTAB_DIRECT);
19476
19477 /* Compare and jump to the loop label. */
19478 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
19479 ptr_mode, 1, loop_label);
19480
19481 emit_label (inc_label);
19482 LABEL_NUSES (inc_label) = 1;
19483
19484 emit_insn (gen_incssp (word_mode, reg_ssp));
19485
19486 emit_label (noadj_label);
19487 LABEL_NUSES (noadj_label) = 1;
19488 }
19489 else
19490 stack_slot = adjust_address (operands[1], Pmode, 0);
19491 emit_move_insn (operands[0], stack_slot);
19492 DONE;
19493 })
19494
19495
19496 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19497 ;; Do not split instructions with mask registers.
19498 (define_split
19499 [(set (match_operand 0 "general_reg_operand")
19500 (match_operator 3 "promotable_binary_operator"
19501 [(match_operand 1 "general_reg_operand")
19502 (match_operand 2 "aligned_operand")]))
19503 (clobber (reg:CC FLAGS_REG))]
19504 "! TARGET_PARTIAL_REG_STALL && reload_completed
19505 && ((GET_MODE (operands[0]) == HImode
19506 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19507 /* ??? next two lines just !satisfies_constraint_K (...) */
19508 || !CONST_INT_P (operands[2])
19509 || satisfies_constraint_K (operands[2])))
19510 || (GET_MODE (operands[0]) == QImode
19511 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19512 [(parallel [(set (match_dup 0)
19513 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19514 (clobber (reg:CC FLAGS_REG))])]
19515 {
19516 operands[0] = gen_lowpart (SImode, operands[0]);
19517 operands[1] = gen_lowpart (SImode, operands[1]);
19518 if (GET_CODE (operands[3]) != ASHIFT)
19519 operands[2] = gen_lowpart (SImode, operands[2]);
19520 operands[3] = shallow_copy_rtx (operands[3]);
19521 PUT_MODE (operands[3], SImode);
19522 })
19523
19524 ; Promote the QImode tests, as i386 has encoding of the AND
19525 ; instruction with 32-bit sign-extended immediate and thus the
19526 ; instruction size is unchanged, except in the %eax case for
19527 ; which it is increased by one byte, hence the ! optimize_size.
19528 (define_split
19529 [(set (match_operand 0 "flags_reg_operand")
19530 (match_operator 2 "compare_operator"
19531 [(and (match_operand 3 "aligned_operand")
19532 (match_operand 4 "const_int_operand"))
19533 (const_int 0)]))
19534 (set (match_operand 1 "register_operand")
19535 (and (match_dup 3) (match_dup 4)))]
19536 "! TARGET_PARTIAL_REG_STALL && reload_completed
19537 && optimize_insn_for_speed_p ()
19538 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19539 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19540 /* Ensure that the operand will remain sign-extended immediate. */
19541 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19542 [(parallel [(set (match_dup 0)
19543 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19544 (const_int 0)]))
19545 (set (match_dup 1)
19546 (and:SI (match_dup 3) (match_dup 4)))])]
19547 {
19548 operands[4]
19549 = gen_int_mode (INTVAL (operands[4])
19550 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19551 operands[1] = gen_lowpart (SImode, operands[1]);
19552 operands[3] = gen_lowpart (SImode, operands[3]);
19553 })
19554
19555 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19556 ; the TEST instruction with 32-bit sign-extended immediate and thus
19557 ; the instruction size would at least double, which is not what we
19558 ; want even with ! optimize_size.
19559 (define_split
19560 [(set (match_operand 0 "flags_reg_operand")
19561 (match_operator 1 "compare_operator"
19562 [(and (match_operand:HI 2 "aligned_operand")
19563 (match_operand:HI 3 "const_int_operand"))
19564 (const_int 0)]))]
19565 "! TARGET_PARTIAL_REG_STALL && reload_completed
19566 && ! TARGET_FAST_PREFIX
19567 && optimize_insn_for_speed_p ()
19568 /* Ensure that the operand will remain sign-extended immediate. */
19569 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19570 [(set (match_dup 0)
19571 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19572 (const_int 0)]))]
19573 {
19574 operands[3]
19575 = gen_int_mode (INTVAL (operands[3])
19576 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19577 operands[2] = gen_lowpart (SImode, operands[2]);
19578 })
19579
19580 (define_split
19581 [(set (match_operand 0 "register_operand")
19582 (neg (match_operand 1 "register_operand")))
19583 (clobber (reg:CC FLAGS_REG))]
19584 "! TARGET_PARTIAL_REG_STALL && reload_completed
19585 && (GET_MODE (operands[0]) == HImode
19586 || (GET_MODE (operands[0]) == QImode
19587 && (TARGET_PROMOTE_QImode
19588 || optimize_insn_for_size_p ())))"
19589 [(parallel [(set (match_dup 0)
19590 (neg:SI (match_dup 1)))
19591 (clobber (reg:CC FLAGS_REG))])]
19592 {
19593 operands[0] = gen_lowpart (SImode, operands[0]);
19594 operands[1] = gen_lowpart (SImode, operands[1]);
19595 })
19596
19597 ;; Do not split instructions with mask regs.
19598 (define_split
19599 [(set (match_operand 0 "general_reg_operand")
19600 (not (match_operand 1 "general_reg_operand")))]
19601 "! TARGET_PARTIAL_REG_STALL && reload_completed
19602 && (GET_MODE (operands[0]) == HImode
19603 || (GET_MODE (operands[0]) == QImode
19604 && (TARGET_PROMOTE_QImode
19605 || optimize_insn_for_size_p ())))"
19606 [(set (match_dup 0)
19607 (not:SI (match_dup 1)))]
19608 {
19609 operands[0] = gen_lowpart (SImode, operands[0]);
19610 operands[1] = gen_lowpart (SImode, operands[1]);
19611 })
19612 \f
19613 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19614 ;; transform a complex memory operation into two memory to register operations.
19615
19616 ;; Don't push memory operands
19617 (define_peephole2
19618 [(set (match_operand:SWI 0 "push_operand")
19619 (match_operand:SWI 1 "memory_operand"))
19620 (match_scratch:SWI 2 "<r>")]
19621 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19622 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19623 [(set (match_dup 2) (match_dup 1))
19624 (set (match_dup 0) (match_dup 2))])
19625
19626 ;; We need to handle SFmode only, because DFmode and XFmode are split to
19627 ;; SImode pushes.
19628 (define_peephole2
19629 [(set (match_operand:SF 0 "push_operand")
19630 (match_operand:SF 1 "memory_operand"))
19631 (match_scratch:SF 2 "r")]
19632 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19633 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19634 [(set (match_dup 2) (match_dup 1))
19635 (set (match_dup 0) (match_dup 2))])
19636
19637 ;; Don't move an immediate directly to memory when the instruction
19638 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
19639 (define_peephole2
19640 [(match_scratch:SWI124 1 "<r>")
19641 (set (match_operand:SWI124 0 "memory_operand")
19642 (const_int 0))]
19643 "optimize_insn_for_speed_p ()
19644 && ((<MODE>mode == HImode
19645 && TARGET_LCP_STALL)
19646 || (!TARGET_USE_MOV0
19647 && TARGET_SPLIT_LONG_MOVES
19648 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
19649 && peep2_regno_dead_p (0, FLAGS_REG)"
19650 [(parallel [(set (match_dup 2) (const_int 0))
19651 (clobber (reg:CC FLAGS_REG))])
19652 (set (match_dup 0) (match_dup 1))]
19653 "operands[2] = gen_lowpart (SImode, operands[1]);")
19654
19655 (define_peephole2
19656 [(match_scratch:SWI124 2 "<r>")
19657 (set (match_operand:SWI124 0 "memory_operand")
19658 (match_operand:SWI124 1 "immediate_operand"))]
19659 "optimize_insn_for_speed_p ()
19660 && ((<MODE>mode == HImode
19661 && TARGET_LCP_STALL)
19662 || (TARGET_SPLIT_LONG_MOVES
19663 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
19664 [(set (match_dup 2) (match_dup 1))
19665 (set (match_dup 0) (match_dup 2))])
19666
19667 ;; Don't compare memory with zero, load and use a test instead.
19668 (define_peephole2
19669 [(set (match_operand 0 "flags_reg_operand")
19670 (match_operator 1 "compare_operator"
19671 [(match_operand:SI 2 "memory_operand")
19672 (const_int 0)]))
19673 (match_scratch:SI 3 "r")]
19674 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19675 [(set (match_dup 3) (match_dup 2))
19676 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
19677
19678 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19679 ;; Don't split NOTs with a displacement operand, because resulting XOR
19680 ;; will not be pairable anyway.
19681 ;;
19682 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19683 ;; represented using a modRM byte. The XOR replacement is long decoded,
19684 ;; so this split helps here as well.
19685 ;;
19686 ;; Note: Can't do this as a regular split because we can't get proper
19687 ;; lifetime information then.
19688
19689 (define_peephole2
19690 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
19691 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
19692 "optimize_insn_for_speed_p ()
19693 && ((TARGET_NOT_UNPAIRABLE
19694 && (!MEM_P (operands[0])
19695 || !memory_displacement_operand (operands[0], <MODE>mode)))
19696 || (TARGET_NOT_VECTORMODE
19697 && long_memory_operand (operands[0], <MODE>mode)))
19698 && peep2_regno_dead_p (0, FLAGS_REG)"
19699 [(parallel [(set (match_dup 0)
19700 (xor:SWI124 (match_dup 1) (const_int -1)))
19701 (clobber (reg:CC FLAGS_REG))])])
19702
19703 ;; Non pairable "test imm, reg" instructions can be translated to
19704 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19705 ;; byte opcode instead of two, have a short form for byte operands),
19706 ;; so do it for other CPUs as well. Given that the value was dead,
19707 ;; this should not create any new dependencies. Pass on the sub-word
19708 ;; versions if we're concerned about partial register stalls.
19709
19710 (define_peephole2
19711 [(set (match_operand 0 "flags_reg_operand")
19712 (match_operator 1 "compare_operator"
19713 [(and:SI (match_operand:SI 2 "register_operand")
19714 (match_operand:SI 3 "immediate_operand"))
19715 (const_int 0)]))]
19716 "ix86_match_ccmode (insn, CCNOmode)
19717 && (REGNO (operands[2]) != AX_REG
19718 || satisfies_constraint_K (operands[3]))
19719 && peep2_reg_dead_p (1, operands[2])"
19720 [(parallel
19721 [(set (match_dup 0)
19722 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19723 (const_int 0)]))
19724 (set (match_dup 2)
19725 (and:SI (match_dup 2) (match_dup 3)))])])
19726
19727 ;; We don't need to handle HImode case, because it will be promoted to SImode
19728 ;; on ! TARGET_PARTIAL_REG_STALL
19729
19730 (define_peephole2
19731 [(set (match_operand 0 "flags_reg_operand")
19732 (match_operator 1 "compare_operator"
19733 [(and:QI (match_operand:QI 2 "register_operand")
19734 (match_operand:QI 3 "immediate_operand"))
19735 (const_int 0)]))]
19736 "! TARGET_PARTIAL_REG_STALL
19737 && ix86_match_ccmode (insn, CCNOmode)
19738 && REGNO (operands[2]) != AX_REG
19739 && peep2_reg_dead_p (1, operands[2])"
19740 [(parallel
19741 [(set (match_dup 0)
19742 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19743 (const_int 0)]))
19744 (set (match_dup 2)
19745 (and:QI (match_dup 2) (match_dup 3)))])])
19746
19747 (define_peephole2
19748 [(set (match_operand 0 "flags_reg_operand")
19749 (match_operator 1 "compare_operator"
19750 [(and:QI
19751 (subreg:QI
19752 (zero_extract:SWI248 (match_operand:SWI248 2 "QIreg_operand")
19753 (const_int 8)
19754 (const_int 8)) 0)
19755 (match_operand 3 "const_int_operand"))
19756 (const_int 0)]))]
19757 "! TARGET_PARTIAL_REG_STALL
19758 && ix86_match_ccmode (insn, CCNOmode)
19759 && REGNO (operands[2]) != AX_REG
19760 && peep2_reg_dead_p (1, operands[2])"
19761 [(parallel
19762 [(set (match_dup 0)
19763 (match_op_dup 1
19764 [(and:QI
19765 (subreg:QI
19766 (zero_extract:SWI248 (match_dup 2)
19767 (const_int 8)
19768 (const_int 8)) 0)
19769 (match_dup 3))
19770 (const_int 0)]))
19771 (set (zero_extract:SWI248 (match_dup 2)
19772 (const_int 8)
19773 (const_int 8))
19774 (subreg:SWI248
19775 (and:QI
19776 (subreg:QI
19777 (zero_extract:SWI248 (match_dup 2)
19778 (const_int 8)
19779 (const_int 8)) 0)
19780 (match_dup 3)) 0))])])
19781
19782 ;; Don't do logical operations with memory inputs.
19783 (define_peephole2
19784 [(match_scratch:SWI 2 "<r>")
19785 (parallel [(set (match_operand:SWI 0 "register_operand")
19786 (match_operator:SWI 3 "arith_or_logical_operator"
19787 [(match_dup 0)
19788 (match_operand:SWI 1 "memory_operand")]))
19789 (clobber (reg:CC FLAGS_REG))])]
19790 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19791 [(set (match_dup 2) (match_dup 1))
19792 (parallel [(set (match_dup 0)
19793 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19794 (clobber (reg:CC FLAGS_REG))])])
19795
19796 (define_peephole2
19797 [(match_scratch:SWI 2 "<r>")
19798 (parallel [(set (match_operand:SWI 0 "register_operand")
19799 (match_operator:SWI 3 "arith_or_logical_operator"
19800 [(match_operand:SWI 1 "memory_operand")
19801 (match_dup 0)]))
19802 (clobber (reg:CC FLAGS_REG))])]
19803 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19804 [(set (match_dup 2) (match_dup 1))
19805 (parallel [(set (match_dup 0)
19806 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19807 (clobber (reg:CC FLAGS_REG))])])
19808
19809 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
19810 ;; the memory address refers to the destination of the load!
19811
19812 (define_peephole2
19813 [(set (match_operand:SWI 0 "general_reg_operand")
19814 (match_operand:SWI 1 "general_reg_operand"))
19815 (parallel [(set (match_dup 0)
19816 (match_operator:SWI 3 "commutative_operator"
19817 [(match_dup 0)
19818 (match_operand:SWI 2 "memory_operand")]))
19819 (clobber (reg:CC FLAGS_REG))])]
19820 "REGNO (operands[0]) != REGNO (operands[1])
19821 && (<MODE>mode != QImode
19822 || any_QIreg_operand (operands[1], QImode))"
19823 [(set (match_dup 0) (match_dup 4))
19824 (parallel [(set (match_dup 0)
19825 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19826 (clobber (reg:CC FLAGS_REG))])]
19827 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
19828
19829 (define_peephole2
19830 [(set (match_operand 0 "mmx_reg_operand")
19831 (match_operand 1 "mmx_reg_operand"))
19832 (set (match_dup 0)
19833 (match_operator 3 "commutative_operator"
19834 [(match_dup 0)
19835 (match_operand 2 "memory_operand")]))]
19836 "REGNO (operands[0]) != REGNO (operands[1])"
19837 [(set (match_dup 0) (match_dup 2))
19838 (set (match_dup 0)
19839 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19840
19841 (define_peephole2
19842 [(set (match_operand 0 "sse_reg_operand")
19843 (match_operand 1 "sse_reg_operand"))
19844 (set (match_dup 0)
19845 (match_operator 3 "commutative_operator"
19846 [(match_dup 0)
19847 (match_operand 2 "memory_operand")]))]
19848 "REGNO (operands[0]) != REGNO (operands[1])"
19849 [(set (match_dup 0) (match_dup 2))
19850 (set (match_dup 0)
19851 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19852
19853 ; Don't do logical operations with memory outputs
19854 ;
19855 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19856 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19857 ; the same decoder scheduling characteristics as the original.
19858
19859 (define_peephole2
19860 [(match_scratch:SWI 2 "<r>")
19861 (parallel [(set (match_operand:SWI 0 "memory_operand")
19862 (match_operator:SWI 3 "arith_or_logical_operator"
19863 [(match_dup 0)
19864 (match_operand:SWI 1 "<nonmemory_operand>")]))
19865 (clobber (reg:CC FLAGS_REG))])]
19866 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19867 [(set (match_dup 2) (match_dup 0))
19868 (parallel [(set (match_dup 2)
19869 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19870 (clobber (reg:CC FLAGS_REG))])
19871 (set (match_dup 0) (match_dup 2))])
19872
19873 (define_peephole2
19874 [(match_scratch:SWI 2 "<r>")
19875 (parallel [(set (match_operand:SWI 0 "memory_operand")
19876 (match_operator:SWI 3 "arith_or_logical_operator"
19877 [(match_operand:SWI 1 "<nonmemory_operand>")
19878 (match_dup 0)]))
19879 (clobber (reg:CC FLAGS_REG))])]
19880 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19881 [(set (match_dup 2) (match_dup 0))
19882 (parallel [(set (match_dup 2)
19883 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19884 (clobber (reg:CC FLAGS_REG))])
19885 (set (match_dup 0) (match_dup 2))])
19886
19887 ;; Attempt to use arith or logical operations with memory outputs with
19888 ;; setting of flags.
19889 (define_peephole2
19890 [(set (match_operand:SWI 0 "register_operand")
19891 (match_operand:SWI 1 "memory_operand"))
19892 (parallel [(set (match_dup 0)
19893 (match_operator:SWI 3 "plusminuslogic_operator"
19894 [(match_dup 0)
19895 (match_operand:SWI 2 "<nonmemory_operand>")]))
19896 (clobber (reg:CC FLAGS_REG))])
19897 (set (match_dup 1) (match_dup 0))
19898 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19899 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19900 && peep2_reg_dead_p (4, operands[0])
19901 && !reg_overlap_mentioned_p (operands[0], operands[1])
19902 && !reg_overlap_mentioned_p (operands[0], operands[2])
19903 && (<MODE>mode != QImode
19904 || immediate_operand (operands[2], QImode)
19905 || any_QIreg_operand (operands[2], QImode))
19906 && ix86_match_ccmode (peep2_next_insn (3),
19907 (GET_CODE (operands[3]) == PLUS
19908 || GET_CODE (operands[3]) == MINUS)
19909 ? CCGOCmode : CCNOmode)"
19910 [(parallel [(set (match_dup 4) (match_dup 6))
19911 (set (match_dup 1) (match_dup 5))])]
19912 {
19913 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19914 operands[5]
19915 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19916 copy_rtx (operands[1]),
19917 operands[2]);
19918 operands[6]
19919 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19920 copy_rtx (operands[5]),
19921 const0_rtx);
19922 })
19923
19924 ;; Likewise for cmpelim optimized pattern.
19925 (define_peephole2
19926 [(set (match_operand:SWI 0 "register_operand")
19927 (match_operand:SWI 1 "memory_operand"))
19928 (parallel [(set (reg FLAGS_REG)
19929 (compare (match_operator:SWI 3 "plusminuslogic_operator"
19930 [(match_dup 0)
19931 (match_operand:SWI 2 "<nonmemory_operand>")])
19932 (const_int 0)))
19933 (set (match_dup 0) (match_dup 3))])
19934 (set (match_dup 1) (match_dup 0))]
19935 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19936 && peep2_reg_dead_p (3, operands[0])
19937 && !reg_overlap_mentioned_p (operands[0], operands[1])
19938 && !reg_overlap_mentioned_p (operands[0], operands[2])
19939 && ix86_match_ccmode (peep2_next_insn (1),
19940 (GET_CODE (operands[3]) == PLUS
19941 || GET_CODE (operands[3]) == MINUS)
19942 ? CCGOCmode : CCNOmode)"
19943 [(parallel [(set (match_dup 4) (match_dup 6))
19944 (set (match_dup 1) (match_dup 5))])]
19945 {
19946 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19947 operands[5]
19948 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19949 copy_rtx (operands[1]), operands[2]);
19950 operands[6]
19951 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
19952 const0_rtx);
19953 })
19954
19955 ;; Likewise for instances where we have a lea pattern.
19956 (define_peephole2
19957 [(set (match_operand:SWI 0 "register_operand")
19958 (match_operand:SWI 1 "memory_operand"))
19959 (set (match_operand:<LEAMODE> 3 "register_operand")
19960 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
19961 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
19962 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
19963 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
19964 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19965 && REGNO (operands[4]) == REGNO (operands[0])
19966 && REGNO (operands[5]) == REGNO (operands[3])
19967 && peep2_reg_dead_p (4, operands[3])
19968 && ((REGNO (operands[0]) == REGNO (operands[3]))
19969 || peep2_reg_dead_p (2, operands[0]))
19970 && !reg_overlap_mentioned_p (operands[0], operands[1])
19971 && !reg_overlap_mentioned_p (operands[3], operands[1])
19972 && !reg_overlap_mentioned_p (operands[0], operands[2])
19973 && (<MODE>mode != QImode
19974 || immediate_operand (operands[2], QImode)
19975 || any_QIreg_operand (operands[2], QImode))
19976 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19977 [(parallel [(set (match_dup 6) (match_dup 8))
19978 (set (match_dup 1) (match_dup 7))])]
19979 {
19980 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
19981 operands[7]
19982 = gen_rtx_PLUS (<MODE>mode,
19983 copy_rtx (operands[1]),
19984 gen_lowpart (<MODE>mode, operands[2]));
19985 operands[8]
19986 = gen_rtx_COMPARE (GET_MODE (operands[6]),
19987 copy_rtx (operands[7]),
19988 const0_rtx);
19989 })
19990
19991 (define_peephole2
19992 [(parallel [(set (match_operand:SWI 0 "register_operand")
19993 (match_operator:SWI 2 "plusminuslogic_operator"
19994 [(match_dup 0)
19995 (match_operand:SWI 1 "memory_operand")]))
19996 (clobber (reg:CC FLAGS_REG))])
19997 (set (match_dup 1) (match_dup 0))
19998 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19999 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20000 && COMMUTATIVE_ARITH_P (operands[2])
20001 && peep2_reg_dead_p (3, operands[0])
20002 && !reg_overlap_mentioned_p (operands[0], operands[1])
20003 && ix86_match_ccmode (peep2_next_insn (2),
20004 GET_CODE (operands[2]) == PLUS
20005 ? CCGOCmode : CCNOmode)"
20006 [(parallel [(set (match_dup 3) (match_dup 5))
20007 (set (match_dup 1) (match_dup 4))])]
20008 {
20009 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
20010 operands[4]
20011 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20012 copy_rtx (operands[1]),
20013 operands[0]);
20014 operands[5]
20015 = gen_rtx_COMPARE (GET_MODE (operands[3]),
20016 copy_rtx (operands[4]),
20017 const0_rtx);
20018 })
20019
20020 ;; Likewise for cmpelim optimized pattern.
20021 (define_peephole2
20022 [(parallel [(set (reg FLAGS_REG)
20023 (compare (match_operator:SWI 2 "plusminuslogic_operator"
20024 [(match_operand:SWI 0 "register_operand")
20025 (match_operand:SWI 1 "memory_operand")])
20026 (const_int 0)))
20027 (set (match_dup 0) (match_dup 2))])
20028 (set (match_dup 1) (match_dup 0))]
20029 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20030 && COMMUTATIVE_ARITH_P (operands[2])
20031 && peep2_reg_dead_p (2, operands[0])
20032 && !reg_overlap_mentioned_p (operands[0], operands[1])
20033 && ix86_match_ccmode (peep2_next_insn (0),
20034 GET_CODE (operands[2]) == PLUS
20035 ? CCGOCmode : CCNOmode)"
20036 [(parallel [(set (match_dup 3) (match_dup 5))
20037 (set (match_dup 1) (match_dup 4))])]
20038 {
20039 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
20040 operands[4]
20041 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20042 copy_rtx (operands[1]), operands[0]);
20043 operands[5]
20044 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
20045 const0_rtx);
20046 })
20047
20048 (define_peephole2
20049 [(set (match_operand:SWI12 0 "register_operand")
20050 (match_operand:SWI12 1 "memory_operand"))
20051 (parallel [(set (match_operand:SI 4 "register_operand")
20052 (match_operator:SI 3 "plusminuslogic_operator"
20053 [(match_dup 4)
20054 (match_operand:SI 2 "nonmemory_operand")]))
20055 (clobber (reg:CC FLAGS_REG))])
20056 (set (match_dup 1) (match_dup 0))
20057 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
20058 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20059 && REGNO (operands[0]) == REGNO (operands[4])
20060 && peep2_reg_dead_p (4, operands[0])
20061 && (<MODE>mode != QImode
20062 || immediate_operand (operands[2], SImode)
20063 || any_QIreg_operand (operands[2], SImode))
20064 && !reg_overlap_mentioned_p (operands[0], operands[1])
20065 && !reg_overlap_mentioned_p (operands[0], operands[2])
20066 && ix86_match_ccmode (peep2_next_insn (3),
20067 (GET_CODE (operands[3]) == PLUS
20068 || GET_CODE (operands[3]) == MINUS)
20069 ? CCGOCmode : CCNOmode)"
20070 [(parallel [(set (match_dup 5) (match_dup 7))
20071 (set (match_dup 1) (match_dup 6))])]
20072 {
20073 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
20074 operands[6]
20075 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
20076 copy_rtx (operands[1]),
20077 gen_lowpart (<MODE>mode, operands[2]));
20078 operands[7]
20079 = gen_rtx_COMPARE (GET_MODE (operands[5]),
20080 copy_rtx (operands[6]),
20081 const0_rtx);
20082 })
20083
20084 ;; peephole2 comes before regcprop, so deal also with a case that
20085 ;; would be cleaned up by regcprop.
20086 (define_peephole2
20087 [(set (match_operand:SWI 0 "register_operand")
20088 (match_operand:SWI 1 "memory_operand"))
20089 (parallel [(set (match_dup 0)
20090 (match_operator:SWI 3 "plusminuslogic_operator"
20091 [(match_dup 0)
20092 (match_operand:SWI 2 "<nonmemory_operand>")]))
20093 (clobber (reg:CC FLAGS_REG))])
20094 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
20095 (set (match_dup 1) (match_dup 4))
20096 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
20097 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20098 && peep2_reg_dead_p (3, operands[0])
20099 && peep2_reg_dead_p (5, operands[4])
20100 && !reg_overlap_mentioned_p (operands[0], operands[1])
20101 && !reg_overlap_mentioned_p (operands[0], operands[2])
20102 && !reg_overlap_mentioned_p (operands[4], operands[1])
20103 && (<MODE>mode != QImode
20104 || immediate_operand (operands[2], QImode)
20105 || any_QIreg_operand (operands[2], QImode))
20106 && ix86_match_ccmode (peep2_next_insn (4),
20107 (GET_CODE (operands[3]) == PLUS
20108 || GET_CODE (operands[3]) == MINUS)
20109 ? CCGOCmode : CCNOmode)"
20110 [(parallel [(set (match_dup 5) (match_dup 7))
20111 (set (match_dup 1) (match_dup 6))])]
20112 {
20113 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
20114 operands[6]
20115 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
20116 copy_rtx (operands[1]),
20117 operands[2]);
20118 operands[7]
20119 = gen_rtx_COMPARE (GET_MODE (operands[5]),
20120 copy_rtx (operands[6]),
20121 const0_rtx);
20122 })
20123
20124 (define_peephole2
20125 [(set (match_operand:SWI12 0 "register_operand")
20126 (match_operand:SWI12 1 "memory_operand"))
20127 (parallel [(set (match_operand:SI 4 "register_operand")
20128 (match_operator:SI 3 "plusminuslogic_operator"
20129 [(match_dup 4)
20130 (match_operand:SI 2 "nonmemory_operand")]))
20131 (clobber (reg:CC FLAGS_REG))])
20132 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
20133 (set (match_dup 1) (match_dup 5))
20134 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
20135 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20136 && REGNO (operands[0]) == REGNO (operands[4])
20137 && peep2_reg_dead_p (3, operands[0])
20138 && peep2_reg_dead_p (5, operands[5])
20139 && (<MODE>mode != QImode
20140 || immediate_operand (operands[2], SImode)
20141 || any_QIreg_operand (operands[2], SImode))
20142 && !reg_overlap_mentioned_p (operands[0], operands[1])
20143 && !reg_overlap_mentioned_p (operands[0], operands[2])
20144 && !reg_overlap_mentioned_p (operands[5], operands[1])
20145 && ix86_match_ccmode (peep2_next_insn (4),
20146 (GET_CODE (operands[3]) == PLUS
20147 || GET_CODE (operands[3]) == MINUS)
20148 ? CCGOCmode : CCNOmode)"
20149 [(parallel [(set (match_dup 6) (match_dup 8))
20150 (set (match_dup 1) (match_dup 7))])]
20151 {
20152 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
20153 operands[7]
20154 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
20155 copy_rtx (operands[1]),
20156 gen_lowpart (<MODE>mode, operands[2]));
20157 operands[8]
20158 = gen_rtx_COMPARE (GET_MODE (operands[6]),
20159 copy_rtx (operands[7]),
20160 const0_rtx);
20161 })
20162
20163 ;; Likewise for cmpelim optimized pattern.
20164 (define_peephole2
20165 [(set (match_operand:SWI 0 "register_operand")
20166 (match_operand:SWI 1 "memory_operand"))
20167 (parallel [(set (reg FLAGS_REG)
20168 (compare (match_operator:SWI 3 "plusminuslogic_operator"
20169 [(match_dup 0)
20170 (match_operand:SWI 2 "<nonmemory_operand>")])
20171 (const_int 0)))
20172 (set (match_dup 0) (match_dup 3))])
20173 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
20174 (set (match_dup 1) (match_dup 4))]
20175 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20176 && peep2_reg_dead_p (3, operands[0])
20177 && peep2_reg_dead_p (4, operands[4])
20178 && !reg_overlap_mentioned_p (operands[0], operands[1])
20179 && !reg_overlap_mentioned_p (operands[0], operands[2])
20180 && !reg_overlap_mentioned_p (operands[4], operands[1])
20181 && ix86_match_ccmode (peep2_next_insn (1),
20182 (GET_CODE (operands[3]) == PLUS
20183 || GET_CODE (operands[3]) == MINUS)
20184 ? CCGOCmode : CCNOmode)"
20185 [(parallel [(set (match_dup 5) (match_dup 7))
20186 (set (match_dup 1) (match_dup 6))])]
20187 {
20188 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
20189 operands[6]
20190 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
20191 copy_rtx (operands[1]), operands[2]);
20192 operands[7]
20193 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
20194 const0_rtx);
20195 })
20196
20197 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
20198 ;; into x = z; x ^= y; x != z
20199 (define_peephole2
20200 [(set (match_operand:SWI 0 "register_operand")
20201 (match_operand:SWI 1 "memory_operand"))
20202 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
20203 (parallel [(set (match_operand:SWI 4 "register_operand")
20204 (xor:SWI (match_dup 4)
20205 (match_operand:SWI 2 "<nonmemory_operand>")))
20206 (clobber (reg:CC FLAGS_REG))])
20207 (set (match_dup 1) (match_dup 4))
20208 (set (reg:CCZ FLAGS_REG)
20209 (compare:CCZ (match_operand:SWI 5 "register_operand")
20210 (match_operand:SWI 6 "<nonmemory_operand>")))]
20211 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20212 && (REGNO (operands[4]) == REGNO (operands[0])
20213 || REGNO (operands[4]) == REGNO (operands[3]))
20214 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
20215 ? 3 : 0], operands[5])
20216 ? rtx_equal_p (operands[2], operands[6])
20217 : rtx_equal_p (operands[2], operands[5])
20218 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
20219 ? 3 : 0], operands[6]))
20220 && peep2_reg_dead_p (4, operands[4])
20221 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
20222 ? 3 : 0])
20223 && !reg_overlap_mentioned_p (operands[0], operands[1])
20224 && !reg_overlap_mentioned_p (operands[0], operands[2])
20225 && !reg_overlap_mentioned_p (operands[3], operands[0])
20226 && !reg_overlap_mentioned_p (operands[3], operands[1])
20227 && !reg_overlap_mentioned_p (operands[3], operands[2])
20228 && (<MODE>mode != QImode
20229 || immediate_operand (operands[2], QImode)
20230 || any_QIreg_operand (operands[2], QImode))"
20231 [(parallel [(set (match_dup 7) (match_dup 9))
20232 (set (match_dup 1) (match_dup 8))])]
20233 {
20234 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
20235 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
20236 operands[2]);
20237 operands[9]
20238 = gen_rtx_COMPARE (GET_MODE (operands[7]),
20239 copy_rtx (operands[8]),
20240 const0_rtx);
20241 })
20242
20243 (define_peephole2
20244 [(set (match_operand:SWI12 0 "register_operand")
20245 (match_operand:SWI12 1 "memory_operand"))
20246 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
20247 (parallel [(set (match_operand:SI 4 "register_operand")
20248 (xor:SI (match_dup 4)
20249 (match_operand:SI 2 "<nonmemory_operand>")))
20250 (clobber (reg:CC FLAGS_REG))])
20251 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
20252 (set (reg:CCZ FLAGS_REG)
20253 (compare:CCZ (match_operand:SWI12 6 "register_operand")
20254 (match_operand:SWI12 7 "<nonmemory_operand>")))]
20255 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20256 && (REGNO (operands[5]) == REGNO (operands[0])
20257 || REGNO (operands[5]) == REGNO (operands[3]))
20258 && REGNO (operands[5]) == REGNO (operands[4])
20259 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
20260 ? 3 : 0], operands[6])
20261 ? (REG_P (operands[2])
20262 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
20263 : rtx_equal_p (operands[2], operands[7]))
20264 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
20265 ? 3 : 0], operands[7])
20266 && REG_P (operands[2])
20267 && REGNO (operands[2]) == REGNO (operands[6])))
20268 && peep2_reg_dead_p (4, operands[5])
20269 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
20270 ? 3 : 0])
20271 && !reg_overlap_mentioned_p (operands[0], operands[1])
20272 && !reg_overlap_mentioned_p (operands[0], operands[2])
20273 && !reg_overlap_mentioned_p (operands[3], operands[0])
20274 && !reg_overlap_mentioned_p (operands[3], operands[1])
20275 && !reg_overlap_mentioned_p (operands[3], operands[2])
20276 && (<MODE>mode != QImode
20277 || immediate_operand (operands[2], SImode)
20278 || any_QIreg_operand (operands[2], SImode))"
20279 [(parallel [(set (match_dup 8) (match_dup 10))
20280 (set (match_dup 1) (match_dup 9))])]
20281 {
20282 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
20283 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
20284 gen_lowpart (<MODE>mode, operands[2]));
20285 operands[10]
20286 = gen_rtx_COMPARE (GET_MODE (operands[8]),
20287 copy_rtx (operands[9]),
20288 const0_rtx);
20289 })
20290
20291 ;; Attempt to optimize away memory stores of values the memory already
20292 ;; has. See PR79593.
20293 (define_peephole2
20294 [(set (match_operand 0 "register_operand")
20295 (match_operand 1 "memory_operand"))
20296 (set (match_operand 2 "memory_operand") (match_dup 0))]
20297 "!MEM_VOLATILE_P (operands[1])
20298 && !MEM_VOLATILE_P (operands[2])
20299 && rtx_equal_p (operands[1], operands[2])
20300 && !reg_overlap_mentioned_p (operands[0], operands[2])"
20301 [(set (match_dup 0) (match_dup 1))])
20302
20303 ;; Attempt to always use XOR for zeroing registers (including FP modes).
20304 (define_peephole2
20305 [(set (match_operand 0 "general_reg_operand")
20306 (match_operand 1 "const0_operand"))]
20307 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20308 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20309 && peep2_regno_dead_p (0, FLAGS_REG)"
20310 [(parallel [(set (match_dup 0) (const_int 0))
20311 (clobber (reg:CC FLAGS_REG))])]
20312 "operands[0] = gen_lowpart (word_mode, operands[0]);")
20313
20314 (define_peephole2
20315 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
20316 (const_int 0))]
20317 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20318 && peep2_regno_dead_p (0, FLAGS_REG)"
20319 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20320 (clobber (reg:CC FLAGS_REG))])])
20321
20322 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
20323 (define_peephole2
20324 [(set (match_operand:SWI248 0 "general_reg_operand")
20325 (const_int -1))]
20326 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
20327 && peep2_regno_dead_p (0, FLAGS_REG)"
20328 [(parallel [(set (match_dup 0) (const_int -1))
20329 (clobber (reg:CC FLAGS_REG))])]
20330 {
20331 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
20332 operands[0] = gen_lowpart (SImode, operands[0]);
20333 })
20334
20335 ;; Attempt to convert simple lea to add/shift.
20336 ;; These can be created by move expanders.
20337 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
20338 ;; relevant lea instructions were already split.
20339
20340 (define_peephole2
20341 [(set (match_operand:SWI48 0 "register_operand")
20342 (plus:SWI48 (match_dup 0)
20343 (match_operand:SWI48 1 "<nonmemory_operand>")))]
20344 "!TARGET_OPT_AGU
20345 && peep2_regno_dead_p (0, FLAGS_REG)"
20346 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
20347 (clobber (reg:CC FLAGS_REG))])])
20348
20349 (define_peephole2
20350 [(set (match_operand:SWI48 0 "register_operand")
20351 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
20352 (match_dup 0)))]
20353 "!TARGET_OPT_AGU
20354 && peep2_regno_dead_p (0, FLAGS_REG)"
20355 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
20356 (clobber (reg:CC FLAGS_REG))])])
20357
20358 (define_peephole2
20359 [(set (match_operand:DI 0 "register_operand")
20360 (zero_extend:DI
20361 (plus:SI (match_operand:SI 1 "register_operand")
20362 (match_operand:SI 2 "nonmemory_operand"))))]
20363 "TARGET_64BIT && !TARGET_OPT_AGU
20364 && REGNO (operands[0]) == REGNO (operands[1])
20365 && peep2_regno_dead_p (0, FLAGS_REG)"
20366 [(parallel [(set (match_dup 0)
20367 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
20368 (clobber (reg:CC FLAGS_REG))])])
20369
20370 (define_peephole2
20371 [(set (match_operand:DI 0 "register_operand")
20372 (zero_extend:DI
20373 (plus:SI (match_operand:SI 1 "nonmemory_operand")
20374 (match_operand:SI 2 "register_operand"))))]
20375 "TARGET_64BIT && !TARGET_OPT_AGU
20376 && REGNO (operands[0]) == REGNO (operands[2])
20377 && peep2_regno_dead_p (0, FLAGS_REG)"
20378 [(parallel [(set (match_dup 0)
20379 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
20380 (clobber (reg:CC FLAGS_REG))])])
20381
20382 (define_peephole2
20383 [(set (match_operand:SWI48 0 "register_operand")
20384 (mult:SWI48 (match_dup 0)
20385 (match_operand:SWI48 1 "const_int_operand")))]
20386 "pow2p_hwi (INTVAL (operands[1]))
20387 && peep2_regno_dead_p (0, FLAGS_REG)"
20388 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
20389 (clobber (reg:CC FLAGS_REG))])]
20390 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20391
20392 (define_peephole2
20393 [(set (match_operand:DI 0 "register_operand")
20394 (zero_extend:DI
20395 (mult:SI (match_operand:SI 1 "register_operand")
20396 (match_operand:SI 2 "const_int_operand"))))]
20397 "TARGET_64BIT
20398 && pow2p_hwi (INTVAL (operands[2]))
20399 && REGNO (operands[0]) == REGNO (operands[1])
20400 && peep2_regno_dead_p (0, FLAGS_REG)"
20401 [(parallel [(set (match_dup 0)
20402 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
20403 (clobber (reg:CC FLAGS_REG))])]
20404 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20405
20406 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20407 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
20408 ;; On many CPUs it is also faster, since special hardware to avoid esp
20409 ;; dependencies is present.
20410
20411 ;; While some of these conversions may be done using splitters, we use
20412 ;; peepholes in order to allow combine_stack_adjustments pass to see
20413 ;; nonobfuscated RTL.
20414
20415 ;; Convert prologue esp subtractions to push.
20416 ;; We need register to push. In order to keep verify_flow_info happy we have
20417 ;; two choices
20418 ;; - use scratch and clobber it in order to avoid dependencies
20419 ;; - use already live register
20420 ;; We can't use the second way right now, since there is no reliable way how to
20421 ;; verify that given register is live. First choice will also most likely in
20422 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20423 ;; call clobbered registers are dead. We may want to use base pointer as an
20424 ;; alternative when no register is available later.
20425
20426 (define_peephole2
20427 [(match_scratch:W 1 "r")
20428 (parallel [(set (reg:P SP_REG)
20429 (plus:P (reg:P SP_REG)
20430 (match_operand:P 0 "const_int_operand")))
20431 (clobber (reg:CC FLAGS_REG))
20432 (clobber (mem:BLK (scratch)))])]
20433 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
20434 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
20435 && ix86_red_zone_size == 0"
20436 [(clobber (match_dup 1))
20437 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
20438 (clobber (mem:BLK (scratch)))])])
20439
20440 (define_peephole2
20441 [(match_scratch:W 1 "r")
20442 (parallel [(set (reg:P SP_REG)
20443 (plus:P (reg:P SP_REG)
20444 (match_operand:P 0 "const_int_operand")))
20445 (clobber (reg:CC FLAGS_REG))
20446 (clobber (mem:BLK (scratch)))])]
20447 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
20448 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
20449 && ix86_red_zone_size == 0"
20450 [(clobber (match_dup 1))
20451 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
20452 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
20453 (clobber (mem:BLK (scratch)))])])
20454
20455 ;; Convert esp subtractions to push.
20456 (define_peephole2
20457 [(match_scratch:W 1 "r")
20458 (parallel [(set (reg:P SP_REG)
20459 (plus:P (reg:P SP_REG)
20460 (match_operand:P 0 "const_int_operand")))
20461 (clobber (reg:CC FLAGS_REG))])]
20462 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
20463 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
20464 && ix86_red_zone_size == 0"
20465 [(clobber (match_dup 1))
20466 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
20467
20468 (define_peephole2
20469 [(match_scratch:W 1 "r")
20470 (parallel [(set (reg:P SP_REG)
20471 (plus:P (reg:P SP_REG)
20472 (match_operand:P 0 "const_int_operand")))
20473 (clobber (reg:CC FLAGS_REG))])]
20474 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
20475 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
20476 && ix86_red_zone_size == 0"
20477 [(clobber (match_dup 1))
20478 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
20479 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
20480
20481 ;; Convert epilogue deallocator to pop.
20482 (define_peephole2
20483 [(match_scratch:W 1 "r")
20484 (parallel [(set (reg:P SP_REG)
20485 (plus:P (reg:P SP_REG)
20486 (match_operand:P 0 "const_int_operand")))
20487 (clobber (reg:CC FLAGS_REG))
20488 (clobber (mem:BLK (scratch)))])]
20489 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
20490 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
20491 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20492 (clobber (mem:BLK (scratch)))])])
20493
20494 ;; Two pops case is tricky, since pop causes dependency
20495 ;; on destination register. We use two registers if available.
20496 (define_peephole2
20497 [(match_scratch:W 1 "r")
20498 (match_scratch:W 2 "r")
20499 (parallel [(set (reg:P SP_REG)
20500 (plus:P (reg:P SP_REG)
20501 (match_operand:P 0 "const_int_operand")))
20502 (clobber (reg:CC FLAGS_REG))
20503 (clobber (mem:BLK (scratch)))])]
20504 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
20505 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
20506 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20507 (clobber (mem:BLK (scratch)))])
20508 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
20509
20510 (define_peephole2
20511 [(match_scratch:W 1 "r")
20512 (parallel [(set (reg:P SP_REG)
20513 (plus:P (reg:P SP_REG)
20514 (match_operand:P 0 "const_int_operand")))
20515 (clobber (reg:CC FLAGS_REG))
20516 (clobber (mem:BLK (scratch)))])]
20517 "optimize_insn_for_size_p ()
20518 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
20519 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20520 (clobber (mem:BLK (scratch)))])
20521 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
20522
20523 ;; Convert esp additions to pop.
20524 (define_peephole2
20525 [(match_scratch:W 1 "r")
20526 (parallel [(set (reg:P SP_REG)
20527 (plus:P (reg:P SP_REG)
20528 (match_operand:P 0 "const_int_operand")))
20529 (clobber (reg:CC FLAGS_REG))])]
20530 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
20531 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
20532
20533 ;; Two pops case is tricky, since pop causes dependency
20534 ;; on destination register. We use two registers if available.
20535 (define_peephole2
20536 [(match_scratch:W 1 "r")
20537 (match_scratch:W 2 "r")
20538 (parallel [(set (reg:P SP_REG)
20539 (plus:P (reg:P SP_REG)
20540 (match_operand:P 0 "const_int_operand")))
20541 (clobber (reg:CC FLAGS_REG))])]
20542 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
20543 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20544 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
20545
20546 (define_peephole2
20547 [(match_scratch:W 1 "r")
20548 (parallel [(set (reg:P SP_REG)
20549 (plus:P (reg:P SP_REG)
20550 (match_operand:P 0 "const_int_operand")))
20551 (clobber (reg:CC FLAGS_REG))])]
20552 "optimize_insn_for_size_p ()
20553 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
20554 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20555 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
20556 \f
20557 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20558 ;; required and register dies. Similarly for 128 to -128.
20559 (define_peephole2
20560 [(set (match_operand 0 "flags_reg_operand")
20561 (match_operator 1 "compare_operator"
20562 [(match_operand 2 "register_operand")
20563 (match_operand 3 "const_int_operand")]))]
20564 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
20565 && incdec_operand (operands[3], GET_MODE (operands[3])))
20566 || (!TARGET_FUSE_CMP_AND_BRANCH
20567 && INTVAL (operands[3]) == 128))
20568 && ix86_match_ccmode (insn, CCGCmode)
20569 && peep2_reg_dead_p (1, operands[2])"
20570 [(parallel [(set (match_dup 0)
20571 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20572 (clobber (match_dup 2))])])
20573 \f
20574 ;; Convert imul by three, five and nine into lea
20575 (define_peephole2
20576 [(parallel
20577 [(set (match_operand:SWI48 0 "register_operand")
20578 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
20579 (match_operand:SWI48 2 "const359_operand")))
20580 (clobber (reg:CC FLAGS_REG))])]
20581 "!TARGET_PARTIAL_REG_STALL
20582 || <MODE>mode == SImode
20583 || optimize_function_for_size_p (cfun)"
20584 [(set (match_dup 0)
20585 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
20586 (match_dup 1)))]
20587 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
20588
20589 (define_peephole2
20590 [(parallel
20591 [(set (match_operand:SWI48 0 "register_operand")
20592 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
20593 (match_operand:SWI48 2 "const359_operand")))
20594 (clobber (reg:CC FLAGS_REG))])]
20595 "optimize_insn_for_speed_p ()
20596 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
20597 [(set (match_dup 0) (match_dup 1))
20598 (set (match_dup 0)
20599 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
20600 (match_dup 0)))]
20601 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
20602
20603 ;; imul $32bit_imm, mem, reg is vector decoded, while
20604 ;; imul $32bit_imm, reg, reg is direct decoded.
20605 (define_peephole2
20606 [(match_scratch:SWI48 3 "r")
20607 (parallel [(set (match_operand:SWI48 0 "register_operand")
20608 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
20609 (match_operand:SWI48 2 "immediate_operand")))
20610 (clobber (reg:CC FLAGS_REG))])]
20611 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20612 && !satisfies_constraint_K (operands[2])"
20613 [(set (match_dup 3) (match_dup 1))
20614 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
20615 (clobber (reg:CC FLAGS_REG))])])
20616
20617 (define_peephole2
20618 [(match_scratch:SI 3 "r")
20619 (parallel [(set (match_operand:DI 0 "register_operand")
20620 (zero_extend:DI
20621 (mult:SI (match_operand:SI 1 "memory_operand")
20622 (match_operand:SI 2 "immediate_operand"))))
20623 (clobber (reg:CC FLAGS_REG))])]
20624 "TARGET_64BIT
20625 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20626 && !satisfies_constraint_K (operands[2])"
20627 [(set (match_dup 3) (match_dup 1))
20628 (parallel [(set (match_dup 0)
20629 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20630 (clobber (reg:CC FLAGS_REG))])])
20631
20632 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20633 ;; Convert it into imul reg, reg
20634 ;; It would be better to force assembler to encode instruction using long
20635 ;; immediate, but there is apparently no way to do so.
20636 (define_peephole2
20637 [(parallel [(set (match_operand:SWI248 0 "register_operand")
20638 (mult:SWI248
20639 (match_operand:SWI248 1 "nonimmediate_operand")
20640 (match_operand:SWI248 2 "const_int_operand")))
20641 (clobber (reg:CC FLAGS_REG))])
20642 (match_scratch:SWI248 3 "r")]
20643 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20644 && satisfies_constraint_K (operands[2])"
20645 [(set (match_dup 3) (match_dup 2))
20646 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
20647 (clobber (reg:CC FLAGS_REG))])]
20648 {
20649 if (!rtx_equal_p (operands[0], operands[1]))
20650 emit_move_insn (operands[0], operands[1]);
20651 })
20652
20653 ;; After splitting up read-modify operations, array accesses with memory
20654 ;; operands might end up in form:
20655 ;; sall $2, %eax
20656 ;; movl 4(%esp), %edx
20657 ;; addl %edx, %eax
20658 ;; instead of pre-splitting:
20659 ;; sall $2, %eax
20660 ;; addl 4(%esp), %eax
20661 ;; Turn it into:
20662 ;; movl 4(%esp), %edx
20663 ;; leal (%edx,%eax,4), %eax
20664
20665 (define_peephole2
20666 [(match_scratch:W 5 "r")
20667 (parallel [(set (match_operand 0 "register_operand")
20668 (ashift (match_operand 1 "register_operand")
20669 (match_operand 2 "const_int_operand")))
20670 (clobber (reg:CC FLAGS_REG))])
20671 (parallel [(set (match_operand 3 "register_operand")
20672 (plus (match_dup 0)
20673 (match_operand 4 "x86_64_general_operand")))
20674 (clobber (reg:CC FLAGS_REG))])]
20675 "IN_RANGE (INTVAL (operands[2]), 1, 3)
20676 /* Validate MODE for lea. */
20677 && ((!TARGET_PARTIAL_REG_STALL
20678 && (GET_MODE (operands[0]) == QImode
20679 || GET_MODE (operands[0]) == HImode))
20680 || GET_MODE (operands[0]) == SImode
20681 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20682 && (rtx_equal_p (operands[0], operands[3])
20683 || peep2_reg_dead_p (2, operands[0]))
20684 /* We reorder load and the shift. */
20685 && !reg_overlap_mentioned_p (operands[0], operands[4])"
20686 [(set (match_dup 5) (match_dup 4))
20687 (set (match_dup 0) (match_dup 1))]
20688 {
20689 machine_mode op1mode = GET_MODE (operands[1]);
20690 machine_mode mode = op1mode == DImode ? DImode : SImode;
20691 int scale = 1 << INTVAL (operands[2]);
20692 rtx index = gen_lowpart (word_mode, operands[1]);
20693 rtx base = gen_lowpart (word_mode, operands[5]);
20694 rtx dest = gen_lowpart (mode, operands[3]);
20695
20696 operands[1] = gen_rtx_PLUS (word_mode, base,
20697 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
20698 if (mode != word_mode)
20699 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20700
20701 operands[5] = base;
20702 if (op1mode != word_mode)
20703 operands[5] = gen_lowpart (op1mode, operands[5]);
20704
20705 operands[0] = dest;
20706 })
20707 \f
20708 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20709 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20710 ;; caught for use by garbage collectors and the like. Using an insn that
20711 ;; maps to SIGILL makes it more likely the program will rightfully die.
20712 ;; Keeping with tradition, "6" is in honor of #UD.
20713 (define_insn "trap"
20714 [(trap_if (const_int 1) (const_int 6))]
20715 ""
20716 {
20717 #ifdef HAVE_AS_IX86_UD2
20718 return "ud2";
20719 #else
20720 return ASM_SHORT "0x0b0f";
20721 #endif
20722 }
20723 [(set_attr "length" "2")])
20724
20725 (define_insn "ud2"
20726 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
20727 ""
20728 {
20729 #ifdef HAVE_AS_IX86_UD2
20730 return "ud2";
20731 #else
20732 return ASM_SHORT "0x0b0f";
20733 #endif
20734 }
20735 [(set_attr "length" "2")])
20736
20737 (define_expand "prefetch"
20738 [(prefetch (match_operand 0 "address_operand")
20739 (match_operand:SI 1 "const_int_operand")
20740 (match_operand:SI 2 "const_int_operand"))]
20741 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
20742 {
20743 bool write = operands[1] != const0_rtx;
20744 int locality = INTVAL (operands[2]);
20745
20746 gcc_assert (IN_RANGE (locality, 0, 3));
20747
20748 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20749 supported by SSE counterpart (non-SSE2 athlon machines) or the
20750 SSE prefetch is not available (K6 machines). Otherwise use SSE
20751 prefetch as it allows specifying of locality. */
20752
20753 if (write)
20754 {
20755 if (TARGET_PREFETCHWT1)
20756 operands[2] = GEN_INT (MAX (locality, 2));
20757 else if (TARGET_PRFCHW)
20758 operands[2] = GEN_INT (3);
20759 else if (TARGET_3DNOW && !TARGET_SSE2)
20760 operands[2] = GEN_INT (3);
20761 else if (TARGET_PREFETCH_SSE)
20762 operands[1] = const0_rtx;
20763 else
20764 {
20765 gcc_assert (TARGET_3DNOW);
20766 operands[2] = GEN_INT (3);
20767 }
20768 }
20769 else
20770 {
20771 if (TARGET_PREFETCH_SSE)
20772 ;
20773 else
20774 {
20775 gcc_assert (TARGET_3DNOW);
20776 operands[2] = GEN_INT (3);
20777 }
20778 }
20779 })
20780
20781 (define_insn "*prefetch_sse"
20782 [(prefetch (match_operand 0 "address_operand" "p")
20783 (const_int 0)
20784 (match_operand:SI 1 "const_int_operand"))]
20785 "TARGET_PREFETCH_SSE"
20786 {
20787 static const char * const patterns[4] = {
20788 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20789 };
20790
20791 int locality = INTVAL (operands[1]);
20792 gcc_assert (IN_RANGE (locality, 0, 3));
20793
20794 return patterns[locality];
20795 }
20796 [(set_attr "type" "sse")
20797 (set_attr "atom_sse_attr" "prefetch")
20798 (set (attr "length_address")
20799 (symbol_ref "memory_address_length (operands[0], false)"))
20800 (set_attr "memory" "none")])
20801
20802 (define_insn "*prefetch_3dnow"
20803 [(prefetch (match_operand 0 "address_operand" "p")
20804 (match_operand:SI 1 "const_int_operand" "n")
20805 (const_int 3))]
20806 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
20807 {
20808 if (operands[1] == const0_rtx)
20809 return "prefetch\t%a0";
20810 else
20811 return "prefetchw\t%a0";
20812 }
20813 [(set_attr "type" "mmx")
20814 (set (attr "length_address")
20815 (symbol_ref "memory_address_length (operands[0], false)"))
20816 (set_attr "memory" "none")])
20817
20818 (define_insn "*prefetch_prefetchwt1"
20819 [(prefetch (match_operand 0 "address_operand" "p")
20820 (const_int 1)
20821 (const_int 2))]
20822 "TARGET_PREFETCHWT1"
20823 "prefetchwt1\t%a0";
20824 [(set_attr "type" "sse")
20825 (set (attr "length_address")
20826 (symbol_ref "memory_address_length (operands[0], false)"))
20827 (set_attr "memory" "none")])
20828
20829 (define_expand "stack_protect_set"
20830 [(match_operand 0 "memory_operand")
20831 (match_operand 1 "memory_operand")]
20832 ""
20833 {
20834 emit_insn (gen_stack_protect_set_1
20835 (ptr_mode, operands[0], operands[1]));
20836 DONE;
20837 })
20838
20839 (define_insn "@stack_protect_set_1_<mode>"
20840 [(set (match_operand:PTR 0 "memory_operand" "=m")
20841 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
20842 UNSPEC_SP_SET))
20843 (set (match_scratch:PTR 2 "=&r") (const_int 0))
20844 (clobber (reg:CC FLAGS_REG))]
20845 ""
20846 {
20847 output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
20848 output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
20849 return "xor{l}\t%k2, %k2";
20850 }
20851 [(set_attr "type" "multi")])
20852
20853 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
20854 ;; immediately followed by *mov{s,d}i_internal to the same register,
20855 ;; where we can avoid the xor{l} above. We don't split this, so that
20856 ;; scheduling or anything else doesn't separate the *stack_protect_set*
20857 ;; pattern from the set of the register that overwrites the register
20858 ;; with a new value.
20859 (define_insn "*stack_protect_set_2_<mode>"
20860 [(set (match_operand:PTR 0 "memory_operand" "=m")
20861 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
20862 UNSPEC_SP_SET))
20863 (set (match_operand:SI 1 "register_operand" "=&r")
20864 (match_operand:SI 2 "general_operand" "g"))
20865 (clobber (reg:CC FLAGS_REG))]
20866 "reload_completed
20867 && !reg_overlap_mentioned_p (operands[1], operands[2])"
20868 {
20869 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
20870 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
20871 if (pic_32bit_operand (operands[2], SImode)
20872 || ix86_use_lea_for_mov (insn, operands + 1))
20873 return "lea{l}\t{%E2, %1|%1, %E2}";
20874 else
20875 return "mov{l}\t{%2, %1|%1, %2}";
20876 }
20877 [(set_attr "type" "multi")
20878 (set_attr "length" "24")])
20879
20880 (define_peephole2
20881 [(parallel [(set (match_operand:PTR 0 "memory_operand")
20882 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
20883 UNSPEC_SP_SET))
20884 (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
20885 (clobber (reg:CC FLAGS_REG))])
20886 (set (match_operand:SI 3 "general_reg_operand")
20887 (match_operand:SI 4))]
20888 "REGNO (operands[2]) == REGNO (operands[3])
20889 && general_operand (operands[4], SImode)
20890 && (general_reg_operand (operands[4], SImode)
20891 || memory_operand (operands[4], SImode)
20892 || immediate_operand (operands[4], SImode))
20893 && !reg_overlap_mentioned_p (operands[3], operands[4])"
20894 [(parallel [(set (match_dup 0)
20895 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
20896 (set (match_dup 3) (match_dup 4))
20897 (clobber (reg:CC FLAGS_REG))])])
20898
20899 (define_insn "*stack_protect_set_3"
20900 [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
20901 (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
20902 UNSPEC_SP_SET))
20903 (set (match_operand:DI 1 "register_operand" "=&r,r,r")
20904 (match_operand:DI 2 "general_operand" "Z,rem,i"))
20905 (clobber (reg:CC FLAGS_REG))]
20906 "TARGET_64BIT
20907 && reload_completed
20908 && !reg_overlap_mentioned_p (operands[1], operands[2])"
20909 {
20910 output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
20911 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
20912 if (pic_32bit_operand (operands[2], DImode))
20913 return "lea{q}\t{%E2, %1|%1, %E2}";
20914 else if (which_alternative == 0)
20915 return "mov{l}\t{%k2, %k1|%k1, %k2}";
20916 else if (which_alternative == 2)
20917 return "movabs{q}\t{%2, %1|%1, %2}";
20918 else if (ix86_use_lea_for_mov (insn, operands + 1))
20919 return "lea{q}\t{%E2, %1|%1, %E2}";
20920 else
20921 return "mov{q}\t{%2, %1|%1, %2}";
20922 }
20923 [(set_attr "type" "multi")
20924 (set_attr "length" "24")])
20925
20926 (define_peephole2
20927 [(parallel [(set (match_operand:DI 0 "memory_operand")
20928 (unspec:DI [(match_operand:DI 1 "memory_operand")]
20929 UNSPEC_SP_SET))
20930 (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
20931 (clobber (reg:CC FLAGS_REG))])
20932 (set (match_dup 2) (match_operand:DI 3))]
20933 "TARGET_64BIT
20934 && general_operand (operands[3], DImode)
20935 && (general_reg_operand (operands[3], DImode)
20936 || memory_operand (operands[3], DImode)
20937 || x86_64_zext_immediate_operand (operands[3], DImode)
20938 || x86_64_immediate_operand (operands[3], DImode)
20939 || (CONSTANT_P (operands[3])
20940 && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
20941 && !reg_overlap_mentioned_p (operands[2], operands[3])"
20942 [(parallel [(set (match_dup 0)
20943 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
20944 (set (match_dup 2) (match_dup 3))
20945 (clobber (reg:CC FLAGS_REG))])])
20946
20947 (define_expand "stack_protect_test"
20948 [(match_operand 0 "memory_operand")
20949 (match_operand 1 "memory_operand")
20950 (match_operand 2)]
20951 ""
20952 {
20953 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20954
20955 emit_insn (gen_stack_protect_test_1
20956 (ptr_mode, flags, operands[0], operands[1]));
20957
20958 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20959 flags, const0_rtx, operands[2]));
20960 DONE;
20961 })
20962
20963 (define_insn "@stack_protect_test_1_<mode>"
20964 [(set (match_operand:CCZ 0 "flags_reg_operand")
20965 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
20966 (match_operand:PTR 2 "memory_operand" "m")]
20967 UNSPEC_SP_TEST))
20968 (clobber (match_scratch:PTR 3 "=&r"))]
20969 ""
20970 {
20971 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
20972 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
20973 }
20974 [(set_attr "type" "multi")])
20975
20976 (define_insn "sse4_2_crc32<mode>"
20977 [(set (match_operand:SI 0 "register_operand" "=r")
20978 (unspec:SI
20979 [(match_operand:SI 1 "register_operand" "0")
20980 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20981 UNSPEC_CRC32))]
20982 "TARGET_SSE4_2 || TARGET_CRC32"
20983 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20984 [(set_attr "type" "sselog1")
20985 (set_attr "prefix_rep" "1")
20986 (set_attr "prefix_extra" "1")
20987 (set (attr "prefix_data16")
20988 (if_then_else (match_operand:HI 2)
20989 (const_string "1")
20990 (const_string "*")))
20991 (set (attr "prefix_rex")
20992 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
20993 (const_string "1")
20994 (const_string "*")))
20995 (set_attr "mode" "SI")])
20996
20997 (define_insn "sse4_2_crc32di"
20998 [(set (match_operand:DI 0 "register_operand" "=r")
20999 (unspec:DI
21000 [(match_operand:DI 1 "register_operand" "0")
21001 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21002 UNSPEC_CRC32))]
21003 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
21004 "crc32{q}\t{%2, %0|%0, %2}"
21005 [(set_attr "type" "sselog1")
21006 (set_attr "prefix_rep" "1")
21007 (set_attr "prefix_extra" "1")
21008 (set_attr "mode" "DI")])
21009
21010 (define_insn "rdpmc"
21011 [(set (match_operand:DI 0 "register_operand" "=A")
21012 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21013 UNSPECV_RDPMC))]
21014 "!TARGET_64BIT"
21015 "rdpmc"
21016 [(set_attr "type" "other")
21017 (set_attr "length" "2")])
21018
21019 (define_insn "rdpmc_rex64"
21020 [(set (match_operand:DI 0 "register_operand" "=a")
21021 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21022 UNSPECV_RDPMC))
21023 (set (match_operand:DI 1 "register_operand" "=d")
21024 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
21025 "TARGET_64BIT"
21026 "rdpmc"
21027 [(set_attr "type" "other")
21028 (set_attr "length" "2")])
21029
21030 (define_insn "rdtsc"
21031 [(set (match_operand:DI 0 "register_operand" "=A")
21032 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21033 "!TARGET_64BIT"
21034 "rdtsc"
21035 [(set_attr "type" "other")
21036 (set_attr "length" "2")])
21037
21038 (define_insn "rdtsc_rex64"
21039 [(set (match_operand:DI 0 "register_operand" "=a")
21040 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21041 (set (match_operand:DI 1 "register_operand" "=d")
21042 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21043 "TARGET_64BIT"
21044 "rdtsc"
21045 [(set_attr "type" "other")
21046 (set_attr "length" "2")])
21047
21048 (define_insn "rdtscp"
21049 [(set (match_operand:DI 0 "register_operand" "=A")
21050 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21051 (set (match_operand:SI 1 "register_operand" "=c")
21052 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21053 "!TARGET_64BIT"
21054 "rdtscp"
21055 [(set_attr "type" "other")
21056 (set_attr "length" "3")])
21057
21058 (define_insn "rdtscp_rex64"
21059 [(set (match_operand:DI 0 "register_operand" "=a")
21060 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21061 (set (match_operand:DI 1 "register_operand" "=d")
21062 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21063 (set (match_operand:SI 2 "register_operand" "=c")
21064 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21065 "TARGET_64BIT"
21066 "rdtscp"
21067 [(set_attr "type" "other")
21068 (set_attr "length" "3")])
21069
21070 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21071 ;;
21072 ;; FXSR, XSAVE and XSAVEOPT instructions
21073 ;;
21074 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21075
21076 (define_insn "fxsave"
21077 [(set (match_operand:BLK 0 "memory_operand" "=m")
21078 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
21079 "TARGET_FXSR"
21080 "fxsave\t%0"
21081 [(set_attr "type" "other")
21082 (set_attr "memory" "store")
21083 (set (attr "length")
21084 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21085
21086 (define_insn "fxsave64"
21087 [(set (match_operand:BLK 0 "memory_operand" "=m")
21088 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
21089 "TARGET_64BIT && TARGET_FXSR"
21090 "fxsave64\t%0"
21091 [(set_attr "type" "other")
21092 (set_attr "memory" "store")
21093 (set (attr "length")
21094 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
21095
21096 (define_insn "fxrstor"
21097 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
21098 UNSPECV_FXRSTOR)]
21099 "TARGET_FXSR"
21100 "fxrstor\t%0"
21101 [(set_attr "type" "other")
21102 (set_attr "memory" "load")
21103 (set (attr "length")
21104 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21105
21106 (define_insn "fxrstor64"
21107 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
21108 UNSPECV_FXRSTOR64)]
21109 "TARGET_64BIT && TARGET_FXSR"
21110 "fxrstor64\t%0"
21111 [(set_attr "type" "other")
21112 (set_attr "memory" "load")
21113 (set (attr "length")
21114 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
21115
21116 (define_int_iterator ANY_XSAVE
21117 [UNSPECV_XSAVE
21118 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
21119 (UNSPECV_XSAVEC "TARGET_XSAVEC")
21120 (UNSPECV_XSAVES "TARGET_XSAVES")])
21121
21122 (define_int_iterator ANY_XSAVE64
21123 [UNSPECV_XSAVE64
21124 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
21125 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
21126 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
21127
21128 (define_int_attr xsave
21129 [(UNSPECV_XSAVE "xsave")
21130 (UNSPECV_XSAVE64 "xsave64")
21131 (UNSPECV_XSAVEOPT "xsaveopt")
21132 (UNSPECV_XSAVEOPT64 "xsaveopt64")
21133 (UNSPECV_XSAVEC "xsavec")
21134 (UNSPECV_XSAVEC64 "xsavec64")
21135 (UNSPECV_XSAVES "xsaves")
21136 (UNSPECV_XSAVES64 "xsaves64")])
21137
21138 (define_int_iterator ANY_XRSTOR
21139 [UNSPECV_XRSTOR
21140 (UNSPECV_XRSTORS "TARGET_XSAVES")])
21141
21142 (define_int_iterator ANY_XRSTOR64
21143 [UNSPECV_XRSTOR64
21144 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
21145
21146 (define_int_attr xrstor
21147 [(UNSPECV_XRSTOR "xrstor")
21148 (UNSPECV_XRSTOR64 "xrstor")
21149 (UNSPECV_XRSTORS "xrstors")
21150 (UNSPECV_XRSTORS64 "xrstors")])
21151
21152 (define_insn "<xsave>"
21153 [(set (match_operand:BLK 0 "memory_operand" "=m")
21154 (unspec_volatile:BLK
21155 [(match_operand:DI 1 "register_operand" "A")]
21156 ANY_XSAVE))]
21157 "!TARGET_64BIT && TARGET_XSAVE"
21158 "<xsave>\t%0"
21159 [(set_attr "type" "other")
21160 (set_attr "memory" "store")
21161 (set (attr "length")
21162 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21163
21164 (define_insn "<xsave>_rex64"
21165 [(set (match_operand:BLK 0 "memory_operand" "=m")
21166 (unspec_volatile:BLK
21167 [(match_operand:SI 1 "register_operand" "a")
21168 (match_operand:SI 2 "register_operand" "d")]
21169 ANY_XSAVE))]
21170 "TARGET_64BIT && TARGET_XSAVE"
21171 "<xsave>\t%0"
21172 [(set_attr "type" "other")
21173 (set_attr "memory" "store")
21174 (set (attr "length")
21175 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21176
21177 (define_insn "<xsave>"
21178 [(set (match_operand:BLK 0 "memory_operand" "=m")
21179 (unspec_volatile:BLK
21180 [(match_operand:SI 1 "register_operand" "a")
21181 (match_operand:SI 2 "register_operand" "d")]
21182 ANY_XSAVE64))]
21183 "TARGET_64BIT && TARGET_XSAVE"
21184 "<xsave>\t%0"
21185 [(set_attr "type" "other")
21186 (set_attr "memory" "store")
21187 (set (attr "length")
21188 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
21189
21190 (define_insn "<xrstor>"
21191 [(unspec_volatile:BLK
21192 [(match_operand:BLK 0 "memory_operand" "m")
21193 (match_operand:DI 1 "register_operand" "A")]
21194 ANY_XRSTOR)]
21195 "!TARGET_64BIT && TARGET_XSAVE"
21196 "<xrstor>\t%0"
21197 [(set_attr "type" "other")
21198 (set_attr "memory" "load")
21199 (set (attr "length")
21200 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21201
21202 (define_insn "<xrstor>_rex64"
21203 [(unspec_volatile:BLK
21204 [(match_operand:BLK 0 "memory_operand" "m")
21205 (match_operand:SI 1 "register_operand" "a")
21206 (match_operand:SI 2 "register_operand" "d")]
21207 ANY_XRSTOR)]
21208 "TARGET_64BIT && TARGET_XSAVE"
21209 "<xrstor>\t%0"
21210 [(set_attr "type" "other")
21211 (set_attr "memory" "load")
21212 (set (attr "length")
21213 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21214
21215 (define_insn "<xrstor>64"
21216 [(unspec_volatile:BLK
21217 [(match_operand:BLK 0 "memory_operand" "m")
21218 (match_operand:SI 1 "register_operand" "a")
21219 (match_operand:SI 2 "register_operand" "d")]
21220 ANY_XRSTOR64)]
21221 "TARGET_64BIT && TARGET_XSAVE"
21222 "<xrstor>64\t%0"
21223 [(set_attr "type" "other")
21224 (set_attr "memory" "load")
21225 (set (attr "length")
21226 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
21227
21228 (define_insn "xsetbv"
21229 [(unspec_volatile:SI
21230 [(match_operand:SI 0 "register_operand" "c")
21231 (match_operand:DI 1 "register_operand" "A")]
21232 UNSPECV_XSETBV)]
21233 "!TARGET_64BIT && TARGET_XSAVE"
21234 "xsetbv"
21235 [(set_attr "type" "other")])
21236
21237 (define_insn "xsetbv_rex64"
21238 [(unspec_volatile:SI
21239 [(match_operand:SI 0 "register_operand" "c")
21240 (match_operand:SI 1 "register_operand" "a")
21241 (match_operand:SI 2 "register_operand" "d")]
21242 UNSPECV_XSETBV)]
21243 "TARGET_64BIT && TARGET_XSAVE"
21244 "xsetbv"
21245 [(set_attr "type" "other")])
21246
21247 (define_insn "xgetbv"
21248 [(set (match_operand:DI 0 "register_operand" "=A")
21249 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21250 UNSPECV_XGETBV))]
21251 "!TARGET_64BIT && TARGET_XSAVE"
21252 "xgetbv"
21253 [(set_attr "type" "other")])
21254
21255 (define_insn "xgetbv_rex64"
21256 [(set (match_operand:DI 0 "register_operand" "=a")
21257 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21258 UNSPECV_XGETBV))
21259 (set (match_operand:DI 1 "register_operand" "=d")
21260 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
21261 "TARGET_64BIT && TARGET_XSAVE"
21262 "xgetbv"
21263 [(set_attr "type" "other")])
21264
21265 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21266 ;;
21267 ;; Floating-point instructions for atomic compound assignments
21268 ;;
21269 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21270
21271 ; Clobber all floating-point registers on environment save and restore
21272 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
21273 (define_insn "fnstenv"
21274 [(set (match_operand:BLK 0 "memory_operand" "=m")
21275 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
21276 (clobber (reg:XF ST0_REG))
21277 (clobber (reg:XF ST1_REG))
21278 (clobber (reg:XF ST2_REG))
21279 (clobber (reg:XF ST3_REG))
21280 (clobber (reg:XF ST4_REG))
21281 (clobber (reg:XF ST5_REG))
21282 (clobber (reg:XF ST6_REG))
21283 (clobber (reg:XF ST7_REG))]
21284 "TARGET_80387"
21285 "fnstenv\t%0"
21286 [(set_attr "type" "other")
21287 (set_attr "memory" "store")
21288 (set (attr "length")
21289 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
21290
21291 (define_insn "fldenv"
21292 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
21293 UNSPECV_FLDENV)
21294 (clobber (reg:XF ST0_REG))
21295 (clobber (reg:XF ST1_REG))
21296 (clobber (reg:XF ST2_REG))
21297 (clobber (reg:XF ST3_REG))
21298 (clobber (reg:XF ST4_REG))
21299 (clobber (reg:XF ST5_REG))
21300 (clobber (reg:XF ST6_REG))
21301 (clobber (reg:XF ST7_REG))]
21302 "TARGET_80387"
21303 "fldenv\t%0"
21304 [(set_attr "type" "other")
21305 (set_attr "memory" "load")
21306 (set (attr "length")
21307 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
21308
21309 (define_insn "fnstsw"
21310 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
21311 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
21312 "TARGET_80387"
21313 "fnstsw\t%0"
21314 [(set_attr "type" "other,other")
21315 (set_attr "memory" "none,store")
21316 (set (attr "length")
21317 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
21318
21319 (define_insn "fnclex"
21320 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
21321 "TARGET_80387"
21322 "fnclex"
21323 [(set_attr "type" "other")
21324 (set_attr "memory" "none")
21325 (set_attr "length" "2")])
21326
21327 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21328 ;;
21329 ;; LWP instructions
21330 ;;
21331 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21332
21333 (define_insn "@lwp_llwpcb<mode>"
21334 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
21335 UNSPECV_LLWP_INTRINSIC)]
21336 "TARGET_LWP"
21337 "llwpcb\t%0"
21338 [(set_attr "type" "lwp")
21339 (set_attr "mode" "<MODE>")
21340 (set_attr "length" "5")])
21341
21342 (define_insn "@lwp_slwpcb<mode>"
21343 [(set (match_operand:P 0 "register_operand" "=r")
21344 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
21345 "TARGET_LWP"
21346 "slwpcb\t%0"
21347 [(set_attr "type" "lwp")
21348 (set_attr "mode" "<MODE>")
21349 (set_attr "length" "5")])
21350
21351 (define_insn "@lwp_lwpval<mode>"
21352 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
21353 (match_operand:SI 1 "nonimmediate_operand" "rm")
21354 (match_operand:SI 2 "const_int_operand" "i")]
21355 UNSPECV_LWPVAL_INTRINSIC)]
21356 "TARGET_LWP"
21357 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21358 [(set_attr "type" "lwp")
21359 (set_attr "mode" "<MODE>")
21360 (set (attr "length")
21361 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
21362
21363 (define_insn "@lwp_lwpins<mode>"
21364 [(set (reg:CCC FLAGS_REG)
21365 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
21366 (match_operand:SI 1 "nonimmediate_operand" "rm")
21367 (match_operand:SI 2 "const_int_operand" "i")]
21368 UNSPECV_LWPINS_INTRINSIC))]
21369 "TARGET_LWP"
21370 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21371 [(set_attr "type" "lwp")
21372 (set_attr "mode" "<MODE>")
21373 (set (attr "length")
21374 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
21375
21376 (define_int_iterator RDFSGSBASE
21377 [UNSPECV_RDFSBASE
21378 UNSPECV_RDGSBASE])
21379
21380 (define_int_iterator WRFSGSBASE
21381 [UNSPECV_WRFSBASE
21382 UNSPECV_WRGSBASE])
21383
21384 (define_int_attr fsgs
21385 [(UNSPECV_RDFSBASE "fs")
21386 (UNSPECV_RDGSBASE "gs")
21387 (UNSPECV_WRFSBASE "fs")
21388 (UNSPECV_WRGSBASE "gs")])
21389
21390 (define_insn "rd<fsgs>base<mode>"
21391 [(set (match_operand:SWI48 0 "register_operand" "=r")
21392 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
21393 "TARGET_64BIT && TARGET_FSGSBASE"
21394 "rd<fsgs>base\t%0"
21395 [(set_attr "type" "other")
21396 (set_attr "prefix_extra" "2")])
21397
21398 (define_insn "wr<fsgs>base<mode>"
21399 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
21400 WRFSGSBASE)]
21401 "TARGET_64BIT && TARGET_FSGSBASE"
21402 "wr<fsgs>base\t%0"
21403 [(set_attr "type" "other")
21404 (set_attr "prefix_extra" "2")])
21405
21406 (define_insn "ptwrite<mode>"
21407 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
21408 UNSPECV_PTWRITE)]
21409 "TARGET_PTWRITE"
21410 "ptwrite\t%0"
21411 [(set_attr "type" "other")
21412 (set_attr "prefix_extra" "2")])
21413
21414 (define_insn "@rdrand<mode>"
21415 [(set (match_operand:SWI248 0 "register_operand" "=r")
21416 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
21417 (set (reg:CCC FLAGS_REG)
21418 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
21419 "TARGET_RDRND"
21420 "rdrand\t%0"
21421 [(set_attr "type" "other")
21422 (set_attr "prefix_extra" "1")])
21423
21424 (define_insn "@rdseed<mode>"
21425 [(set (match_operand:SWI248 0 "register_operand" "=r")
21426 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
21427 (set (reg:CCC FLAGS_REG)
21428 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
21429 "TARGET_RDSEED"
21430 "rdseed\t%0"
21431 [(set_attr "type" "other")
21432 (set_attr "prefix_extra" "1")])
21433
21434 (define_expand "pause"
21435 [(set (match_dup 0)
21436 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
21437 ""
21438 {
21439 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21440 MEM_VOLATILE_P (operands[0]) = 1;
21441 })
21442
21443 ;; Use "rep; nop", instead of "pause", to support older assemblers.
21444 ;; They have the same encoding.
21445 (define_insn "*pause"
21446 [(set (match_operand:BLK 0)
21447 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
21448 ""
21449 "rep%; nop"
21450 [(set_attr "length" "2")
21451 (set_attr "memory" "unknown")])
21452
21453 ;; CET instructions
21454 (define_insn "@rdssp<mode>"
21455 [(set (match_operand:SWI48 0 "register_operand" "=r")
21456 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
21457 UNSPECV_NOP_RDSSP))]
21458 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
21459 "rdssp<mskmodesuffix>\t%0"
21460 [(set_attr "length" "6")
21461 (set_attr "type" "other")])
21462
21463 (define_insn "@incssp<mode>"
21464 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
21465 UNSPECV_INCSSP)]
21466 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
21467 "incssp<mskmodesuffix>\t%0"
21468 [(set_attr "length" "4")
21469 (set_attr "type" "other")])
21470
21471 (define_insn "saveprevssp"
21472 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
21473 "TARGET_SHSTK"
21474 "saveprevssp"
21475 [(set_attr "length" "5")
21476 (set_attr "type" "other")])
21477
21478 (define_insn "rstorssp"
21479 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
21480 UNSPECV_RSTORSSP)]
21481 "TARGET_SHSTK"
21482 "rstorssp\t%0"
21483 [(set_attr "length" "5")
21484 (set_attr "type" "other")])
21485
21486 (define_insn "@wrss<mode>"
21487 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
21488 (match_operand:SWI48 1 "memory_operand" "m")]
21489 UNSPECV_WRSS)]
21490 "TARGET_SHSTK"
21491 "wrss<mskmodesuffix>\t%0, %1"
21492 [(set_attr "length" "3")
21493 (set_attr "type" "other")])
21494
21495 (define_insn "@wruss<mode>"
21496 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
21497 (match_operand:SWI48 1 "memory_operand" "m")]
21498 UNSPECV_WRUSS)]
21499 "TARGET_SHSTK"
21500 "wruss<mskmodesuffix>\t%0, %1"
21501 [(set_attr "length" "4")
21502 (set_attr "type" "other")])
21503
21504 (define_insn "setssbsy"
21505 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
21506 "TARGET_SHSTK"
21507 "setssbsy"
21508 [(set_attr "length" "4")
21509 (set_attr "type" "other")])
21510
21511 (define_insn "clrssbsy"
21512 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
21513 UNSPECV_CLRSSBSY)]
21514 "TARGET_SHSTK"
21515 "clrssbsy\t%0"
21516 [(set_attr "length" "4")
21517 (set_attr "type" "other")])
21518
21519 (define_insn "nop_endbr"
21520 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
21521 "(flag_cf_protection & CF_BRANCH)"
21522 {
21523 return TARGET_64BIT ? "endbr64" : "endbr32";
21524 }
21525 [(set_attr "length" "4")
21526 (set_attr "length_immediate" "0")
21527 (set_attr "modrm" "0")])
21528
21529 ;; For RTM support
21530 (define_expand "xbegin"
21531 [(set (match_operand:SI 0 "register_operand")
21532 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
21533 "TARGET_RTM"
21534 {
21535 rtx_code_label *label = gen_label_rtx ();
21536
21537 /* xbegin is emitted as jump_insn, so reload won't be able
21538 to reload its operand. Force the value into AX hard register. */
21539 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
21540 emit_move_insn (ax_reg, constm1_rtx);
21541
21542 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
21543
21544 emit_label (label);
21545 LABEL_NUSES (label) = 1;
21546
21547 emit_move_insn (operands[0], ax_reg);
21548
21549 DONE;
21550 })
21551
21552 (define_insn "xbegin_1"
21553 [(set (pc)
21554 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
21555 (const_int 0))
21556 (label_ref (match_operand 1))
21557 (pc)))
21558 (set (match_operand:SI 0 "register_operand" "+a")
21559 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
21560 "TARGET_RTM"
21561 "xbegin\t%l1"
21562 [(set_attr "type" "other")
21563 (set_attr "length" "6")])
21564
21565 (define_insn "xend"
21566 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
21567 "TARGET_RTM"
21568 "xend"
21569 [(set_attr "type" "other")
21570 (set_attr "length" "3")])
21571
21572 (define_insn "xabort"
21573 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
21574 UNSPECV_XABORT)]
21575 "TARGET_RTM"
21576 "xabort\t%0"
21577 [(set_attr "type" "other")
21578 (set_attr "length" "3")])
21579
21580 (define_expand "xtest"
21581 [(set (match_operand:QI 0 "register_operand")
21582 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
21583 "TARGET_RTM"
21584 {
21585 emit_insn (gen_xtest_1 ());
21586
21587 ix86_expand_setcc (operands[0], NE,
21588 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
21589 DONE;
21590 })
21591
21592 (define_insn "xtest_1"
21593 [(set (reg:CCZ FLAGS_REG)
21594 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
21595 "TARGET_RTM"
21596 "xtest"
21597 [(set_attr "type" "other")
21598 (set_attr "length" "3")])
21599
21600 (define_insn "clwb"
21601 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
21602 UNSPECV_CLWB)]
21603 "TARGET_CLWB"
21604 "clwb\t%a0"
21605 [(set_attr "type" "sse")
21606 (set_attr "atom_sse_attr" "fence")
21607 (set_attr "memory" "unknown")])
21608
21609 (define_insn "clflushopt"
21610 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
21611 UNSPECV_CLFLUSHOPT)]
21612 "TARGET_CLFLUSHOPT"
21613 "clflushopt\t%a0"
21614 [(set_attr "type" "sse")
21615 (set_attr "atom_sse_attr" "fence")
21616 (set_attr "memory" "unknown")])
21617
21618 ;; MONITORX and MWAITX
21619 (define_insn "mwaitx"
21620 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
21621 (match_operand:SI 1 "register_operand" "a")
21622 (match_operand:SI 2 "register_operand" "b")]
21623 UNSPECV_MWAITX)]
21624 "TARGET_MWAITX"
21625 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
21626 ;; Since 32bit register operands are implicitly zero extended to 64bit,
21627 ;; we only need to set up 32bit registers.
21628 "mwaitx"
21629 [(set_attr "length" "3")])
21630
21631 (define_insn "@monitorx_<mode>"
21632 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
21633 (match_operand:SI 1 "register_operand" "c")
21634 (match_operand:SI 2 "register_operand" "d")]
21635 UNSPECV_MONITORX)]
21636 "TARGET_MWAITX"
21637 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
21638 ;; RCX and RDX are used. Since 32bit register operands are implicitly
21639 ;; zero extended to 64bit, we only need to set up 32bit registers.
21640 "%^monitorx"
21641 [(set (attr "length")
21642 (symbol_ref ("(Pmode != word_mode) + 3")))])
21643
21644 ;; CLZERO
21645 (define_insn "@clzero_<mode>"
21646 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
21647 UNSPECV_CLZERO)]
21648 "TARGET_CLZERO"
21649 "clzero"
21650 [(set_attr "length" "3")
21651 (set_attr "memory" "unknown")])
21652
21653 ;; RDPKRU and WRPKRU
21654
21655 (define_expand "rdpkru"
21656 [(parallel
21657 [(set (match_operand:SI 0 "register_operand")
21658 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
21659 (set (match_dup 2) (const_int 0))])]
21660 "TARGET_PKU"
21661 {
21662 operands[1] = force_reg (SImode, const0_rtx);
21663 operands[2] = gen_reg_rtx (SImode);
21664 })
21665
21666 (define_insn "*rdpkru"
21667 [(set (match_operand:SI 0 "register_operand" "=a")
21668 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
21669 UNSPECV_PKU))
21670 (set (match_operand:SI 1 "register_operand" "=d")
21671 (const_int 0))]
21672 "TARGET_PKU"
21673 "rdpkru"
21674 [(set_attr "type" "other")])
21675
21676 (define_expand "wrpkru"
21677 [(unspec_volatile:SI
21678 [(match_operand:SI 0 "register_operand")
21679 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
21680 "TARGET_PKU"
21681 {
21682 operands[1] = force_reg (SImode, const0_rtx);
21683 operands[2] = force_reg (SImode, const0_rtx);
21684 })
21685
21686 (define_insn "*wrpkru"
21687 [(unspec_volatile:SI
21688 [(match_operand:SI 0 "register_operand" "a")
21689 (match_operand:SI 1 "register_operand" "d")
21690 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
21691 "TARGET_PKU"
21692 "wrpkru"
21693 [(set_attr "type" "other")])
21694
21695 (define_insn "rdpid"
21696 [(set (match_operand:SI 0 "register_operand" "=r")
21697 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
21698 "!TARGET_64BIT && TARGET_RDPID"
21699 "rdpid\t%0"
21700 [(set_attr "type" "other")])
21701
21702 (define_insn "rdpid_rex64"
21703 [(set (match_operand:DI 0 "register_operand" "=r")
21704 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
21705 "TARGET_64BIT && TARGET_RDPID"
21706 "rdpid\t%0"
21707 [(set_attr "type" "other")])
21708
21709 ;; Intirinsics for > i486
21710
21711 (define_insn "wbinvd"
21712 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
21713 ""
21714 "wbinvd"
21715 [(set_attr "type" "other")])
21716
21717 (define_insn "wbnoinvd"
21718 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
21719 "TARGET_WBNOINVD"
21720 "wbnoinvd"
21721 [(set_attr "type" "other")])
21722
21723 ;; MOVDIRI and MOVDIR64B
21724
21725 (define_insn "movdiri<mode>"
21726 [(set (match_operand:SWI48 0 "memory_operand" "=m")
21727 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
21728 UNSPEC_MOVDIRI))]
21729 "TARGET_MOVDIRI"
21730 "movdiri\t{%1, %0|%0, %1}"
21731 [(set_attr "type" "other")])
21732
21733 (define_insn "@movdir64b_<mode>"
21734 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
21735 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
21736 UNSPEC_MOVDIR64B))]
21737 "TARGET_MOVDIR64B"
21738 "movdir64b\t{%1, %0|%0, %1}"
21739 [(set_attr "type" "other")])
21740
21741 ;; TSXLDTRK
21742 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
21743 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
21744 (UNSPECV_XRESLDTRK "xresldtrk")])
21745 (define_insn "<tsxldtrk>"
21746 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
21747 "TARGET_TSXLDTRK"
21748 "<tsxldtrk>"
21749 [(set_attr "type" "other")
21750 (set_attr "length" "4")])
21751
21752 ;; ENQCMD and ENQCMDS
21753
21754 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
21755 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
21756
21757 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
21758 [(set (reg:CCZ FLAGS_REG)
21759 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
21760 (match_operand:XI 1 "memory_operand" "m")]
21761 ENQCMD))]
21762 "TARGET_ENQCMD"
21763 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
21764 [(set_attr "type" "other")])
21765
21766 ;; UINTR
21767 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
21768 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
21769
21770 (define_insn "<uintr>"
21771 [(unspec_volatile [(const_int 0)] UINTR)]
21772 "TARGET_UINTR && TARGET_64BIT"
21773 "<uintr>"
21774 [(set_attr "type" "other")
21775 (set_attr "length" "4")])
21776
21777 (define_insn "testui"
21778 [(set (reg:CCC FLAGS_REG)
21779 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
21780 "TARGET_UINTR && TARGET_64BIT"
21781 "testui"
21782 [(set_attr "type" "other")
21783 (set_attr "length" "4")])
21784
21785 (define_insn "senduipi"
21786 [(unspec_volatile
21787 [(match_operand:DI 0 "register_operand" "r")]
21788 UNSPECV_SENDUIPI)]
21789 "TARGET_UINTR && TARGET_64BIT"
21790 "senduipi\t%0"
21791 [(set_attr "type" "other")
21792 (set_attr "length" "4")])
21793
21794 ;; WAITPKG
21795
21796 (define_insn "umwait"
21797 [(set (reg:CCC FLAGS_REG)
21798 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21799 (match_operand:DI 1 "register_operand" "A")]
21800 UNSPECV_UMWAIT))]
21801 "!TARGET_64BIT && TARGET_WAITPKG"
21802 "umwait\t%0"
21803 [(set_attr "length" "3")])
21804
21805 (define_insn "umwait_rex64"
21806 [(set (reg:CCC FLAGS_REG)
21807 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21808 (match_operand:SI 1 "register_operand" "a")
21809 (match_operand:SI 2 "register_operand" "d")]
21810 UNSPECV_UMWAIT))]
21811 "TARGET_64BIT && TARGET_WAITPKG"
21812 "umwait\t%0"
21813 [(set_attr "length" "3")])
21814
21815 (define_insn "@umonitor_<mode>"
21816 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
21817 UNSPECV_UMONITOR)]
21818 "TARGET_WAITPKG"
21819 "umonitor\t%0"
21820 [(set (attr "length")
21821 (symbol_ref ("(Pmode != word_mode) + 3")))])
21822
21823 (define_insn "tpause"
21824 [(set (reg:CCC FLAGS_REG)
21825 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21826 (match_operand:DI 1 "register_operand" "A")]
21827 UNSPECV_TPAUSE))]
21828 "!TARGET_64BIT && TARGET_WAITPKG"
21829 "tpause\t%0"
21830 [(set_attr "length" "3")])
21831
21832 (define_insn "tpause_rex64"
21833 [(set (reg:CCC FLAGS_REG)
21834 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21835 (match_operand:SI 1 "register_operand" "a")
21836 (match_operand:SI 2 "register_operand" "d")]
21837 UNSPECV_TPAUSE))]
21838 "TARGET_64BIT && TARGET_WAITPKG"
21839 "tpause\t%0"
21840 [(set_attr "length" "3")])
21841
21842 (define_insn "cldemote"
21843 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
21844 UNSPECV_CLDEMOTE)]
21845 "TARGET_CLDEMOTE"
21846 "cldemote\t%a0"
21847 [(set_attr "type" "other")
21848 (set_attr "memory" "unknown")])
21849
21850 (define_insn "speculation_barrier"
21851 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
21852 ""
21853 "lfence"
21854 [(set_attr "type" "other")
21855 (set_attr "length" "3")])
21856
21857 (define_insn "serialize"
21858 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
21859 "TARGET_SERIALIZE"
21860 "serialize"
21861 [(set_attr "type" "other")
21862 (set_attr "length" "3")])
21863
21864 (define_insn "patchable_area"
21865 [(unspec_volatile [(match_operand 0 "const_int_operand")
21866 (match_operand 1 "const_int_operand")]
21867 UNSPECV_PATCHABLE_AREA)]
21868 ""
21869 {
21870 ix86_output_patchable_area (INTVAL (operands[0]),
21871 INTVAL (operands[1]) != 0);
21872 return "";
21873 }
21874 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
21875 (set_attr "length_immediate" "0")
21876 (set_attr "modrm" "0")])
21877
21878 (define_insn "hreset"
21879 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
21880 UNSPECV_HRESET)]
21881 "TARGET_HRESET"
21882 "hreset\t{$0|0}"
21883 [(set_attr "type" "other")
21884 (set_attr "length" "4")])
21885
21886 (include "mmx.md")
21887 (include "sse.md")
21888 (include "sync.md")