]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
* config/i386/i386.md (and<mode>3): Generate zero-extends for
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2019 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_FLOOR
145 UNSPEC_FRNDINT_CEIL
146 UNSPEC_FRNDINT_TRUNC
147 UNSPEC_FIST_FLOOR
148 UNSPEC_FIST_CEIL
149
150 ;; x87 Double output FP
151 UNSPEC_SINCOS_COS
152 UNSPEC_SINCOS_SIN
153 UNSPEC_XTRACT_FRACT
154 UNSPEC_XTRACT_EXP
155 UNSPEC_FSCALE_FRACT
156 UNSPEC_FSCALE_EXP
157 UNSPEC_FPREM_F
158 UNSPEC_FPREM_U
159 UNSPEC_FPREM1_F
160 UNSPEC_FPREM1_U
161
162 UNSPEC_C2_FLAG
163 UNSPEC_FXAM_MEM
164
165 ;; SSP patterns
166 UNSPEC_SP_SET
167 UNSPEC_SP_TEST
168
169 ;; For ROUND support
170 UNSPEC_ROUND
171
172 ;; For CRC32 support
173 UNSPEC_CRC32
174
175 ;; For LZCNT suppoprt
176 UNSPEC_LZCNT
177
178 ;; For BMI support
179 UNSPEC_TZCNT
180 UNSPEC_BEXTR
181
182 ;; For BMI2 support
183 UNSPEC_PDEP
184 UNSPEC_PEXT
185
186 ;; IRET support
187 UNSPEC_INTERRUPT_RETURN
188 ])
189
190 (define_c_enum "unspecv" [
191 UNSPECV_UD2
192 UNSPECV_BLOCKAGE
193 UNSPECV_STACK_PROBE
194 UNSPECV_PROBE_STACK_RANGE
195 UNSPECV_ALIGN
196 UNSPECV_PROLOGUE_USE
197 UNSPECV_SPLIT_STACK_RETURN
198 UNSPECV_CLD
199 UNSPECV_NOPS
200 UNSPECV_RDTSC
201 UNSPECV_RDTSCP
202 UNSPECV_RDPMC
203 UNSPECV_LLWP_INTRINSIC
204 UNSPECV_SLWP_INTRINSIC
205 UNSPECV_LWPVAL_INTRINSIC
206 UNSPECV_LWPINS_INTRINSIC
207 UNSPECV_RDFSBASE
208 UNSPECV_RDGSBASE
209 UNSPECV_WRFSBASE
210 UNSPECV_WRGSBASE
211 UNSPECV_FXSAVE
212 UNSPECV_FXRSTOR
213 UNSPECV_FXSAVE64
214 UNSPECV_FXRSTOR64
215 UNSPECV_XSAVE
216 UNSPECV_XRSTOR
217 UNSPECV_XSAVE64
218 UNSPECV_XRSTOR64
219 UNSPECV_XSAVEOPT
220 UNSPECV_XSAVEOPT64
221 UNSPECV_XSAVES
222 UNSPECV_XRSTORS
223 UNSPECV_XSAVES64
224 UNSPECV_XRSTORS64
225 UNSPECV_XSAVEC
226 UNSPECV_XSAVEC64
227 UNSPECV_XGETBV
228 UNSPECV_XSETBV
229 UNSPECV_WBINVD
230 UNSPECV_WBNOINVD
231
232 ;; For atomic compound assignments.
233 UNSPECV_FNSTENV
234 UNSPECV_FLDENV
235 UNSPECV_FNSTSW
236 UNSPECV_FNCLEX
237
238 ;; For RDRAND support
239 UNSPECV_RDRAND
240
241 ;; For RDSEED support
242 UNSPECV_RDSEED
243
244 ;; For RTM support
245 UNSPECV_XBEGIN
246 UNSPECV_XEND
247 UNSPECV_XABORT
248 UNSPECV_XTEST
249
250 UNSPECV_NLGR
251
252 ;; For CLWB support
253 UNSPECV_CLWB
254
255 ;; For CLFLUSHOPT support
256 UNSPECV_CLFLUSHOPT
257
258 ;; For MONITORX and MWAITX support
259 UNSPECV_MONITORX
260 UNSPECV_MWAITX
261
262 ;; For CLZERO support
263 UNSPECV_CLZERO
264
265 ;; For RDPKRU and WRPKRU support
266 UNSPECV_PKU
267
268 ;; For RDPID support
269 UNSPECV_RDPID
270
271 ;; For CET support
272 UNSPECV_NOP_ENDBR
273 UNSPECV_NOP_RDSSP
274 UNSPECV_INCSSP
275 UNSPECV_SAVEPREVSSP
276 UNSPECV_RSTORSSP
277 UNSPECV_WRSS
278 UNSPECV_WRUSS
279 UNSPECV_SETSSBSY
280 UNSPECV_CLRSSBSY
281
282 ;; For MOVDIRI and MOVDIR64B support
283 UNSPECV_MOVDIRI
284 UNSPECV_MOVDIR64B
285
286 ;; For WAITPKG support
287 UNSPECV_UMWAIT
288 UNSPECV_UMONITOR
289 UNSPECV_TPAUSE
290
291 ;; For CLDEMOTE support
292 UNSPECV_CLDEMOTE
293
294 ;; For Speculation Barrier support
295 UNSPECV_SPECULATION_BARRIER
296
297 UNSPECV_PTWRITE
298
299 ;; For ENQCMD and ENQCMDS support
300 UNSPECV_ENQCMD
301 UNSPECV_ENQCMDS
302 ])
303
304 ;; Constants to represent rounding modes in the ROUND instruction
305 (define_constants
306 [(ROUND_FLOOR 0x1)
307 (ROUND_CEIL 0x2)
308 (ROUND_TRUNC 0x3)
309 (ROUND_MXCSR 0x4)
310 (ROUND_NO_EXC 0x8)
311 ])
312
313 ;; Constants to represent AVX512F embeded rounding
314 (define_constants
315 [(ROUND_NEAREST_INT 0)
316 (ROUND_NEG_INF 1)
317 (ROUND_POS_INF 2)
318 (ROUND_ZERO 3)
319 (NO_ROUND 4)
320 (ROUND_SAE 8)
321 ])
322
323 ;; Constants to represent pcomtrue/pcomfalse variants
324 (define_constants
325 [(PCOM_FALSE 0)
326 (PCOM_TRUE 1)
327 (COM_FALSE_S 2)
328 (COM_FALSE_P 3)
329 (COM_TRUE_S 4)
330 (COM_TRUE_P 5)
331 ])
332
333 ;; Constants used in the XOP pperm instruction
334 (define_constants
335 [(PPERM_SRC 0x00) /* copy source */
336 (PPERM_INVERT 0x20) /* invert source */
337 (PPERM_REVERSE 0x40) /* bit reverse source */
338 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
339 (PPERM_ZERO 0x80) /* all 0's */
340 (PPERM_ONES 0xa0) /* all 1's */
341 (PPERM_SIGN 0xc0) /* propagate sign bit */
342 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
343 (PPERM_SRC1 0x00) /* use first source byte */
344 (PPERM_SRC2 0x10) /* use second source byte */
345 ])
346
347 ;; Registers by name.
348 (define_constants
349 [(AX_REG 0)
350 (DX_REG 1)
351 (CX_REG 2)
352 (BX_REG 3)
353 (SI_REG 4)
354 (DI_REG 5)
355 (BP_REG 6)
356 (SP_REG 7)
357 (ST0_REG 8)
358 (ST1_REG 9)
359 (ST2_REG 10)
360 (ST3_REG 11)
361 (ST4_REG 12)
362 (ST5_REG 13)
363 (ST6_REG 14)
364 (ST7_REG 15)
365 (ARGP_REG 16)
366 (FLAGS_REG 17)
367 (FPSR_REG 18)
368 (FRAME_REG 19)
369 (XMM0_REG 20)
370 (XMM1_REG 21)
371 (XMM2_REG 22)
372 (XMM3_REG 23)
373 (XMM4_REG 24)
374 (XMM5_REG 25)
375 (XMM6_REG 26)
376 (XMM7_REG 27)
377 (MM0_REG 28)
378 (MM1_REG 29)
379 (MM2_REG 30)
380 (MM3_REG 31)
381 (MM4_REG 32)
382 (MM5_REG 33)
383 (MM6_REG 34)
384 (MM7_REG 35)
385 (R8_REG 36)
386 (R9_REG 37)
387 (R10_REG 38)
388 (R11_REG 39)
389 (R12_REG 40)
390 (R13_REG 41)
391 (R14_REG 42)
392 (R15_REG 43)
393 (XMM8_REG 44)
394 (XMM9_REG 45)
395 (XMM10_REG 46)
396 (XMM11_REG 47)
397 (XMM12_REG 48)
398 (XMM13_REG 49)
399 (XMM14_REG 50)
400 (XMM15_REG 51)
401 (XMM16_REG 52)
402 (XMM17_REG 53)
403 (XMM18_REG 54)
404 (XMM19_REG 55)
405 (XMM20_REG 56)
406 (XMM21_REG 57)
407 (XMM22_REG 58)
408 (XMM23_REG 59)
409 (XMM24_REG 60)
410 (XMM25_REG 61)
411 (XMM26_REG 62)
412 (XMM27_REG 63)
413 (XMM28_REG 64)
414 (XMM29_REG 65)
415 (XMM30_REG 66)
416 (XMM31_REG 67)
417 (MASK0_REG 68)
418 (MASK1_REG 69)
419 (MASK2_REG 70)
420 (MASK3_REG 71)
421 (MASK4_REG 72)
422 (MASK5_REG 73)
423 (MASK6_REG 74)
424 (MASK7_REG 75)
425 (FIRST_PSEUDO_REG 76)
426 ])
427
428 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
429 ;; from i386.c.
430
431 ;; In C guard expressions, put expressions which may be compile-time
432 ;; constants first. This allows for better optimization. For
433 ;; example, write "TARGET_64BIT && reload_completed", not
434 ;; "reload_completed && TARGET_64BIT".
435
436 \f
437 ;; Processor type.
438 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
439 atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
440 bdver4,btver2,znver1,znver2"
441 (const (symbol_ref "ix86_schedule")))
442
443 ;; A basic instruction type. Refinements due to arguments to be
444 ;; provided in other attributes.
445 (define_attr "type"
446 "other,multi,
447 alu,alu1,negnot,imov,imovx,lea,
448 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
449 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
450 push,pop,call,callv,leave,
451 str,bitmanip,
452 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
453 fxch,fistp,fisttp,frndint,
454 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
455 ssemul,sseimul,ssediv,sselog,sselog1,
456 sseishft,sseishft1,ssecmp,ssecomi,
457 ssecvt,ssecvt1,sseicvt,sseins,
458 sseshuf,sseshuf1,ssemuladd,sse4arg,
459 lwp,mskmov,msklog,
460 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
461 (const_string "other"))
462
463 ;; Main data type used by the insn
464 (define_attr "mode"
465 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
466 V2DF,V2SF,V1DF,V8DF"
467 (const_string "unknown"))
468
469 ;; The CPU unit operations uses.
470 (define_attr "unit" "integer,i387,sse,mmx,unknown"
471 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
472 fxch,fistp,fisttp,frndint")
473 (const_string "i387")
474 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
475 ssemul,sseimul,ssediv,sselog,sselog1,
476 sseishft,sseishft1,ssecmp,ssecomi,
477 ssecvt,ssecvt1,sseicvt,sseins,
478 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
479 (const_string "sse")
480 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
481 (const_string "mmx")
482 (eq_attr "type" "other")
483 (const_string "unknown")]
484 (const_string "integer")))
485
486 ;; The (bounding maximum) length of an instruction immediate.
487 (define_attr "length_immediate" ""
488 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
489 bitmanip,imulx,msklog,mskmov")
490 (const_int 0)
491 (eq_attr "unit" "i387,sse,mmx")
492 (const_int 0)
493 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
494 rotate,rotatex,rotate1,imul,icmp,push,pop")
495 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
496 (eq_attr "type" "imov,test")
497 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
498 (eq_attr "type" "call")
499 (if_then_else (match_operand 0 "constant_call_address_operand")
500 (const_int 4)
501 (const_int 0))
502 (eq_attr "type" "callv")
503 (if_then_else (match_operand 1 "constant_call_address_operand")
504 (const_int 4)
505 (const_int 0))
506 ;; We don't know the size before shorten_branches. Expect
507 ;; the instruction to fit for better scheduling.
508 (eq_attr "type" "ibr")
509 (const_int 1)
510 ]
511 (symbol_ref "/* Update immediate_length and other attributes! */
512 gcc_unreachable (),1")))
513
514 ;; The (bounding maximum) length of an instruction address.
515 (define_attr "length_address" ""
516 (cond [(eq_attr "type" "str,other,multi,fxch")
517 (const_int 0)
518 (and (eq_attr "type" "call")
519 (match_operand 0 "constant_call_address_operand"))
520 (const_int 0)
521 (and (eq_attr "type" "callv")
522 (match_operand 1 "constant_call_address_operand"))
523 (const_int 0)
524 ]
525 (symbol_ref "ix86_attr_length_address_default (insn)")))
526
527 ;; Set when length prefix is used.
528 (define_attr "prefix_data16" ""
529 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
530 (const_int 0)
531 (eq_attr "mode" "HI")
532 (const_int 1)
533 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
534 (const_int 1)
535 ]
536 (const_int 0)))
537
538 ;; Set when string REP prefix is used.
539 (define_attr "prefix_rep" ""
540 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
541 (const_int 0)
542 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
543 (const_int 1)
544 ]
545 (const_int 0)))
546
547 ;; Set when 0f opcode prefix is used.
548 (define_attr "prefix_0f" ""
549 (if_then_else
550 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
551 (eq_attr "unit" "sse,mmx"))
552 (const_int 1)
553 (const_int 0)))
554
555 ;; Set when REX opcode prefix is used.
556 (define_attr "prefix_rex" ""
557 (cond [(not (match_test "TARGET_64BIT"))
558 (const_int 0)
559 (and (eq_attr "mode" "DI")
560 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
561 (eq_attr "unit" "!mmx")))
562 (const_int 1)
563 (and (eq_attr "mode" "QI")
564 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
565 (const_int 1)
566 (match_test "x86_extended_reg_mentioned_p (insn)")
567 (const_int 1)
568 (and (eq_attr "type" "imovx")
569 (match_operand:QI 1 "ext_QIreg_operand"))
570 (const_int 1)
571 ]
572 (const_int 0)))
573
574 ;; There are also additional prefixes in 3DNOW, SSSE3.
575 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
576 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
577 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
578 (define_attr "prefix_extra" ""
579 (cond [(eq_attr "type" "ssemuladd,sse4arg")
580 (const_int 2)
581 (eq_attr "type" "sseiadd1,ssecvt1")
582 (const_int 1)
583 ]
584 (const_int 0)))
585
586 ;; Prefix used: original, VEX or maybe VEX.
587 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
588 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
589 (const_string "vex")
590 (eq_attr "mode" "XI,V16SF,V8DF")
591 (const_string "evex")
592 ]
593 (const_string "orig")))
594
595 ;; VEX W bit is used.
596 (define_attr "prefix_vex_w" "" (const_int 0))
597
598 ;; The length of VEX prefix
599 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
600 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
601 ;; still prefix_0f 1, with prefix_extra 1.
602 (define_attr "length_vex" ""
603 (if_then_else (and (eq_attr "prefix_0f" "1")
604 (eq_attr "prefix_extra" "0"))
605 (if_then_else (eq_attr "prefix_vex_w" "1")
606 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
607 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
608 (if_then_else (eq_attr "prefix_vex_w" "1")
609 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
610 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
611
612 ;; 4-bytes evex prefix and 1 byte opcode.
613 (define_attr "length_evex" "" (const_int 5))
614
615 ;; Set when modrm byte is used.
616 (define_attr "modrm" ""
617 (cond [(eq_attr "type" "str,leave")
618 (const_int 0)
619 (eq_attr "unit" "i387")
620 (const_int 0)
621 (and (eq_attr "type" "incdec")
622 (and (not (match_test "TARGET_64BIT"))
623 (ior (match_operand:SI 1 "register_operand")
624 (match_operand:HI 1 "register_operand"))))
625 (const_int 0)
626 (and (eq_attr "type" "push")
627 (not (match_operand 1 "memory_operand")))
628 (const_int 0)
629 (and (eq_attr "type" "pop")
630 (not (match_operand 0 "memory_operand")))
631 (const_int 0)
632 (and (eq_attr "type" "imov")
633 (and (not (eq_attr "mode" "DI"))
634 (ior (and (match_operand 0 "register_operand")
635 (match_operand 1 "immediate_operand"))
636 (ior (and (match_operand 0 "ax_reg_operand")
637 (match_operand 1 "memory_displacement_only_operand"))
638 (and (match_operand 0 "memory_displacement_only_operand")
639 (match_operand 1 "ax_reg_operand"))))))
640 (const_int 0)
641 (and (eq_attr "type" "call")
642 (match_operand 0 "constant_call_address_operand"))
643 (const_int 0)
644 (and (eq_attr "type" "callv")
645 (match_operand 1 "constant_call_address_operand"))
646 (const_int 0)
647 (and (eq_attr "type" "alu,alu1,icmp,test")
648 (match_operand 0 "ax_reg_operand"))
649 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
650 ]
651 (const_int 1)))
652
653 ;; The (bounding maximum) length of an instruction in bytes.
654 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
655 ;; Later we may want to split them and compute proper length as for
656 ;; other insns.
657 (define_attr "length" ""
658 (cond [(eq_attr "type" "other,multi,fistp,frndint")
659 (const_int 16)
660 (eq_attr "type" "fcmp")
661 (const_int 4)
662 (eq_attr "unit" "i387")
663 (plus (const_int 2)
664 (plus (attr "prefix_data16")
665 (attr "length_address")))
666 (ior (eq_attr "prefix" "evex")
667 (and (ior (eq_attr "prefix" "maybe_evex")
668 (eq_attr "prefix" "maybe_vex"))
669 (match_test "TARGET_AVX512F")))
670 (plus (attr "length_evex")
671 (plus (attr "length_immediate")
672 (plus (attr "modrm")
673 (attr "length_address"))))
674 (ior (eq_attr "prefix" "vex")
675 (and (ior (eq_attr "prefix" "maybe_vex")
676 (eq_attr "prefix" "maybe_evex"))
677 (match_test "TARGET_AVX")))
678 (plus (attr "length_vex")
679 (plus (attr "length_immediate")
680 (plus (attr "modrm")
681 (attr "length_address"))))]
682 (plus (plus (attr "modrm")
683 (plus (attr "prefix_0f")
684 (plus (attr "prefix_rex")
685 (plus (attr "prefix_extra")
686 (const_int 1)))))
687 (plus (attr "prefix_rep")
688 (plus (attr "prefix_data16")
689 (plus (attr "length_immediate")
690 (attr "length_address")))))))
691
692 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
693 ;; `store' if there is a simple memory reference therein, or `unknown'
694 ;; if the instruction is complex.
695
696 (define_attr "memory" "none,load,store,both,unknown"
697 (cond [(eq_attr "type" "other,multi,str,lwp")
698 (const_string "unknown")
699 (eq_attr "type" "lea,fcmov,fpspc")
700 (const_string "none")
701 (eq_attr "type" "fistp,leave")
702 (const_string "both")
703 (eq_attr "type" "frndint")
704 (const_string "load")
705 (eq_attr "type" "push")
706 (if_then_else (match_operand 1 "memory_operand")
707 (const_string "both")
708 (const_string "store"))
709 (eq_attr "type" "pop")
710 (if_then_else (match_operand 0 "memory_operand")
711 (const_string "both")
712 (const_string "load"))
713 (eq_attr "type" "setcc")
714 (if_then_else (match_operand 0 "memory_operand")
715 (const_string "store")
716 (const_string "none"))
717 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
718 (if_then_else (ior (match_operand 0 "memory_operand")
719 (match_operand 1 "memory_operand"))
720 (const_string "load")
721 (const_string "none"))
722 (eq_attr "type" "ibr")
723 (if_then_else (match_operand 0 "memory_operand")
724 (const_string "load")
725 (const_string "none"))
726 (eq_attr "type" "call")
727 (if_then_else (match_operand 0 "constant_call_address_operand")
728 (const_string "none")
729 (const_string "load"))
730 (eq_attr "type" "callv")
731 (if_then_else (match_operand 1 "constant_call_address_operand")
732 (const_string "none")
733 (const_string "load"))
734 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
735 (match_operand 1 "memory_operand"))
736 (const_string "both")
737 (and (match_operand 0 "memory_operand")
738 (match_operand 1 "memory_operand"))
739 (const_string "both")
740 (match_operand 0 "memory_operand")
741 (const_string "store")
742 (match_operand 1 "memory_operand")
743 (const_string "load")
744 (and (eq_attr "type"
745 "!alu1,negnot,ishift1,rotate1,
746 imov,imovx,icmp,test,bitmanip,
747 fmov,fcmp,fsgn,
748 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
749 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
750 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
751 (match_operand 2 "memory_operand"))
752 (const_string "load")
753 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
754 (match_operand 3 "memory_operand"))
755 (const_string "load")
756 ]
757 (const_string "none")))
758
759 ;; Indicates if an instruction has both an immediate and a displacement.
760
761 (define_attr "imm_disp" "false,true,unknown"
762 (cond [(eq_attr "type" "other,multi")
763 (const_string "unknown")
764 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
765 (and (match_operand 0 "memory_displacement_operand")
766 (match_operand 1 "immediate_operand")))
767 (const_string "true")
768 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
769 (and (match_operand 0 "memory_displacement_operand")
770 (match_operand 2 "immediate_operand")))
771 (const_string "true")
772 ]
773 (const_string "false")))
774
775 ;; Indicates if an FP operation has an integer source.
776
777 (define_attr "fp_int_src" "false,true"
778 (const_string "false"))
779
780 ;; Defines rounding mode of an FP operation.
781
782 (define_attr "i387_cw" "trunc,floor,ceil,uninitialized,any"
783 (const_string "any"))
784
785 ;; Define attribute to indicate AVX insns with partial XMM register update.
786 (define_attr "avx_partial_xmm_update" "false,true"
787 (const_string "false"))
788
789 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
790 (define_attr "use_carry" "0,1" (const_string "0"))
791
792 ;; Define attribute to indicate unaligned ssemov insns
793 (define_attr "movu" "0,1" (const_string "0"))
794
795 ;; Used to control the "enabled" attribute on a per-instruction basis.
796 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
797 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
798 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
799 avx512bw,noavx512bw,avx512dq,noavx512dq,
800 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
801 (const_string "base"))
802
803 ;; Define instruction set of MMX instructions
804 (define_attr "mmx_isa" "base,native,x64,x64_noavx,x64_avx"
805 (const_string "base"))
806
807 (define_attr "enabled" ""
808 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
809 (eq_attr "isa" "x64_sse2")
810 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
811 (eq_attr "isa" "x64_sse4")
812 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
813 (eq_attr "isa" "x64_sse4_noavx")
814 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
815 (eq_attr "isa" "x64_avx")
816 (symbol_ref "TARGET_64BIT && TARGET_AVX")
817 (eq_attr "isa" "x64_avx512dq")
818 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
819 (eq_attr "isa" "x64_avx512bw")
820 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
821 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
822 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
823 (eq_attr "isa" "sse2_noavx")
824 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
825 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
826 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
827 (eq_attr "isa" "sse4_noavx")
828 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
829 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
830 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
831 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
832 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
833 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
834 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
835 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
836 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
837 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
838 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
839 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
840 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
841 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
842 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
843 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
844 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
845
846 (eq_attr "mmx_isa" "native")
847 (symbol_ref "!TARGET_MMX_WITH_SSE")
848 (eq_attr "mmx_isa" "x64")
849 (symbol_ref "TARGET_MMX_WITH_SSE")
850 (eq_attr "mmx_isa" "x64_avx")
851 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
852 (eq_attr "mmx_isa" "x64_noavx")
853 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
854 ]
855 (const_int 1)))
856
857 (define_attr "preferred_for_size" "" (const_int 1))
858 (define_attr "preferred_for_speed" "" (const_int 1))
859
860 ;; Describe a user's asm statement.
861 (define_asm_attributes
862 [(set_attr "length" "128")
863 (set_attr "type" "multi")])
864
865 (define_code_iterator plusminus [plus minus])
866
867 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
868
869 (define_code_iterator multdiv [mult div])
870
871 ;; Base name for define_insn
872 (define_code_attr plusminus_insn
873 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
874 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
875
876 ;; Base name for insn mnemonic.
877 (define_code_attr plusminus_mnemonic
878 [(plus "add") (ss_plus "adds") (us_plus "addus")
879 (minus "sub") (ss_minus "subs") (us_minus "subus")])
880 (define_code_attr multdiv_mnemonic
881 [(mult "mul") (div "div")])
882
883 ;; Mark commutative operators as such in constraints.
884 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
885 (minus "") (ss_minus "") (us_minus "")])
886
887 ;; Mapping of max and min
888 (define_code_iterator maxmin [smax smin umax umin])
889
890 ;; Mapping of signed max and min
891 (define_code_iterator smaxmin [smax smin])
892
893 ;; Mapping of unsigned max and min
894 (define_code_iterator umaxmin [umax umin])
895
896 ;; Base name for integer and FP insn mnemonic
897 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
898 (umax "maxu") (umin "minu")])
899 (define_code_attr maxmin_float [(smax "max") (smin "min")])
900
901 (define_int_iterator IEEE_MAXMIN
902 [UNSPEC_IEEE_MAX
903 UNSPEC_IEEE_MIN])
904
905 (define_int_attr ieee_maxmin
906 [(UNSPEC_IEEE_MAX "max")
907 (UNSPEC_IEEE_MIN "min")])
908
909 ;; Mapping of logic operators
910 (define_code_iterator any_logic [and ior xor])
911 (define_code_iterator any_or [ior xor])
912 (define_code_iterator fpint_logic [and xor])
913
914 ;; Base name for insn mnemonic.
915 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
916
917 ;; Mapping of logic-shift operators
918 (define_code_iterator any_lshift [ashift lshiftrt])
919
920 ;; Mapping of shift-right operators
921 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
922
923 ;; Mapping of all shift operators
924 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
925
926 ;; Base name for define_insn
927 (define_code_attr shift_insn
928 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
929
930 ;; Base name for insn mnemonic.
931 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
932 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
933
934 ;; Mapping of rotate operators
935 (define_code_iterator any_rotate [rotate rotatert])
936
937 ;; Base name for define_insn
938 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
939
940 ;; Base name for insn mnemonic.
941 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
942
943 ;; Mapping of abs neg operators
944 (define_code_iterator absneg [abs neg])
945
946 ;; Base name for x87 insn mnemonic.
947 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
948
949 ;; Used in signed and unsigned widening multiplications.
950 (define_code_iterator any_extend [sign_extend zero_extend])
951
952 ;; Prefix for insn menmonic.
953 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
954 (div "i") (udiv "")])
955 ;; Prefix for define_insn
956 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
957 (define_code_attr u [(sign_extend "") (zero_extend "u")
958 (div "") (udiv "u")])
959 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
960 (div "false") (udiv "true")])
961
962 ;; Used in signed and unsigned truncations.
963 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
964 ;; Instruction suffix for truncations.
965 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
966
967 ;; Used in signed and unsigned fix.
968 (define_code_iterator any_fix [fix unsigned_fix])
969 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
970 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
971 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
972
973 ;; Used in signed and unsigned float.
974 (define_code_iterator any_float [float unsigned_float])
975 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
976 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
977 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
978
979 ;; All integer modes.
980 (define_mode_iterator SWI1248x [QI HI SI DI])
981
982 ;; All integer modes without QImode.
983 (define_mode_iterator SWI248x [HI SI DI])
984
985 ;; All integer modes without QImode and HImode.
986 (define_mode_iterator SWI48x [SI DI])
987
988 ;; All integer modes without SImode and DImode.
989 (define_mode_iterator SWI12 [QI HI])
990
991 ;; All integer modes without DImode.
992 (define_mode_iterator SWI124 [QI HI SI])
993
994 ;; All integer modes without QImode and DImode.
995 (define_mode_iterator SWI24 [HI SI])
996
997 ;; Single word integer modes.
998 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
999
1000 ;; Single word integer modes without QImode.
1001 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1002
1003 ;; Single word integer modes without QImode and HImode.
1004 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1005
1006 ;; All math-dependant single and double word integer modes.
1007 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1008 (HI "TARGET_HIMODE_MATH")
1009 SI DI (TI "TARGET_64BIT")])
1010
1011 ;; Math-dependant single word integer modes.
1012 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1013 (HI "TARGET_HIMODE_MATH")
1014 SI (DI "TARGET_64BIT")])
1015
1016 ;; Math-dependant integer modes without DImode.
1017 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1018 (HI "TARGET_HIMODE_MATH")
1019 SI])
1020
1021 ;; Math-dependant integer modes with DImode (enabled for 32bit with STV).
1022 (define_mode_iterator SWIM1248s
1023 [(QI "TARGET_QIMODE_MATH")
1024 (HI "TARGET_HIMODE_MATH")
1025 SI (DI "TARGET_64BIT || (TARGET_STV && TARGET_SSE2)")])
1026
1027 ;; Math-dependant single word integer modes without QImode.
1028 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1029 SI (DI "TARGET_64BIT")])
1030
1031 ;; Double word integer modes.
1032 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1033 (TI "TARGET_64BIT")])
1034
1035 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1036 ;; compile time constant, it is faster to use <MODE_SIZE> than
1037 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1038 ;; command line options just use GET_MODE_SIZE macro.
1039 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1040 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1041 (V16QI "16") (V32QI "32") (V64QI "64")
1042 (V8HI "16") (V16HI "32") (V32HI "64")
1043 (V4SI "16") (V8SI "32") (V16SI "64")
1044 (V2DI "16") (V4DI "32") (V8DI "64")
1045 (V1TI "16") (V2TI "32") (V4TI "64")
1046 (V2DF "16") (V4DF "32") (V8DF "64")
1047 (V4SF "16") (V8SF "32") (V16SF "64")])
1048
1049 ;; Double word integer modes as mode attribute.
1050 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1051 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1052
1053 ;; LEA mode corresponding to an integer mode
1054 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1055
1056 ;; Half mode for double word integer modes.
1057 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1058 (DI "TARGET_64BIT")])
1059
1060 ;; Instruction suffix for integer modes.
1061 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1062
1063 ;; Instruction suffix for masks.
1064 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1065
1066 ;; Pointer size prefix for integer modes (Intel asm dialect)
1067 (define_mode_attr iptrsize [(QI "BYTE")
1068 (HI "WORD")
1069 (SI "DWORD")
1070 (DI "QWORD")])
1071
1072 ;; Register class for integer modes.
1073 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1074
1075 ;; Immediate operand constraint for integer modes.
1076 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1077
1078 ;; General operand constraint for word modes.
1079 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1080
1081 ;; Immediate operand constraint for double integer modes.
1082 (define_mode_attr di [(SI "nF") (DI "Wd")])
1083
1084 ;; Immediate operand constraint for shifts.
1085 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1086
1087 ;; Print register name in the specified mode.
1088 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1089
1090 ;; General operand predicate for integer modes.
1091 (define_mode_attr general_operand
1092 [(QI "general_operand")
1093 (HI "general_operand")
1094 (SI "x86_64_general_operand")
1095 (DI "x86_64_general_operand")
1096 (TI "x86_64_general_operand")])
1097
1098 ;; General operand predicate for integer modes, where for TImode
1099 ;; we need both words of the operand to be general operands.
1100 (define_mode_attr general_hilo_operand
1101 [(QI "general_operand")
1102 (HI "general_operand")
1103 (SI "x86_64_general_operand")
1104 (DI "x86_64_general_operand")
1105 (TI "x86_64_hilo_general_operand")])
1106
1107 ;; General sign extend operand predicate for integer modes,
1108 ;; which disallows VOIDmode operands and thus it is suitable
1109 ;; for use inside sign_extend.
1110 (define_mode_attr general_sext_operand
1111 [(QI "sext_operand")
1112 (HI "sext_operand")
1113 (SI "x86_64_sext_operand")
1114 (DI "x86_64_sext_operand")])
1115
1116 ;; General sign/zero extend operand predicate for integer modes.
1117 (define_mode_attr general_szext_operand
1118 [(QI "general_operand")
1119 (HI "general_operand")
1120 (SI "x86_64_szext_general_operand")
1121 (DI "x86_64_szext_general_operand")])
1122
1123 ;; Immediate operand predicate for integer modes.
1124 (define_mode_attr immediate_operand
1125 [(QI "immediate_operand")
1126 (HI "immediate_operand")
1127 (SI "x86_64_immediate_operand")
1128 (DI "x86_64_immediate_operand")])
1129
1130 ;; Nonmemory operand predicate for integer modes.
1131 (define_mode_attr nonmemory_operand
1132 [(QI "nonmemory_operand")
1133 (HI "nonmemory_operand")
1134 (SI "x86_64_nonmemory_operand")
1135 (DI "x86_64_nonmemory_operand")])
1136
1137 ;; Operand predicate for shifts.
1138 (define_mode_attr shift_operand
1139 [(QI "nonimmediate_operand")
1140 (HI "nonimmediate_operand")
1141 (SI "nonimmediate_operand")
1142 (DI "shiftdi_operand")
1143 (TI "register_operand")])
1144
1145 ;; Operand predicate for shift argument.
1146 (define_mode_attr shift_immediate_operand
1147 [(QI "const_1_to_31_operand")
1148 (HI "const_1_to_31_operand")
1149 (SI "const_1_to_31_operand")
1150 (DI "const_1_to_63_operand")])
1151
1152 ;; Input operand predicate for arithmetic left shifts.
1153 (define_mode_attr ashl_input_operand
1154 [(QI "nonimmediate_operand")
1155 (HI "nonimmediate_operand")
1156 (SI "nonimmediate_operand")
1157 (DI "ashldi_input_operand")
1158 (TI "reg_or_pm1_operand")])
1159
1160 ;; SSE and x87 SFmode and DFmode floating point modes
1161 (define_mode_iterator MODEF [SF DF])
1162
1163 ;; All x87 floating point modes
1164 (define_mode_iterator X87MODEF [SF DF XF])
1165
1166 ;; All SSE floating point modes
1167 (define_mode_iterator SSEMODEF [SF DF TF])
1168 (define_mode_attr ssevecmodef [(SF "V4SF") (DF "V2DF") (TF "TF")])
1169
1170 ;; SSE instruction suffix for various modes
1171 (define_mode_attr ssemodesuffix
1172 [(SF "ss") (DF "sd")
1173 (V16SF "ps") (V8DF "pd")
1174 (V8SF "ps") (V4DF "pd")
1175 (V4SF "ps") (V2DF "pd")
1176 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1177 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1178 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1179
1180 ;; SSE vector suffix for floating point modes
1181 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1182
1183 ;; SSE vector mode corresponding to a scalar mode
1184 (define_mode_attr ssevecmode
1185 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1186 (define_mode_attr ssevecmodelower
1187 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1188
1189 ;; AVX512F vector mode corresponding to a scalar mode
1190 (define_mode_attr avx512fvecmode
1191 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1192
1193 ;; Instruction suffix for REX 64bit operators.
1194 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1195 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1196
1197 ;; This mode iterator allows :P to be used for patterns that operate on
1198 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1199 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1200
1201 ;; This mode iterator allows :W to be used for patterns that operate on
1202 ;; word_mode sized quantities.
1203 (define_mode_iterator W
1204 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1205
1206 ;; This mode iterator allows :PTR to be used for patterns that operate on
1207 ;; ptr_mode sized quantities.
1208 (define_mode_iterator PTR
1209 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1210 \f
1211 ;; Scheduling descriptions
1212
1213 (include "pentium.md")
1214 (include "ppro.md")
1215 (include "k6.md")
1216 (include "athlon.md")
1217 (include "bdver1.md")
1218 (include "bdver3.md")
1219 (include "btver2.md")
1220 (include "znver1.md")
1221 (include "geode.md")
1222 (include "atom.md")
1223 (include "slm.md")
1224 (include "glm.md")
1225 (include "core2.md")
1226 (include "haswell.md")
1227
1228 \f
1229 ;; Operand and operator predicates and constraints
1230
1231 (include "predicates.md")
1232 (include "constraints.md")
1233
1234 \f
1235 ;; Compare and branch/compare and store instructions.
1236
1237 (define_expand "cbranch<mode>4"
1238 [(set (reg:CC FLAGS_REG)
1239 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1240 (match_operand:SDWIM 2 "<general_operand>")))
1241 (set (pc) (if_then_else
1242 (match_operator 0 "ordered_comparison_operator"
1243 [(reg:CC FLAGS_REG) (const_int 0)])
1244 (label_ref (match_operand 3))
1245 (pc)))]
1246 ""
1247 {
1248 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1249 operands[1] = force_reg (<MODE>mode, operands[1]);
1250 ix86_expand_branch (GET_CODE (operands[0]),
1251 operands[1], operands[2], operands[3]);
1252 DONE;
1253 })
1254
1255 (define_expand "cstore<mode>4"
1256 [(set (reg:CC FLAGS_REG)
1257 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1258 (match_operand:SWIM 3 "<general_operand>")))
1259 (set (match_operand:QI 0 "register_operand")
1260 (match_operator 1 "ordered_comparison_operator"
1261 [(reg:CC FLAGS_REG) (const_int 0)]))]
1262 ""
1263 {
1264 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1265 operands[2] = force_reg (<MODE>mode, operands[2]);
1266 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1267 operands[2], operands[3]);
1268 DONE;
1269 })
1270
1271 (define_expand "cmp<mode>_1"
1272 [(set (reg:CC FLAGS_REG)
1273 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1274 (match_operand:SWI48 1 "<general_operand>")))])
1275
1276 (define_mode_iterator SWI1248_AVX512BWDQ_64
1277 [(QI "TARGET_AVX512DQ") HI
1278 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1279
1280 (define_insn "*cmp<mode>_ccz_1"
1281 [(set (reg FLAGS_REG)
1282 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1283 "nonimmediate_operand" "<r>,?m<r>,$k")
1284 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1285 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1286 "@
1287 test{<imodesuffix>}\t%0, %0
1288 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1289 kortest<mskmodesuffix>\t%0, %0"
1290 [(set_attr "type" "test,icmp,msklog")
1291 (set_attr "length_immediate" "0,1,*")
1292 (set_attr "prefix" "*,*,vex")
1293 (set_attr "mode" "<MODE>")])
1294
1295 (define_insn "*cmp<mode>_ccno_1"
1296 [(set (reg FLAGS_REG)
1297 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1298 (match_operand:SWI 1 "const0_operand")))]
1299 "ix86_match_ccmode (insn, CCNOmode)"
1300 "@
1301 test{<imodesuffix>}\t%0, %0
1302 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1303 [(set_attr "type" "test,icmp")
1304 (set_attr "length_immediate" "0,1")
1305 (set_attr "mode" "<MODE>")])
1306
1307 (define_insn "*cmp<mode>_1"
1308 [(set (reg FLAGS_REG)
1309 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1310 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1311 "ix86_match_ccmode (insn, CCmode)"
1312 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1313 [(set_attr "type" "icmp")
1314 (set_attr "mode" "<MODE>")])
1315
1316 (define_insn "*cmp<mode>_minus_1"
1317 [(set (reg FLAGS_REG)
1318 (compare
1319 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1320 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1321 (const_int 0)))]
1322 "ix86_match_ccmode (insn, CCGOCmode)"
1323 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1324 [(set_attr "type" "icmp")
1325 (set_attr "mode" "<MODE>")])
1326
1327 (define_insn "*cmpqi_ext_1"
1328 [(set (reg FLAGS_REG)
1329 (compare
1330 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1331 (subreg:QI
1332 (zero_extract:SI
1333 (match_operand 1 "ext_register_operand" "Q,Q")
1334 (const_int 8)
1335 (const_int 8)) 0)))]
1336 "ix86_match_ccmode (insn, CCmode)"
1337 "cmp{b}\t{%h1, %0|%0, %h1}"
1338 [(set_attr "isa" "*,nox64")
1339 (set_attr "type" "icmp")
1340 (set_attr "mode" "QI")])
1341
1342 (define_insn "*cmpqi_ext_2"
1343 [(set (reg FLAGS_REG)
1344 (compare
1345 (subreg:QI
1346 (zero_extract:SI
1347 (match_operand 0 "ext_register_operand" "Q")
1348 (const_int 8)
1349 (const_int 8)) 0)
1350 (match_operand:QI 1 "const0_operand")))]
1351 "ix86_match_ccmode (insn, CCNOmode)"
1352 "test{b}\t%h0, %h0"
1353 [(set_attr "type" "test")
1354 (set_attr "length_immediate" "0")
1355 (set_attr "mode" "QI")])
1356
1357 (define_expand "cmpqi_ext_3"
1358 [(set (reg:CC FLAGS_REG)
1359 (compare:CC
1360 (subreg:QI
1361 (zero_extract:SI
1362 (match_operand 0 "ext_register_operand")
1363 (const_int 8)
1364 (const_int 8)) 0)
1365 (match_operand:QI 1 "const_int_operand")))])
1366
1367 (define_insn "*cmpqi_ext_3"
1368 [(set (reg FLAGS_REG)
1369 (compare
1370 (subreg:QI
1371 (zero_extract:SI
1372 (match_operand 0 "ext_register_operand" "Q,Q")
1373 (const_int 8)
1374 (const_int 8)) 0)
1375 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1376 "ix86_match_ccmode (insn, CCmode)"
1377 "cmp{b}\t{%1, %h0|%h0, %1}"
1378 [(set_attr "isa" "*,nox64")
1379 (set_attr "type" "icmp")
1380 (set_attr "mode" "QI")])
1381
1382 (define_insn "*cmpqi_ext_4"
1383 [(set (reg FLAGS_REG)
1384 (compare
1385 (subreg:QI
1386 (zero_extract:SI
1387 (match_operand 0 "ext_register_operand" "Q")
1388 (const_int 8)
1389 (const_int 8)) 0)
1390 (subreg:QI
1391 (zero_extract:SI
1392 (match_operand 1 "ext_register_operand" "Q")
1393 (const_int 8)
1394 (const_int 8)) 0)))]
1395 "ix86_match_ccmode (insn, CCmode)"
1396 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1397 [(set_attr "type" "icmp")
1398 (set_attr "mode" "QI")])
1399
1400 ;; These implement float point compares.
1401 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1402 ;; which would allow mix and match FP modes on the compares. Which is what
1403 ;; the old patterns did, but with many more of them.
1404
1405 (define_expand "cbranchxf4"
1406 [(set (reg:CC FLAGS_REG)
1407 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1408 (match_operand:XF 2 "nonmemory_operand")))
1409 (set (pc) (if_then_else
1410 (match_operator 0 "ix86_fp_comparison_operator"
1411 [(reg:CC FLAGS_REG)
1412 (const_int 0)])
1413 (label_ref (match_operand 3))
1414 (pc)))]
1415 "TARGET_80387"
1416 {
1417 ix86_expand_branch (GET_CODE (operands[0]),
1418 operands[1], operands[2], operands[3]);
1419 DONE;
1420 })
1421
1422 (define_expand "cstorexf4"
1423 [(set (reg:CC FLAGS_REG)
1424 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1425 (match_operand:XF 3 "nonmemory_operand")))
1426 (set (match_operand:QI 0 "register_operand")
1427 (match_operator 1 "ix86_fp_comparison_operator"
1428 [(reg:CC FLAGS_REG)
1429 (const_int 0)]))]
1430 "TARGET_80387"
1431 {
1432 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1433 operands[2], operands[3]);
1434 DONE;
1435 })
1436
1437 (define_expand "cbranch<mode>4"
1438 [(set (reg:CC FLAGS_REG)
1439 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1440 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1441 (set (pc) (if_then_else
1442 (match_operator 0 "ix86_fp_comparison_operator"
1443 [(reg:CC FLAGS_REG)
1444 (const_int 0)])
1445 (label_ref (match_operand 3))
1446 (pc)))]
1447 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1448 {
1449 ix86_expand_branch (GET_CODE (operands[0]),
1450 operands[1], operands[2], operands[3]);
1451 DONE;
1452 })
1453
1454 (define_expand "cstore<mode>4"
1455 [(set (reg:CC FLAGS_REG)
1456 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1457 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1458 (set (match_operand:QI 0 "register_operand")
1459 (match_operator 1 "ix86_fp_comparison_operator"
1460 [(reg:CC FLAGS_REG)
1461 (const_int 0)]))]
1462 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1463 {
1464 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1465 operands[2], operands[3]);
1466 DONE;
1467 })
1468
1469 (define_expand "cbranchcc4"
1470 [(set (pc) (if_then_else
1471 (match_operator 0 "comparison_operator"
1472 [(match_operand 1 "flags_reg_operand")
1473 (match_operand 2 "const0_operand")])
1474 (label_ref (match_operand 3))
1475 (pc)))]
1476 ""
1477 {
1478 ix86_expand_branch (GET_CODE (operands[0]),
1479 operands[1], operands[2], operands[3]);
1480 DONE;
1481 })
1482
1483 (define_expand "cstorecc4"
1484 [(set (match_operand:QI 0 "register_operand")
1485 (match_operator 1 "comparison_operator"
1486 [(match_operand 2 "flags_reg_operand")
1487 (match_operand 3 "const0_operand")]))]
1488 ""
1489 {
1490 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1491 operands[2], operands[3]);
1492 DONE;
1493 })
1494
1495 ;; FP compares, step 1:
1496 ;; Set the FP condition codes and move fpsr to ax.
1497
1498 ;; We may not use "#" to split and emit these
1499 ;; due to reg-stack pops killing fpsr.
1500
1501 (define_insn "*cmpxf_i387"
1502 [(set (match_operand:HI 0 "register_operand" "=a")
1503 (unspec:HI
1504 [(compare:CCFP
1505 (match_operand:XF 1 "register_operand" "f")
1506 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1507 UNSPEC_FNSTSW))]
1508 "TARGET_80387"
1509 "* return output_fp_compare (insn, operands, false, false);"
1510 [(set_attr "type" "multi")
1511 (set_attr "unit" "i387")
1512 (set_attr "mode" "XF")])
1513
1514 (define_insn "*cmp<mode>_i387"
1515 [(set (match_operand:HI 0 "register_operand" "=a")
1516 (unspec:HI
1517 [(compare:CCFP
1518 (match_operand:MODEF 1 "register_operand" "f")
1519 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1520 UNSPEC_FNSTSW))]
1521 "TARGET_80387"
1522 "* return output_fp_compare (insn, operands, false, false);"
1523 [(set_attr "type" "multi")
1524 (set_attr "unit" "i387")
1525 (set_attr "mode" "<MODE>")])
1526
1527 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1528 [(set (match_operand:HI 0 "register_operand" "=a")
1529 (unspec:HI
1530 [(compare:CCFP
1531 (match_operand:X87MODEF 1 "register_operand" "f")
1532 (float:X87MODEF
1533 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1534 UNSPEC_FNSTSW))]
1535 "TARGET_80387
1536 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1537 || optimize_function_for_size_p (cfun))"
1538 "* return output_fp_compare (insn, operands, false, false);"
1539 [(set_attr "type" "multi")
1540 (set_attr "unit" "i387")
1541 (set_attr "fp_int_src" "true")
1542 (set_attr "mode" "<SWI24:MODE>")])
1543
1544 (define_insn "*cmpu<mode>_i387"
1545 [(set (match_operand:HI 0 "register_operand" "=a")
1546 (unspec:HI
1547 [(unspec:CCFP
1548 [(compare:CCFP
1549 (match_operand:X87MODEF 1 "register_operand" "f")
1550 (match_operand:X87MODEF 2 "register_operand" "f"))]
1551 UNSPEC_NOTRAP)]
1552 UNSPEC_FNSTSW))]
1553 "TARGET_80387"
1554 "* return output_fp_compare (insn, operands, false, true);"
1555 [(set_attr "type" "multi")
1556 (set_attr "unit" "i387")
1557 (set_attr "mode" "<MODE>")])
1558
1559 ;; FP compares, step 2:
1560 ;; Get ax into flags, general case.
1561
1562 (define_insn "x86_sahf_1"
1563 [(set (reg:CC FLAGS_REG)
1564 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1565 UNSPEC_SAHF))]
1566 "TARGET_SAHF"
1567 {
1568 #ifndef HAVE_AS_IX86_SAHF
1569 if (TARGET_64BIT)
1570 return ASM_BYTE "0x9e";
1571 else
1572 #endif
1573 return "sahf";
1574 }
1575 [(set_attr "length" "1")
1576 (set_attr "athlon_decode" "vector")
1577 (set_attr "amdfam10_decode" "direct")
1578 (set_attr "bdver1_decode" "direct")
1579 (set_attr "mode" "SI")])
1580
1581 ;; Pentium Pro can do both steps in one go.
1582 ;; (these instructions set flags directly)
1583
1584 (define_subst_attr "unord" "unord_subst" "" "u")
1585 (define_subst_attr "unordered" "unord_subst" "false" "true")
1586
1587 (define_subst "unord_subst"
1588 [(set (match_operand:CCFP 0)
1589 (match_operand:CCFP 1))]
1590 ""
1591 [(set (match_dup 0)
1592 (unspec:CCFP
1593 [(match_dup 1)]
1594 UNSPEC_NOTRAP))])
1595
1596 (define_insn "*cmpi<unord>xf_i387"
1597 [(set (reg:CCFP FLAGS_REG)
1598 (compare:CCFP
1599 (match_operand:XF 0 "register_operand" "f")
1600 (match_operand:XF 1 "register_operand" "f")))]
1601 "TARGET_80387 && TARGET_CMOVE"
1602 "* return output_fp_compare (insn, operands, true, <unordered>);"
1603 [(set_attr "type" "fcmp")
1604 (set_attr "mode" "XF")
1605 (set_attr "athlon_decode" "vector")
1606 (set_attr "amdfam10_decode" "direct")
1607 (set_attr "bdver1_decode" "double")
1608 (set_attr "znver1_decode" "double")])
1609
1610 (define_insn "*cmpi<unord><MODEF:mode>"
1611 [(set (reg:CCFP FLAGS_REG)
1612 (compare:CCFP
1613 (match_operand:MODEF 0 "register_operand" "f,v")
1614 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1615 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1616 || (TARGET_80387 && TARGET_CMOVE)"
1617 "@
1618 * return output_fp_compare (insn, operands, true, <unordered>);
1619 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1620 [(set_attr "type" "fcmp,ssecomi")
1621 (set_attr "prefix" "orig,maybe_vex")
1622 (set_attr "mode" "<MODEF:MODE>")
1623 (set_attr "prefix_rep" "*,0")
1624 (set (attr "prefix_data16")
1625 (cond [(eq_attr "alternative" "0")
1626 (const_string "*")
1627 (eq_attr "mode" "DF")
1628 (const_string "1")
1629 ]
1630 (const_string "0")))
1631 (set_attr "athlon_decode" "vector")
1632 (set_attr "amdfam10_decode" "direct")
1633 (set_attr "bdver1_decode" "double")
1634 (set_attr "znver1_decode" "double")
1635 (set (attr "enabled")
1636 (if_then_else
1637 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1638 (if_then_else
1639 (eq_attr "alternative" "0")
1640 (symbol_ref "TARGET_MIX_SSE_I387")
1641 (symbol_ref "true"))
1642 (if_then_else
1643 (eq_attr "alternative" "0")
1644 (symbol_ref "true")
1645 (symbol_ref "false"))))])
1646 \f
1647 ;; Push/pop instructions.
1648
1649 (define_insn "*push<mode>2"
1650 [(set (match_operand:DWI 0 "push_operand" "=<")
1651 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1652 ""
1653 "#"
1654 [(set_attr "type" "multi")
1655 (set_attr "mode" "<MODE>")])
1656
1657 (define_split
1658 [(set (match_operand:DWI 0 "push_operand")
1659 (match_operand:DWI 1 "general_gr_operand"))]
1660 "reload_completed"
1661 [(const_int 0)]
1662 "ix86_split_long_move (operands); DONE;")
1663
1664 (define_insn "*pushdi2_rex64"
1665 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1666 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1667 "TARGET_64BIT"
1668 "@
1669 push{q}\t%1
1670 #"
1671 [(set_attr "type" "push,multi")
1672 (set_attr "mode" "DI")])
1673
1674 ;; Convert impossible pushes of immediate to existing instructions.
1675 ;; First try to get scratch register and go through it. In case this
1676 ;; fails, push sign extended lower part first and then overwrite
1677 ;; upper part by 32bit move.
1678 (define_peephole2
1679 [(match_scratch:DI 2 "r")
1680 (set (match_operand:DI 0 "push_operand")
1681 (match_operand:DI 1 "immediate_operand"))]
1682 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1683 && !x86_64_immediate_operand (operands[1], DImode)"
1684 [(set (match_dup 2) (match_dup 1))
1685 (set (match_dup 0) (match_dup 2))])
1686
1687 ;; We need to define this as both peepholer and splitter for case
1688 ;; peephole2 pass is not run.
1689 ;; "&& 1" is needed to keep it from matching the previous pattern.
1690 (define_peephole2
1691 [(set (match_operand:DI 0 "push_operand")
1692 (match_operand:DI 1 "immediate_operand"))]
1693 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1694 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1695 [(set (match_dup 0) (match_dup 1))
1696 (set (match_dup 2) (match_dup 3))]
1697 {
1698 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1699
1700 operands[1] = gen_lowpart (DImode, operands[2]);
1701 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1702 GEN_INT (4)));
1703 })
1704
1705 (define_split
1706 [(set (match_operand:DI 0 "push_operand")
1707 (match_operand:DI 1 "immediate_operand"))]
1708 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1709 ? epilogue_completed : reload_completed)
1710 && !symbolic_operand (operands[1], DImode)
1711 && !x86_64_immediate_operand (operands[1], DImode)"
1712 [(set (match_dup 0) (match_dup 1))
1713 (set (match_dup 2) (match_dup 3))]
1714 {
1715 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1716
1717 operands[1] = gen_lowpart (DImode, operands[2]);
1718 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1719 GEN_INT (4)));
1720 })
1721
1722 (define_insn "*pushsi2"
1723 [(set (match_operand:SI 0 "push_operand" "=<")
1724 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1725 "!TARGET_64BIT"
1726 "push{l}\t%1"
1727 [(set_attr "type" "push")
1728 (set_attr "mode" "SI")])
1729
1730 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1731 ;; "push a byte/word". But actually we use pushl, which has the effect
1732 ;; of rounding the amount pushed up to a word.
1733
1734 ;; For TARGET_64BIT we always round up to 8 bytes.
1735 (define_insn "*push<mode>2_rex64"
1736 [(set (match_operand:SWI124 0 "push_operand" "=X")
1737 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1738 "TARGET_64BIT"
1739 "push{q}\t%q1"
1740 [(set_attr "type" "push")
1741 (set_attr "mode" "DI")])
1742
1743 (define_insn "*push<mode>2"
1744 [(set (match_operand:SWI12 0 "push_operand" "=X")
1745 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1746 "!TARGET_64BIT"
1747 "push{l}\t%k1"
1748 [(set_attr "type" "push")
1749 (set_attr "mode" "SI")])
1750
1751 (define_insn "*push<mode>2_prologue"
1752 [(set (match_operand:W 0 "push_operand" "=<")
1753 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1754 (clobber (mem:BLK (scratch)))]
1755 ""
1756 "push{<imodesuffix>}\t%1"
1757 [(set_attr "type" "push")
1758 (set_attr "mode" "<MODE>")])
1759
1760 (define_insn "*pop<mode>1"
1761 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1762 (match_operand:W 1 "pop_operand" ">"))]
1763 ""
1764 "pop{<imodesuffix>}\t%0"
1765 [(set_attr "type" "pop")
1766 (set_attr "mode" "<MODE>")])
1767
1768 (define_insn "*pop<mode>1_epilogue"
1769 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1770 (match_operand:W 1 "pop_operand" ">"))
1771 (clobber (mem:BLK (scratch)))]
1772 ""
1773 "pop{<imodesuffix>}\t%0"
1774 [(set_attr "type" "pop")
1775 (set_attr "mode" "<MODE>")])
1776
1777 (define_insn "*pushfl<mode>2"
1778 [(set (match_operand:W 0 "push_operand" "=<")
1779 (match_operand:W 1 "flags_reg_operand"))]
1780 ""
1781 "pushf{<imodesuffix>}"
1782 [(set_attr "type" "push")
1783 (set_attr "mode" "<MODE>")])
1784
1785 (define_insn "*popfl<mode>1"
1786 [(set (match_operand:W 0 "flags_reg_operand")
1787 (match_operand:W 1 "pop_operand" ">"))]
1788 ""
1789 "popf{<imodesuffix>}"
1790 [(set_attr "type" "pop")
1791 (set_attr "mode" "<MODE>")])
1792
1793 \f
1794 ;; Reload patterns to support multi-word load/store
1795 ;; with non-offsetable address.
1796 (define_expand "reload_noff_store"
1797 [(parallel [(match_operand 0 "memory_operand" "=m")
1798 (match_operand 1 "register_operand" "r")
1799 (match_operand:DI 2 "register_operand" "=&r")])]
1800 "TARGET_64BIT"
1801 {
1802 rtx mem = operands[0];
1803 rtx addr = XEXP (mem, 0);
1804
1805 emit_move_insn (operands[2], addr);
1806 mem = replace_equiv_address_nv (mem, operands[2]);
1807
1808 emit_insn (gen_rtx_SET (mem, operands[1]));
1809 DONE;
1810 })
1811
1812 (define_expand "reload_noff_load"
1813 [(parallel [(match_operand 0 "register_operand" "=r")
1814 (match_operand 1 "memory_operand" "m")
1815 (match_operand:DI 2 "register_operand" "=r")])]
1816 "TARGET_64BIT"
1817 {
1818 rtx mem = operands[1];
1819 rtx addr = XEXP (mem, 0);
1820
1821 emit_move_insn (operands[2], addr);
1822 mem = replace_equiv_address_nv (mem, operands[2]);
1823
1824 emit_insn (gen_rtx_SET (operands[0], mem));
1825 DONE;
1826 })
1827
1828 ;; Move instructions.
1829
1830 (define_expand "movxi"
1831 [(set (match_operand:XI 0 "nonimmediate_operand")
1832 (match_operand:XI 1 "general_operand"))]
1833 "TARGET_AVX512F"
1834 "ix86_expand_vector_move (XImode, operands); DONE;")
1835
1836 (define_expand "movoi"
1837 [(set (match_operand:OI 0 "nonimmediate_operand")
1838 (match_operand:OI 1 "general_operand"))]
1839 "TARGET_AVX"
1840 "ix86_expand_vector_move (OImode, operands); DONE;")
1841
1842 (define_expand "movti"
1843 [(set (match_operand:TI 0 "nonimmediate_operand")
1844 (match_operand:TI 1 "general_operand"))]
1845 "TARGET_64BIT || TARGET_SSE"
1846 {
1847 if (TARGET_64BIT)
1848 ix86_expand_move (TImode, operands);
1849 else
1850 ix86_expand_vector_move (TImode, operands);
1851 DONE;
1852 })
1853
1854 ;; This expands to what emit_move_complex would generate if we didn't
1855 ;; have a movti pattern. Having this avoids problems with reload on
1856 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1857 ;; to have around all the time.
1858 (define_expand "movcdi"
1859 [(set (match_operand:CDI 0 "nonimmediate_operand")
1860 (match_operand:CDI 1 "general_operand"))]
1861 ""
1862 {
1863 if (push_operand (operands[0], CDImode))
1864 emit_move_complex_push (CDImode, operands[0], operands[1]);
1865 else
1866 emit_move_complex_parts (operands[0], operands[1]);
1867 DONE;
1868 })
1869
1870 (define_expand "mov<mode>"
1871 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1872 (match_operand:SWI1248x 1 "general_operand"))]
1873 ""
1874 "ix86_expand_move (<MODE>mode, operands); DONE;")
1875
1876 (define_insn "*mov<mode>_xor"
1877 [(set (match_operand:SWI48 0 "register_operand" "=r")
1878 (match_operand:SWI48 1 "const0_operand"))
1879 (clobber (reg:CC FLAGS_REG))]
1880 "reload_completed"
1881 "xor{l}\t%k0, %k0"
1882 [(set_attr "type" "alu1")
1883 (set_attr "mode" "SI")
1884 (set_attr "length_immediate" "0")])
1885
1886 (define_insn "*mov<mode>_or"
1887 [(set (match_operand:SWI48 0 "register_operand" "=r")
1888 (match_operand:SWI48 1 "constm1_operand"))
1889 (clobber (reg:CC FLAGS_REG))]
1890 "reload_completed"
1891 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1892 [(set_attr "type" "alu1")
1893 (set_attr "mode" "<MODE>")
1894 (set_attr "length_immediate" "1")])
1895
1896 (define_insn "*movxi_internal_avx512f"
1897 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
1898 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1899 "TARGET_AVX512F
1900 && (register_operand (operands[0], XImode)
1901 || register_operand (operands[1], XImode))"
1902 {
1903 switch (get_attr_type (insn))
1904 {
1905 case TYPE_SSELOG1:
1906 return standard_sse_constant_opcode (insn, operands);
1907
1908 case TYPE_SSEMOV:
1909 if (misaligned_operand (operands[0], XImode)
1910 || misaligned_operand (operands[1], XImode))
1911 return "vmovdqu32\t{%1, %0|%0, %1}";
1912 else
1913 return "vmovdqa32\t{%1, %0|%0, %1}";
1914
1915 default:
1916 gcc_unreachable ();
1917 }
1918 }
1919 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1920 (set_attr "prefix" "evex")
1921 (set_attr "mode" "XI")])
1922
1923 (define_insn "*movoi_internal_avx"
1924 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
1925 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1926 "TARGET_AVX
1927 && (register_operand (operands[0], OImode)
1928 || register_operand (operands[1], OImode))"
1929 {
1930 switch (get_attr_type (insn))
1931 {
1932 case TYPE_SSELOG1:
1933 return standard_sse_constant_opcode (insn, operands);
1934
1935 case TYPE_SSEMOV:
1936 if (misaligned_operand (operands[0], OImode)
1937 || misaligned_operand (operands[1], OImode))
1938 {
1939 if (get_attr_mode (insn) == MODE_V8SF)
1940 return "vmovups\t{%1, %0|%0, %1}";
1941 else if (get_attr_mode (insn) == MODE_XI)
1942 return "vmovdqu32\t{%1, %0|%0, %1}";
1943 else
1944 return "vmovdqu\t{%1, %0|%0, %1}";
1945 }
1946 else
1947 {
1948 if (get_attr_mode (insn) == MODE_V8SF)
1949 return "vmovaps\t{%1, %0|%0, %1}";
1950 else if (get_attr_mode (insn) == MODE_XI)
1951 return "vmovdqa32\t{%1, %0|%0, %1}";
1952 else
1953 return "vmovdqa\t{%1, %0|%0, %1}";
1954 }
1955
1956 default:
1957 gcc_unreachable ();
1958 }
1959 }
1960 [(set_attr "isa" "*,avx2,*,*")
1961 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1962 (set_attr "prefix" "vex")
1963 (set (attr "mode")
1964 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1965 (match_operand 1 "ext_sse_reg_operand"))
1966 (const_string "XI")
1967 (and (eq_attr "alternative" "1")
1968 (match_test "TARGET_AVX512VL"))
1969 (const_string "XI")
1970 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1971 (and (eq_attr "alternative" "3")
1972 (match_test "TARGET_SSE_TYPELESS_STORES")))
1973 (const_string "V8SF")
1974 ]
1975 (const_string "OI")))])
1976
1977 (define_insn "*movti_internal"
1978 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
1979 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
1980 "(TARGET_64BIT
1981 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
1982 || (TARGET_SSE
1983 && nonimmediate_or_sse_const_operand (operands[1], TImode)
1984 && (register_operand (operands[0], TImode)
1985 || register_operand (operands[1], TImode)))"
1986 {
1987 switch (get_attr_type (insn))
1988 {
1989 case TYPE_MULTI:
1990 return "#";
1991
1992 case TYPE_SSELOG1:
1993 return standard_sse_constant_opcode (insn, operands);
1994
1995 case TYPE_SSEMOV:
1996 /* TDmode values are passed as TImode on the stack. Moving them
1997 to stack may result in unaligned memory access. */
1998 if (misaligned_operand (operands[0], TImode)
1999 || misaligned_operand (operands[1], TImode))
2000 {
2001 if (get_attr_mode (insn) == MODE_V4SF)
2002 return "%vmovups\t{%1, %0|%0, %1}";
2003 else if (get_attr_mode (insn) == MODE_XI)
2004 return "vmovdqu32\t{%1, %0|%0, %1}";
2005 else
2006 return "%vmovdqu\t{%1, %0|%0, %1}";
2007 }
2008 else
2009 {
2010 if (get_attr_mode (insn) == MODE_V4SF)
2011 return "%vmovaps\t{%1, %0|%0, %1}";
2012 else if (get_attr_mode (insn) == MODE_XI)
2013 return "vmovdqa32\t{%1, %0|%0, %1}";
2014 else
2015 return "%vmovdqa\t{%1, %0|%0, %1}";
2016 }
2017
2018 default:
2019 gcc_unreachable ();
2020 }
2021 }
2022 [(set (attr "isa")
2023 (cond [(eq_attr "alternative" "0,1,6,7")
2024 (const_string "x64")
2025 (eq_attr "alternative" "3")
2026 (const_string "sse2")
2027 ]
2028 (const_string "*")))
2029 (set (attr "type")
2030 (cond [(eq_attr "alternative" "0,1,6,7")
2031 (const_string "multi")
2032 (eq_attr "alternative" "2,3")
2033 (const_string "sselog1")
2034 ]
2035 (const_string "ssemov")))
2036 (set (attr "prefix")
2037 (if_then_else (eq_attr "type" "sselog1,ssemov")
2038 (const_string "maybe_vex")
2039 (const_string "orig")))
2040 (set (attr "mode")
2041 (cond [(eq_attr "alternative" "0,1")
2042 (const_string "DI")
2043 (ior (match_operand 0 "ext_sse_reg_operand")
2044 (match_operand 1 "ext_sse_reg_operand"))
2045 (const_string "XI")
2046 (and (eq_attr "alternative" "3")
2047 (match_test "TARGET_AVX512VL"))
2048 (const_string "XI")
2049 (ior (not (match_test "TARGET_SSE2"))
2050 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2051 (and (eq_attr "alternative" "5")
2052 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2053 (const_string "V4SF")
2054 (match_test "TARGET_AVX")
2055 (const_string "TI")
2056 (match_test "optimize_function_for_size_p (cfun)")
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 {
2093 switch (get_attr_type (insn))
2094 {
2095 case TYPE_MSKMOV:
2096 return "kmovq\t{%1, %0|%0, %1}";
2097
2098 case TYPE_MSKLOG:
2099 if (operands[1] == const0_rtx)
2100 return "kxorq\t%0, %0, %0";
2101 else if (operands[1] == constm1_rtx)
2102 return "kxnorq\t%0, %0, %0";
2103 gcc_unreachable ();
2104
2105 case TYPE_MULTI:
2106 return "#";
2107
2108 case TYPE_MMX:
2109 return "pxor\t%0, %0";
2110
2111 case TYPE_MMXMOV:
2112 /* Handle broken assemblers that require movd instead of movq. */
2113 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2114 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2115 return "movd\t{%1, %0|%0, %1}";
2116 return "movq\t{%1, %0|%0, %1}";
2117
2118 case TYPE_SSELOG1:
2119 return standard_sse_constant_opcode (insn, operands);
2120
2121 case TYPE_SSEMOV:
2122 switch (get_attr_mode (insn))
2123 {
2124 case MODE_DI:
2125 /* Handle broken assemblers that require movd instead of movq. */
2126 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2127 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2128 return "%vmovd\t{%1, %0|%0, %1}";
2129 return "%vmovq\t{%1, %0|%0, %1}";
2130
2131 case MODE_TI:
2132 /* Handle AVX512 registers set. */
2133 if (EXT_REX_SSE_REG_P (operands[0])
2134 || EXT_REX_SSE_REG_P (operands[1]))
2135 return "vmovdqa64\t{%1, %0|%0, %1}";
2136 return "%vmovdqa\t{%1, %0|%0, %1}";
2137
2138 case MODE_V2SF:
2139 gcc_assert (!TARGET_AVX);
2140 return "movlps\t{%1, %0|%0, %1}";
2141 case MODE_V4SF:
2142 return "%vmovaps\t{%1, %0|%0, %1}";
2143
2144 default:
2145 gcc_unreachable ();
2146 }
2147
2148 case TYPE_SSECVT:
2149 if (SSE_REG_P (operands[0]))
2150 return "movq2dq\t{%1, %0|%0, %1}";
2151 else
2152 return "movdq2q\t{%1, %0|%0, %1}";
2153
2154 case TYPE_LEA:
2155 return "lea{q}\t{%E1, %0|%0, %E1}";
2156
2157 case TYPE_IMOV:
2158 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2159 if (get_attr_mode (insn) == MODE_SI)
2160 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2161 else if (which_alternative == 4)
2162 return "movabs{q}\t{%1, %0|%0, %1}";
2163 else if (ix86_use_lea_for_mov (insn, operands))
2164 return "lea{q}\t{%E1, %0|%0, %E1}";
2165 else
2166 return "mov{q}\t{%1, %0|%0, %1}";
2167
2168 default:
2169 gcc_unreachable ();
2170 }
2171 }
2172 [(set (attr "isa")
2173 (cond [(eq_attr "alternative" "0,1,17,18")
2174 (const_string "nox64")
2175 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2176 (const_string "x64")
2177 (eq_attr "alternative" "19,20")
2178 (const_string "x64_sse2")
2179 (eq_attr "alternative" "21,22")
2180 (const_string "sse2")
2181 ]
2182 (const_string "*")))
2183 (set (attr "type")
2184 (cond [(eq_attr "alternative" "0,1,17,18")
2185 (const_string "multi")
2186 (eq_attr "alternative" "6")
2187 (const_string "mmx")
2188 (eq_attr "alternative" "7,8,9,10,11")
2189 (const_string "mmxmov")
2190 (eq_attr "alternative" "12")
2191 (const_string "sselog1")
2192 (eq_attr "alternative" "13,14,15,16,19,20")
2193 (const_string "ssemov")
2194 (eq_attr "alternative" "21,22")
2195 (const_string "ssecvt")
2196 (eq_attr "alternative" "23,24,25,26")
2197 (const_string "mskmov")
2198 (eq_attr "alternative" "27")
2199 (const_string "msklog")
2200 (and (match_operand 0 "register_operand")
2201 (match_operand 1 "pic_32bit_operand"))
2202 (const_string "lea")
2203 ]
2204 (const_string "imov")))
2205 (set (attr "modrm")
2206 (if_then_else
2207 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2208 (const_string "0")
2209 (const_string "*")))
2210 (set (attr "length_immediate")
2211 (if_then_else
2212 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2213 (const_string "8")
2214 (const_string "*")))
2215 (set (attr "prefix_rex")
2216 (if_then_else
2217 (eq_attr "alternative" "10,11,19,20")
2218 (const_string "1")
2219 (const_string "*")))
2220 (set (attr "prefix")
2221 (if_then_else (eq_attr "type" "sselog1,ssemov")
2222 (const_string "maybe_vex")
2223 (const_string "orig")))
2224 (set (attr "prefix_data16")
2225 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2226 (const_string "1")
2227 (const_string "*")))
2228 (set (attr "mode")
2229 (cond [(eq_attr "alternative" "2")
2230 (const_string "SI")
2231 (eq_attr "alternative" "12,13")
2232 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2233 (match_operand 1 "ext_sse_reg_operand"))
2234 (const_string "TI")
2235 (ior (not (match_test "TARGET_SSE2"))
2236 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2237 (const_string "V4SF")
2238 (match_test "TARGET_AVX")
2239 (const_string "TI")
2240 (match_test "optimize_function_for_size_p (cfun)")
2241 (const_string "V4SF")
2242 ]
2243 (const_string "TI"))
2244
2245 (and (eq_attr "alternative" "14,15,16")
2246 (not (match_test "TARGET_SSE2")))
2247 (const_string "V2SF")
2248 ]
2249 (const_string "DI")))
2250 (set (attr "preferred_for_speed")
2251 (cond [(eq_attr "alternative" "10,17,19")
2252 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2253 (eq_attr "alternative" "11,18,20")
2254 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2255 ]
2256 (symbol_ref "true")))
2257 (set (attr "enabled")
2258 (cond [(eq_attr "alternative" "15")
2259 (if_then_else
2260 (match_test "TARGET_STV && TARGET_SSE2")
2261 (symbol_ref "false")
2262 (const_string "*"))
2263 (eq_attr "alternative" "16")
2264 (if_then_else
2265 (match_test "TARGET_STV && TARGET_SSE2")
2266 (symbol_ref "true")
2267 (symbol_ref "false"))
2268 ]
2269 (const_string "*")))])
2270
2271 (define_split
2272 [(set (match_operand:<DWI> 0 "general_reg_operand")
2273 (match_operand:<DWI> 1 "sse_reg_operand"))]
2274 "TARGET_SSE4_1
2275 && reload_completed"
2276 [(set (match_dup 2)
2277 (vec_select:DWIH
2278 (match_dup 3)
2279 (parallel [(const_int 1)])))]
2280 {
2281 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2282 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2283
2284 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2285 gen_lowpart (<MODE>mode, operands[1]));
2286 })
2287
2288 (define_split
2289 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2290 (match_operand:DWI 1 "general_gr_operand"))]
2291 "reload_completed"
2292 [(const_int 0)]
2293 "ix86_split_long_move (operands); DONE;")
2294
2295 (define_split
2296 [(set (match_operand:DI 0 "sse_reg_operand")
2297 (match_operand:DI 1 "general_reg_operand"))]
2298 "!TARGET_64BIT && TARGET_SSE4_1
2299 && reload_completed"
2300 [(set (match_dup 2)
2301 (vec_merge:V4SI
2302 (vec_duplicate:V4SI (match_dup 3))
2303 (match_dup 2)
2304 (const_int 2)))]
2305 {
2306 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2307 operands[3] = gen_highpart (SImode, operands[1]);
2308
2309 emit_move_insn (gen_lowpart (SImode, operands[0]),
2310 gen_lowpart (SImode, operands[1]));
2311 })
2312
2313 ;; movabsq $0x0012345678000000, %rax is longer
2314 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2315 (define_peephole2
2316 [(set (match_operand:DI 0 "register_operand")
2317 (match_operand:DI 1 "const_int_operand"))]
2318 "TARGET_64BIT
2319 && optimize_insn_for_size_p ()
2320 && LEGACY_INT_REG_P (operands[0])
2321 && !x86_64_immediate_operand (operands[1], DImode)
2322 && !x86_64_zext_immediate_operand (operands[1], DImode)
2323 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2324 & ~(HOST_WIDE_INT) 0xffffffff)
2325 && peep2_regno_dead_p (0, FLAGS_REG)"
2326 [(set (match_dup 0) (match_dup 1))
2327 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2328 (clobber (reg:CC FLAGS_REG))])]
2329 {
2330 int shift = ctz_hwi (UINTVAL (operands[1]));
2331 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2332 operands[2] = gen_int_mode (shift, QImode);
2333 })
2334
2335 (define_insn "*movsi_internal"
2336 [(set (match_operand:SI 0 "nonimmediate_operand"
2337 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k")
2338 (match_operand:SI 1 "general_operand"
2339 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k ,CBC"))]
2340 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2341 {
2342 switch (get_attr_type (insn))
2343 {
2344 case TYPE_SSELOG1:
2345 return standard_sse_constant_opcode (insn, operands);
2346
2347 case TYPE_MSKMOV:
2348 return "kmovd\t{%1, %0|%0, %1}";
2349
2350 case TYPE_MSKLOG:
2351 if (operands[1] == const0_rtx)
2352 return "kxord\t%0, %0, %0";
2353 else if (operands[1] == constm1_rtx)
2354 return "kxnord\t%0, %0, %0";
2355 gcc_unreachable ();
2356
2357 case TYPE_SSEMOV:
2358 switch (get_attr_mode (insn))
2359 {
2360 case MODE_SI:
2361 return "%vmovd\t{%1, %0|%0, %1}";
2362 case MODE_TI:
2363 return "%vmovdqa\t{%1, %0|%0, %1}";
2364 case MODE_XI:
2365 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2366
2367 case MODE_V4SF:
2368 return "%vmovaps\t{%1, %0|%0, %1}";
2369
2370 case MODE_SF:
2371 gcc_assert (!TARGET_AVX);
2372 return "movss\t{%1, %0|%0, %1}";
2373
2374 default:
2375 gcc_unreachable ();
2376 }
2377
2378 case TYPE_MMX:
2379 return "pxor\t%0, %0";
2380
2381 case TYPE_MMXMOV:
2382 switch (get_attr_mode (insn))
2383 {
2384 case MODE_DI:
2385 return "movq\t{%1, %0|%0, %1}";
2386 case MODE_SI:
2387 return "movd\t{%1, %0|%0, %1}";
2388
2389 default:
2390 gcc_unreachable ();
2391 }
2392
2393 case TYPE_LEA:
2394 return "lea{l}\t{%E1, %0|%0, %E1}";
2395
2396 case TYPE_IMOV:
2397 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2398 if (ix86_use_lea_for_mov (insn, operands))
2399 return "lea{l}\t{%E1, %0|%0, %E1}";
2400 else
2401 return "mov{l}\t{%1, %0|%0, %1}";
2402
2403 default:
2404 gcc_unreachable ();
2405 }
2406 }
2407 [(set (attr "isa")
2408 (cond [(eq_attr "alternative" "12,13")
2409 (const_string "sse2")
2410 ]
2411 (const_string "*")))
2412 (set (attr "type")
2413 (cond [(eq_attr "alternative" "2")
2414 (const_string "mmx")
2415 (eq_attr "alternative" "3,4,5,6,7")
2416 (const_string "mmxmov")
2417 (eq_attr "alternative" "8")
2418 (const_string "sselog1")
2419 (eq_attr "alternative" "9,10,11,12,13")
2420 (const_string "ssemov")
2421 (eq_attr "alternative" "14,15,16")
2422 (const_string "mskmov")
2423 (eq_attr "alternative" "17")
2424 (const_string "msklog")
2425 (and (match_operand 0 "register_operand")
2426 (match_operand 1 "pic_32bit_operand"))
2427 (const_string "lea")
2428 ]
2429 (const_string "imov")))
2430 (set (attr "prefix")
2431 (if_then_else (eq_attr "type" "sselog1,ssemov")
2432 (const_string "maybe_vex")
2433 (const_string "orig")))
2434 (set (attr "prefix_data16")
2435 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2436 (const_string "1")
2437 (const_string "*")))
2438 (set (attr "mode")
2439 (cond [(eq_attr "alternative" "2,3")
2440 (const_string "DI")
2441 (eq_attr "alternative" "8,9")
2442 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2443 (match_operand 1 "ext_sse_reg_operand"))
2444 (const_string "XI")
2445 (ior (not (match_test "TARGET_SSE2"))
2446 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2447 (const_string "V4SF")
2448 (match_test "TARGET_AVX")
2449 (const_string "TI")
2450 (match_test "optimize_function_for_size_p (cfun)")
2451 (const_string "V4SF")
2452 ]
2453 (const_string "TI"))
2454
2455 (and (eq_attr "alternative" "10,11")
2456 (not (match_test "TARGET_SSE2")))
2457 (const_string "SF")
2458 ]
2459 (const_string "SI")))
2460 (set (attr "preferred_for_speed")
2461 (cond [(eq_attr "alternative" "6,12")
2462 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2463 (eq_attr "alternative" "7,13")
2464 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2465 ]
2466 (symbol_ref "true")))])
2467
2468 (define_insn "*movhi_internal"
2469 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m,k")
2470 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k,CBC"))]
2471 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2472 {
2473 switch (get_attr_type (insn))
2474 {
2475 case TYPE_IMOVX:
2476 /* movzwl is faster than movw on p2 due to partial word stalls,
2477 though not as fast as an aligned movl. */
2478 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2479
2480 case TYPE_MSKMOV:
2481 switch (which_alternative)
2482 {
2483 case 4:
2484 return "kmovw\t{%k1, %0|%0, %k1}";
2485 case 6:
2486 return "kmovw\t{%1, %k0|%k0, %1}";
2487 case 5:
2488 case 7:
2489 return "kmovw\t{%1, %0|%0, %1}";
2490 default:
2491 gcc_unreachable ();
2492 }
2493
2494 case TYPE_MSKLOG:
2495 if (operands[1] == const0_rtx)
2496 return "kxorw\t%0, %0, %0";
2497 else if (operands[1] == constm1_rtx)
2498 return "kxnorw\t%0, %0, %0";
2499 gcc_unreachable ();
2500
2501 default:
2502 if (get_attr_mode (insn) == MODE_SI)
2503 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2504 else
2505 return "mov{w}\t{%1, %0|%0, %1}";
2506 }
2507 }
2508 [(set (attr "type")
2509 (cond [(eq_attr "alternative" "4,5,6,7")
2510 (const_string "mskmov")
2511 (eq_attr "alternative" "8")
2512 (const_string "msklog")
2513 (match_test "optimize_function_for_size_p (cfun)")
2514 (const_string "imov")
2515 (and (eq_attr "alternative" "0")
2516 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2517 (not (match_test "TARGET_HIMODE_MATH"))))
2518 (const_string "imov")
2519 (and (eq_attr "alternative" "1,2")
2520 (match_operand:HI 1 "aligned_operand"))
2521 (const_string "imov")
2522 (and (match_test "TARGET_MOVX")
2523 (eq_attr "alternative" "0,2"))
2524 (const_string "imovx")
2525 ]
2526 (const_string "imov")))
2527 (set (attr "prefix")
2528 (if_then_else (eq_attr "alternative" "4,5,6,7,8")
2529 (const_string "vex")
2530 (const_string "orig")))
2531 (set (attr "mode")
2532 (cond [(eq_attr "type" "imovx")
2533 (const_string "SI")
2534 (and (eq_attr "alternative" "1,2")
2535 (match_operand:HI 1 "aligned_operand"))
2536 (const_string "SI")
2537 (and (eq_attr "alternative" "0")
2538 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2539 (not (match_test "TARGET_HIMODE_MATH"))))
2540 (const_string "SI")
2541 ]
2542 (const_string "HI")))])
2543
2544 ;; Situation is quite tricky about when to choose full sized (SImode) move
2545 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2546 ;; partial register dependency machines (such as AMD Athlon), where QImode
2547 ;; moves issue extra dependency and for partial register stalls machines
2548 ;; that don't use QImode patterns (and QImode move cause stall on the next
2549 ;; instruction).
2550 ;;
2551 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2552 ;; register stall machines with, where we use QImode instructions, since
2553 ;; partial register stall can be caused there. Then we use movzx.
2554
2555 (define_insn "*movqi_internal"
2556 [(set (match_operand:QI 0 "nonimmediate_operand"
2557 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k,k,k")
2558 (match_operand:QI 1 "general_operand"
2559 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m,C,BC"))]
2560 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2561 {
2562 char buf[128];
2563 const char *ops;
2564 const char *suffix;
2565
2566 switch (get_attr_type (insn))
2567 {
2568 case TYPE_IMOVX:
2569 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2570 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2571
2572 case TYPE_MSKMOV:
2573 switch (which_alternative)
2574 {
2575 case 9:
2576 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2577 break;
2578 case 11:
2579 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2580 break;
2581 case 12:
2582 case 13:
2583 gcc_assert (TARGET_AVX512DQ);
2584 /* FALLTHRU */
2585 case 10:
2586 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2587 break;
2588 default:
2589 gcc_unreachable ();
2590 }
2591
2592 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2593
2594 snprintf (buf, sizeof (buf), ops, suffix);
2595 output_asm_insn (buf, operands);
2596 return "";
2597
2598 case TYPE_MSKLOG:
2599 if (operands[1] == const0_rtx)
2600 {
2601 if (get_attr_mode (insn) == MODE_HI)
2602 return "kxorw\t%0, %0, %0";
2603 else
2604 return "kxorb\t%0, %0, %0";
2605 }
2606 else if (operands[1] == constm1_rtx)
2607 {
2608 gcc_assert (TARGET_AVX512DQ);
2609 return "kxnorb\t%0, %0, %0";
2610 }
2611 gcc_unreachable ();
2612
2613 default:
2614 if (get_attr_mode (insn) == MODE_SI)
2615 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2616 else
2617 return "mov{b}\t{%1, %0|%0, %1}";
2618 }
2619 }
2620 [(set (attr "isa")
2621 (cond [(eq_attr "alternative" "1,2")
2622 (const_string "x64")
2623 (eq_attr "alternative" "12,13,15")
2624 (const_string "avx512dq")
2625 ]
2626 (const_string "*")))
2627 (set (attr "type")
2628 (cond [(eq_attr "alternative" "9,10,11,12,13")
2629 (const_string "mskmov")
2630 (eq_attr "alternative" "14,15")
2631 (const_string "msklog")
2632 (and (eq_attr "alternative" "7")
2633 (not (match_operand:QI 1 "aligned_operand")))
2634 (const_string "imovx")
2635 (match_test "optimize_function_for_size_p (cfun)")
2636 (const_string "imov")
2637 (and (eq_attr "alternative" "5")
2638 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2639 (not (match_test "TARGET_QIMODE_MATH"))))
2640 (const_string "imov")
2641 (eq_attr "alternative" "5,7")
2642 (const_string "imovx")
2643 (and (match_test "TARGET_MOVX")
2644 (eq_attr "alternative" "4"))
2645 (const_string "imovx")
2646 ]
2647 (const_string "imov")))
2648 (set (attr "prefix")
2649 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
2650 (const_string "vex")
2651 (const_string "orig")))
2652 (set (attr "mode")
2653 (cond [(eq_attr "alternative" "5,6,7")
2654 (const_string "SI")
2655 (eq_attr "alternative" "8")
2656 (const_string "QI")
2657 (and (eq_attr "alternative" "9,10,11,14")
2658 (not (match_test "TARGET_AVX512DQ")))
2659 (const_string "HI")
2660 (eq_attr "type" "imovx")
2661 (const_string "SI")
2662 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2663 ;; ones.
2664 (and (eq_attr "type" "imov")
2665 (and (eq_attr "alternative" "3")
2666 (match_test "optimize_function_for_size_p (cfun)")))
2667 (const_string "QI")
2668 ;; For -Os, movl where one or both operands are NON_Q_REGS
2669 ;; and both are LEGACY_REGS is shorter than movb.
2670 ;; Otherwise movb and movl sizes are the same, so decide purely
2671 ;; based on speed factors.
2672 (and (eq_attr "type" "imov")
2673 (and (eq_attr "alternative" "1")
2674 (match_test "optimize_function_for_size_p (cfun)")))
2675 (const_string "SI")
2676 (and (eq_attr "type" "imov")
2677 (and (eq_attr "alternative" "0,1,2,3")
2678 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2679 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2680 (const_string "SI")
2681 ;; Avoid partial register stalls when not using QImode arithmetic
2682 (and (eq_attr "type" "imov")
2683 (and (eq_attr "alternative" "0,1,2,3")
2684 (and (match_test "TARGET_PARTIAL_REG_STALL")
2685 (not (match_test "TARGET_QIMODE_MATH")))))
2686 (const_string "SI")
2687 ]
2688 (const_string "QI")))])
2689
2690 ;; Stores and loads of ax to arbitrary constant address.
2691 ;; We fake an second form of instruction to force reload to load address
2692 ;; into register when rax is not available
2693 (define_insn "*movabs<mode>_1"
2694 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2695 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2696 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2697 {
2698 /* Recover the full memory rtx. */
2699 operands[0] = SET_DEST (PATTERN (insn));
2700 switch (which_alternative)
2701 {
2702 case 0:
2703 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2704 case 1:
2705 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2706 default:
2707 gcc_unreachable ();
2708 }
2709 }
2710 [(set_attr "type" "imov")
2711 (set_attr "modrm" "0,*")
2712 (set_attr "length_address" "8,0")
2713 (set_attr "length_immediate" "0,*")
2714 (set_attr "memory" "store")
2715 (set_attr "mode" "<MODE>")])
2716
2717 (define_insn "*movabs<mode>_2"
2718 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2719 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2720 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2721 {
2722 /* Recover the full memory rtx. */
2723 operands[1] = SET_SRC (PATTERN (insn));
2724 switch (which_alternative)
2725 {
2726 case 0:
2727 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2728 case 1:
2729 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2730 default:
2731 gcc_unreachable ();
2732 }
2733 }
2734 [(set_attr "type" "imov")
2735 (set_attr "modrm" "0,*")
2736 (set_attr "length_address" "8,0")
2737 (set_attr "length_immediate" "0")
2738 (set_attr "memory" "load")
2739 (set_attr "mode" "<MODE>")])
2740
2741 (define_insn "*swap<mode>"
2742 [(set (match_operand:SWI48 0 "register_operand" "+r")
2743 (match_operand:SWI48 1 "register_operand" "+r"))
2744 (set (match_dup 1)
2745 (match_dup 0))]
2746 ""
2747 "xchg{<imodesuffix>}\t%1, %0"
2748 [(set_attr "type" "imov")
2749 (set_attr "mode" "<MODE>")
2750 (set_attr "pent_pair" "np")
2751 (set_attr "athlon_decode" "vector")
2752 (set_attr "amdfam10_decode" "double")
2753 (set_attr "bdver1_decode" "double")])
2754
2755 (define_insn "*swap<mode>"
2756 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2757 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2758 (set (match_dup 1)
2759 (match_dup 0))]
2760 ""
2761 "@
2762 xchg{<imodesuffix>}\t%1, %0
2763 xchg{l}\t%k1, %k0"
2764 [(set_attr "type" "imov")
2765 (set_attr "mode" "<MODE>,SI")
2766 (set (attr "preferred_for_size")
2767 (cond [(eq_attr "alternative" "0")
2768 (symbol_ref "false")]
2769 (symbol_ref "true")))
2770 ;; Potential partial reg stall on alternative 1.
2771 (set (attr "preferred_for_speed")
2772 (cond [(eq_attr "alternative" "1")
2773 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2774 (symbol_ref "true")))
2775 (set_attr "pent_pair" "np")
2776 (set_attr "athlon_decode" "vector")
2777 (set_attr "amdfam10_decode" "double")
2778 (set_attr "bdver1_decode" "double")])
2779
2780 (define_expand "movstrict<mode>"
2781 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2782 (match_operand:SWI12 1 "general_operand"))]
2783 ""
2784 {
2785 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2786 FAIL;
2787 if (SUBREG_P (operands[0])
2788 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2789 FAIL;
2790 /* Don't generate memory->memory moves, go through a register */
2791 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2792 operands[1] = force_reg (<MODE>mode, operands[1]);
2793 })
2794
2795 (define_insn "*movstrict<mode>_1"
2796 [(set (strict_low_part
2797 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2798 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2799 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2800 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2801 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2802 [(set_attr "type" "imov")
2803 (set_attr "mode" "<MODE>")])
2804
2805 (define_insn "*movstrict<mode>_xor"
2806 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2807 (match_operand:SWI12 1 "const0_operand"))
2808 (clobber (reg:CC FLAGS_REG))]
2809 "reload_completed"
2810 "xor{<imodesuffix>}\t%0, %0"
2811 [(set_attr "type" "alu1")
2812 (set_attr "mode" "<MODE>")
2813 (set_attr "length_immediate" "0")])
2814
2815 (define_expand "extv<mode>"
2816 [(set (match_operand:SWI24 0 "register_operand")
2817 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2818 (match_operand:SI 2 "const_int_operand")
2819 (match_operand:SI 3 "const_int_operand")))]
2820 ""
2821 {
2822 /* Handle extractions from %ah et al. */
2823 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2824 FAIL;
2825
2826 unsigned int regno = reg_or_subregno (operands[1]);
2827
2828 /* Be careful to expand only with registers having upper parts. */
2829 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2830 operands[1] = copy_to_reg (operands[1]);
2831 })
2832
2833 (define_insn "*extv<mode>"
2834 [(set (match_operand:SWI24 0 "register_operand" "=R")
2835 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2836 (const_int 8)
2837 (const_int 8)))]
2838 ""
2839 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2840 [(set_attr "type" "imovx")
2841 (set_attr "mode" "SI")])
2842
2843 (define_expand "extzv<mode>"
2844 [(set (match_operand:SWI248 0 "register_operand")
2845 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2846 (match_operand:SI 2 "const_int_operand")
2847 (match_operand:SI 3 "const_int_operand")))]
2848 ""
2849 {
2850 if (ix86_expand_pextr (operands))
2851 DONE;
2852
2853 /* Handle extractions from %ah et al. */
2854 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2855 FAIL;
2856
2857 unsigned int regno = reg_or_subregno (operands[1]);
2858
2859 /* Be careful to expand only with registers having upper parts. */
2860 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2861 operands[1] = copy_to_reg (operands[1]);
2862 })
2863
2864 (define_insn "*extzvqi_mem_rex64"
2865 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2866 (subreg:QI
2867 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2868 (const_int 8)
2869 (const_int 8)) 0))]
2870 "TARGET_64BIT && reload_completed"
2871 "mov{b}\t{%h1, %0|%0, %h1}"
2872 [(set_attr "type" "imov")
2873 (set_attr "mode" "QI")])
2874
2875 (define_insn "*extzv<mode>"
2876 [(set (match_operand:SWI248 0 "register_operand" "=R")
2877 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2878 (const_int 8)
2879 (const_int 8)))]
2880 ""
2881 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2882 [(set_attr "type" "imovx")
2883 (set_attr "mode" "SI")])
2884
2885 (define_insn "*extzvqi"
2886 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2887 (subreg:QI
2888 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2889 (const_int 8)
2890 (const_int 8)) 0))]
2891 ""
2892 {
2893 switch (get_attr_type (insn))
2894 {
2895 case TYPE_IMOVX:
2896 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2897 default:
2898 return "mov{b}\t{%h1, %0|%0, %h1}";
2899 }
2900 }
2901 [(set_attr "isa" "*,*,nox64")
2902 (set (attr "type")
2903 (if_then_else (and (match_operand:QI 0 "register_operand")
2904 (ior (not (match_operand:QI 0 "QIreg_operand"))
2905 (match_test "TARGET_MOVX")))
2906 (const_string "imovx")
2907 (const_string "imov")))
2908 (set (attr "mode")
2909 (if_then_else (eq_attr "type" "imovx")
2910 (const_string "SI")
2911 (const_string "QI")))])
2912
2913 (define_peephole2
2914 [(set (match_operand:QI 0 "register_operand")
2915 (subreg:QI
2916 (zero_extract:SI (match_operand 1 "ext_register_operand")
2917 (const_int 8)
2918 (const_int 8)) 0))
2919 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2920 "TARGET_64BIT
2921 && peep2_reg_dead_p (2, operands[0])"
2922 [(set (match_dup 2)
2923 (subreg:QI
2924 (zero_extract:SI (match_dup 1)
2925 (const_int 8)
2926 (const_int 8)) 0))])
2927
2928 (define_expand "insv<mode>"
2929 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2930 (match_operand:SI 1 "const_int_operand")
2931 (match_operand:SI 2 "const_int_operand"))
2932 (match_operand:SWI248 3 "register_operand"))]
2933 ""
2934 {
2935 rtx dst;
2936
2937 if (ix86_expand_pinsr (operands))
2938 DONE;
2939
2940 /* Handle insertions to %ah et al. */
2941 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2942 FAIL;
2943
2944 unsigned int regno = reg_or_subregno (operands[0]);
2945
2946 /* Be careful to expand only with registers having upper parts. */
2947 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2948 dst = copy_to_reg (operands[0]);
2949 else
2950 dst = operands[0];
2951
2952 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2953
2954 /* Fix up the destination if needed. */
2955 if (dst != operands[0])
2956 emit_move_insn (operands[0], dst);
2957
2958 DONE;
2959 })
2960
2961 (define_insn "*insvqi_1_mem_rex64"
2962 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2963 (const_int 8)
2964 (const_int 8))
2965 (subreg:SI
2966 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2967 "TARGET_64BIT && reload_completed"
2968 "mov{b}\t{%1, %h0|%h0, %1}"
2969 [(set_attr "type" "imov")
2970 (set_attr "mode" "QI")])
2971
2972 (define_insn "insv<mode>_1"
2973 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2974 (const_int 8)
2975 (const_int 8))
2976 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2977 ""
2978 {
2979 if (CONST_INT_P (operands[1]))
2980 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2981 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2982 }
2983 [(set_attr "isa" "*,nox64")
2984 (set_attr "type" "imov")
2985 (set_attr "mode" "QI")])
2986
2987 (define_insn "*insvqi_1"
2988 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
2989 (const_int 8)
2990 (const_int 8))
2991 (subreg:SI
2992 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
2993 ""
2994 "mov{b}\t{%1, %h0|%h0, %1}"
2995 [(set_attr "isa" "*,nox64")
2996 (set_attr "type" "imov")
2997 (set_attr "mode" "QI")])
2998
2999 (define_peephole2
3000 [(set (match_operand:QI 0 "register_operand")
3001 (match_operand:QI 1 "norex_memory_operand"))
3002 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3003 (const_int 8)
3004 (const_int 8))
3005 (subreg:SI (match_dup 0) 0))]
3006 "TARGET_64BIT
3007 && peep2_reg_dead_p (2, operands[0])"
3008 [(set (zero_extract:SI (match_dup 2)
3009 (const_int 8)
3010 (const_int 8))
3011 (subreg:SI (match_dup 1) 0))])
3012
3013 (define_code_iterator any_extract [sign_extract zero_extract])
3014
3015 (define_insn "*insvqi_2"
3016 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3017 (const_int 8)
3018 (const_int 8))
3019 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3020 (const_int 8)
3021 (const_int 8)))]
3022 ""
3023 "mov{b}\t{%h1, %h0|%h0, %h1}"
3024 [(set_attr "type" "imov")
3025 (set_attr "mode" "QI")])
3026
3027 (define_insn "*insvqi_3"
3028 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3029 (const_int 8)
3030 (const_int 8))
3031 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3032 (const_int 8)))]
3033 ""
3034 "mov{b}\t{%h1, %h0|%h0, %h1}"
3035 [(set_attr "type" "imov")
3036 (set_attr "mode" "QI")])
3037 \f
3038 ;; Floating point push instructions.
3039
3040 (define_insn "*pushtf"
3041 [(set (match_operand:TF 0 "push_operand" "=<,<")
3042 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3043 "TARGET_64BIT || TARGET_SSE"
3044 {
3045 /* This insn should be already split before reg-stack. */
3046 gcc_unreachable ();
3047 }
3048 [(set_attr "isa" "*,x64")
3049 (set_attr "type" "multi")
3050 (set_attr "unit" "sse,*")
3051 (set_attr "mode" "TF,DI")])
3052
3053 ;; %%% Kill this when call knows how to work this out.
3054 (define_split
3055 [(set (match_operand:TF 0 "push_operand")
3056 (match_operand:TF 1 "sse_reg_operand"))]
3057 "TARGET_SSE && reload_completed"
3058 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3059 (set (match_dup 0) (match_dup 1))]
3060 {
3061 /* Preserve memory attributes. */
3062 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3063 })
3064
3065 (define_insn_and_split "*pushxf_rounded"
3066 [(set (mem:XF
3067 (pre_modify:P
3068 (reg:P SP_REG)
3069 (plus:P (reg:P SP_REG) (const_int -16))))
3070 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3071 "TARGET_64BIT"
3072 "#"
3073 "&& 1"
3074 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3075 (set (match_dup 1) (match_dup 0))]
3076 {
3077 rtx pat = PATTERN (curr_insn);
3078 operands[1] = SET_DEST (pat);
3079
3080 /* Preserve memory attributes. */
3081 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3082 }
3083 [(set_attr "type" "multi")
3084 (set_attr "unit" "i387,*,*,*")
3085 (set (attr "mode")
3086 (cond [(eq_attr "alternative" "1,2,3")
3087 (const_string "DI")
3088 ]
3089 (const_string "XF")))
3090 (set (attr "preferred_for_size")
3091 (cond [(eq_attr "alternative" "1")
3092 (symbol_ref "false")]
3093 (symbol_ref "true")))])
3094
3095 (define_insn "*pushxf"
3096 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3097 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3098 ""
3099 {
3100 /* This insn should be already split before reg-stack. */
3101 gcc_unreachable ();
3102 }
3103 [(set_attr "isa" "*,*,*,nox64,x64")
3104 (set_attr "type" "multi")
3105 (set_attr "unit" "i387,*,*,*,*")
3106 (set (attr "mode")
3107 (cond [(eq_attr "alternative" "1,2,3,4")
3108 (if_then_else (match_test "TARGET_64BIT")
3109 (const_string "DI")
3110 (const_string "SI"))
3111 ]
3112 (const_string "XF")))
3113 (set (attr "preferred_for_size")
3114 (cond [(eq_attr "alternative" "1")
3115 (symbol_ref "false")]
3116 (symbol_ref "true")))])
3117
3118 ;; %%% Kill this when call knows how to work this out.
3119 (define_split
3120 [(set (match_operand:XF 0 "push_operand")
3121 (match_operand:XF 1 "fp_register_operand"))]
3122 "reload_completed"
3123 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3124 (set (match_dup 0) (match_dup 1))]
3125 {
3126 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3127 /* Preserve memory attributes. */
3128 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3129 })
3130
3131 (define_insn "*pushdf"
3132 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3133 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3134 ""
3135 {
3136 /* This insn should be already split before reg-stack. */
3137 gcc_unreachable ();
3138 }
3139 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3140 (set_attr "type" "multi")
3141 (set_attr "unit" "i387,*,*,*,*,sse")
3142 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3143 (set (attr "preferred_for_size")
3144 (cond [(eq_attr "alternative" "1")
3145 (symbol_ref "false")]
3146 (symbol_ref "true")))
3147 (set (attr "preferred_for_speed")
3148 (cond [(eq_attr "alternative" "1")
3149 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3150 (symbol_ref "true")))])
3151
3152 ;; %%% Kill this when call knows how to work this out.
3153 (define_split
3154 [(set (match_operand:DF 0 "push_operand")
3155 (match_operand:DF 1 "any_fp_register_operand"))]
3156 "reload_completed"
3157 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3158 (set (match_dup 0) (match_dup 1))]
3159 {
3160 /* Preserve memory attributes. */
3161 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3162 })
3163
3164 (define_insn "*pushsf_rex64"
3165 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3166 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3167 "TARGET_64BIT"
3168 {
3169 /* Anything else should be already split before reg-stack. */
3170 gcc_assert (which_alternative == 1);
3171 return "push{q}\t%q1";
3172 }
3173 [(set_attr "type" "multi,push,multi")
3174 (set_attr "unit" "i387,*,*")
3175 (set_attr "mode" "SF,DI,SF")])
3176
3177 (define_insn "*pushsf"
3178 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3179 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3180 "!TARGET_64BIT"
3181 {
3182 /* Anything else should be already split before reg-stack. */
3183 gcc_assert (which_alternative == 1);
3184 return "push{l}\t%1";
3185 }
3186 [(set_attr "type" "multi,push,multi")
3187 (set_attr "unit" "i387,*,*")
3188 (set_attr "mode" "SF,SI,SF")])
3189
3190 ;; %%% Kill this when call knows how to work this out.
3191 (define_split
3192 [(set (match_operand:SF 0 "push_operand")
3193 (match_operand:SF 1 "any_fp_register_operand"))]
3194 "reload_completed"
3195 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3196 (set (match_dup 0) (match_dup 1))]
3197 {
3198 rtx op = XEXP (operands[0], 0);
3199 if (GET_CODE (op) == PRE_DEC)
3200 {
3201 gcc_assert (!TARGET_64BIT);
3202 op = GEN_INT (-4);
3203 }
3204 else
3205 {
3206 op = XEXP (XEXP (op, 1), 1);
3207 gcc_assert (CONST_INT_P (op));
3208 }
3209 operands[2] = op;
3210 /* Preserve memory attributes. */
3211 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3212 })
3213
3214 (define_split
3215 [(set (match_operand:SF 0 "push_operand")
3216 (match_operand:SF 1 "memory_operand"))]
3217 "reload_completed
3218 && find_constant_src (insn)"
3219 [(set (match_dup 0) (match_dup 2))]
3220 "operands[2] = find_constant_src (curr_insn);")
3221
3222 (define_split
3223 [(set (match_operand 0 "push_operand")
3224 (match_operand 1 "general_gr_operand"))]
3225 "reload_completed
3226 && (GET_MODE (operands[0]) == TFmode
3227 || GET_MODE (operands[0]) == XFmode
3228 || GET_MODE (operands[0]) == DFmode)"
3229 [(const_int 0)]
3230 "ix86_split_long_move (operands); DONE;")
3231 \f
3232 ;; Floating point move instructions.
3233
3234 (define_expand "movtf"
3235 [(set (match_operand:TF 0 "nonimmediate_operand")
3236 (match_operand:TF 1 "nonimmediate_operand"))]
3237 "TARGET_64BIT || TARGET_SSE"
3238 "ix86_expand_move (TFmode, operands); DONE;")
3239
3240 (define_expand "mov<mode>"
3241 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3242 (match_operand:X87MODEF 1 "general_operand"))]
3243 ""
3244 "ix86_expand_move (<MODE>mode, operands); DONE;")
3245
3246 (define_insn "*movtf_internal"
3247 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3248 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3249 "(TARGET_64BIT || TARGET_SSE)
3250 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3251 && (lra_in_progress || reload_completed
3252 || !CONST_DOUBLE_P (operands[1])
3253 || ((optimize_function_for_size_p (cfun)
3254 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3255 && standard_sse_constant_p (operands[1], TFmode) == 1
3256 && !memory_operand (operands[0], TFmode))
3257 || (!TARGET_MEMORY_MISMATCH_STALL
3258 && memory_operand (operands[0], TFmode)))"
3259 {
3260 switch (get_attr_type (insn))
3261 {
3262 case TYPE_SSELOG1:
3263 return standard_sse_constant_opcode (insn, operands);
3264
3265 case TYPE_SSEMOV:
3266 /* Handle misaligned load/store since we
3267 don't have movmisaligntf pattern. */
3268 if (misaligned_operand (operands[0], TFmode)
3269 || misaligned_operand (operands[1], TFmode))
3270 {
3271 if (get_attr_mode (insn) == MODE_V4SF)
3272 return "%vmovups\t{%1, %0|%0, %1}";
3273 else if (TARGET_AVX512VL
3274 && (EXT_REX_SSE_REG_P (operands[0])
3275 || EXT_REX_SSE_REG_P (operands[1])))
3276 return "vmovdqu64\t{%1, %0|%0, %1}";
3277 else
3278 return "%vmovdqu\t{%1, %0|%0, %1}";
3279 }
3280 else
3281 {
3282 if (get_attr_mode (insn) == MODE_V4SF)
3283 return "%vmovaps\t{%1, %0|%0, %1}";
3284 else if (TARGET_AVX512VL
3285 && (EXT_REX_SSE_REG_P (operands[0])
3286 || EXT_REX_SSE_REG_P (operands[1])))
3287 return "vmovdqa64\t{%1, %0|%0, %1}";
3288 else
3289 return "%vmovdqa\t{%1, %0|%0, %1}";
3290 }
3291
3292 case TYPE_MULTI:
3293 return "#";
3294
3295 default:
3296 gcc_unreachable ();
3297 }
3298 }
3299 [(set_attr "isa" "*,*,*,x64,x64")
3300 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3301 (set (attr "prefix")
3302 (if_then_else (eq_attr "type" "sselog1,ssemov")
3303 (const_string "maybe_vex")
3304 (const_string "orig")))
3305 (set (attr "mode")
3306 (cond [(eq_attr "alternative" "3,4")
3307 (const_string "DI")
3308 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3309 (const_string "V4SF")
3310 (and (eq_attr "alternative" "2")
3311 (match_test "TARGET_SSE_TYPELESS_STORES"))
3312 (const_string "V4SF")
3313 (match_test "TARGET_AVX")
3314 (const_string "TI")
3315 (ior (not (match_test "TARGET_SSE2"))
3316 (match_test "optimize_function_for_size_p (cfun)"))
3317 (const_string "V4SF")
3318 ]
3319 (const_string "TI")))])
3320
3321 (define_split
3322 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3323 (match_operand:TF 1 "general_gr_operand"))]
3324 "reload_completed"
3325 [(const_int 0)]
3326 "ix86_split_long_move (operands); DONE;")
3327
3328 ;; Possible store forwarding (partial memory) stall
3329 ;; in alternatives 4, 6, 7 and 8.
3330 (define_insn "*movxf_internal"
3331 [(set (match_operand:XF 0 "nonimmediate_operand"
3332 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3333 (match_operand:XF 1 "general_operand"
3334 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3335 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3336 && (lra_in_progress || reload_completed
3337 || !CONST_DOUBLE_P (operands[1])
3338 || ((optimize_function_for_size_p (cfun)
3339 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3340 && standard_80387_constant_p (operands[1]) > 0
3341 && !memory_operand (operands[0], XFmode))
3342 || (!TARGET_MEMORY_MISMATCH_STALL
3343 && memory_operand (operands[0], XFmode))
3344 || !TARGET_HARD_XF_REGS)"
3345 {
3346 switch (get_attr_type (insn))
3347 {
3348 case TYPE_FMOV:
3349 if (which_alternative == 2)
3350 return standard_80387_constant_opcode (operands[1]);
3351 return output_387_reg_move (insn, operands);
3352
3353 case TYPE_MULTI:
3354 return "#";
3355
3356 default:
3357 gcc_unreachable ();
3358 }
3359 }
3360 [(set (attr "isa")
3361 (cond [(eq_attr "alternative" "7,10")
3362 (const_string "nox64")
3363 (eq_attr "alternative" "8,11")
3364 (const_string "x64")
3365 ]
3366 (const_string "*")))
3367 (set (attr "type")
3368 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3369 (const_string "multi")
3370 ]
3371 (const_string "fmov")))
3372 (set (attr "mode")
3373 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3374 (if_then_else (match_test "TARGET_64BIT")
3375 (const_string "DI")
3376 (const_string "SI"))
3377 ]
3378 (const_string "XF")))
3379 (set (attr "preferred_for_size")
3380 (cond [(eq_attr "alternative" "3,4")
3381 (symbol_ref "false")]
3382 (symbol_ref "true")))
3383 (set (attr "enabled")
3384 (cond [(eq_attr "alternative" "9,10,11")
3385 (if_then_else
3386 (match_test "TARGET_HARD_XF_REGS")
3387 (symbol_ref "false")
3388 (const_string "*"))
3389 (not (match_test "TARGET_HARD_XF_REGS"))
3390 (symbol_ref "false")
3391 ]
3392 (const_string "*")))])
3393
3394 (define_split
3395 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3396 (match_operand:XF 1 "general_gr_operand"))]
3397 "reload_completed"
3398 [(const_int 0)]
3399 "ix86_split_long_move (operands); DONE;")
3400
3401 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3402 (define_insn "*movdf_internal"
3403 [(set (match_operand:DF 0 "nonimmediate_operand"
3404 "=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")
3405 (match_operand:DF 1 "general_operand"
3406 "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"))]
3407 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3408 && (lra_in_progress || reload_completed
3409 || !CONST_DOUBLE_P (operands[1])
3410 || ((optimize_function_for_size_p (cfun)
3411 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3412 && ((IS_STACK_MODE (DFmode)
3413 && standard_80387_constant_p (operands[1]) > 0)
3414 || (TARGET_SSE2 && TARGET_SSE_MATH
3415 && standard_sse_constant_p (operands[1], DFmode) == 1))
3416 && !memory_operand (operands[0], DFmode))
3417 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3418 && memory_operand (operands[0], DFmode))
3419 || !TARGET_HARD_DF_REGS)"
3420 {
3421 switch (get_attr_type (insn))
3422 {
3423 case TYPE_FMOV:
3424 if (which_alternative == 2)
3425 return standard_80387_constant_opcode (operands[1]);
3426 return output_387_reg_move (insn, operands);
3427
3428 case TYPE_MULTI:
3429 return "#";
3430
3431 case TYPE_IMOV:
3432 if (get_attr_mode (insn) == MODE_SI)
3433 return "mov{l}\t{%1, %k0|%k0, %1}";
3434 else if (which_alternative == 11)
3435 return "movabs{q}\t{%1, %0|%0, %1}";
3436 else
3437 return "mov{q}\t{%1, %0|%0, %1}";
3438
3439 case TYPE_SSELOG1:
3440 return standard_sse_constant_opcode (insn, operands);
3441
3442 case TYPE_SSEMOV:
3443 switch (get_attr_mode (insn))
3444 {
3445 case MODE_DF:
3446 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3447 return "vmovsd\t{%d1, %0|%0, %d1}";
3448 return "%vmovsd\t{%1, %0|%0, %1}";
3449
3450 case MODE_V4SF:
3451 return "%vmovaps\t{%1, %0|%0, %1}";
3452 case MODE_V8DF:
3453 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3454 case MODE_V2DF:
3455 return "%vmovapd\t{%1, %0|%0, %1}";
3456
3457 case MODE_V2SF:
3458 gcc_assert (!TARGET_AVX);
3459 return "movlps\t{%1, %0|%0, %1}";
3460 case MODE_V1DF:
3461 gcc_assert (!TARGET_AVX);
3462 return "movlpd\t{%1, %0|%0, %1}";
3463
3464 case MODE_DI:
3465 /* Handle broken assemblers that require movd instead of movq. */
3466 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3467 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3468 return "%vmovd\t{%1, %0|%0, %1}";
3469 return "%vmovq\t{%1, %0|%0, %1}";
3470
3471 default:
3472 gcc_unreachable ();
3473 }
3474
3475 default:
3476 gcc_unreachable ();
3477 }
3478 }
3479 [(set (attr "isa")
3480 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3481 (const_string "nox64")
3482 (eq_attr "alternative" "8,9,10,11,24,25")
3483 (const_string "x64")
3484 (eq_attr "alternative" "12,13,14,15")
3485 (const_string "sse2")
3486 (eq_attr "alternative" "20,21")
3487 (const_string "x64_sse2")
3488 ]
3489 (const_string "*")))
3490 (set (attr "type")
3491 (cond [(eq_attr "alternative" "0,1,2")
3492 (const_string "fmov")
3493 (eq_attr "alternative" "3,4,5,6,7,22,23")
3494 (const_string "multi")
3495 (eq_attr "alternative" "8,9,10,11,24,25")
3496 (const_string "imov")
3497 (eq_attr "alternative" "12,16")
3498 (const_string "sselog1")
3499 ]
3500 (const_string "ssemov")))
3501 (set (attr "modrm")
3502 (if_then_else (eq_attr "alternative" "11")
3503 (const_string "0")
3504 (const_string "*")))
3505 (set (attr "length_immediate")
3506 (if_then_else (eq_attr "alternative" "11")
3507 (const_string "8")
3508 (const_string "*")))
3509 (set (attr "prefix")
3510 (if_then_else (eq_attr "type" "sselog1,ssemov")
3511 (const_string "maybe_vex")
3512 (const_string "orig")))
3513 (set (attr "prefix_data16")
3514 (if_then_else
3515 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3516 (eq_attr "mode" "V1DF"))
3517 (const_string "1")
3518 (const_string "*")))
3519 (set (attr "mode")
3520 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3521 (const_string "SI")
3522 (eq_attr "alternative" "8,9,11,20,21,24,25")
3523 (const_string "DI")
3524
3525 /* xorps is one byte shorter for non-AVX targets. */
3526 (eq_attr "alternative" "12,16")
3527 (cond [(not (match_test "TARGET_SSE2"))
3528 (const_string "V4SF")
3529 (and (match_test "TARGET_AVX512F")
3530 (not (match_test "TARGET_PREFER_AVX256")))
3531 (const_string "XI")
3532 (match_test "TARGET_AVX")
3533 (const_string "V2DF")
3534 (match_test "optimize_function_for_size_p (cfun)")
3535 (const_string "V4SF")
3536 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3537 (const_string "TI")
3538 ]
3539 (const_string "V2DF"))
3540
3541 /* For architectures resolving dependencies on
3542 whole SSE registers use movapd to break dependency
3543 chains, otherwise use short move to avoid extra work. */
3544
3545 /* movaps is one byte shorter for non-AVX targets. */
3546 (eq_attr "alternative" "13,17")
3547 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3548 (not (match_test "TARGET_AVX512VL")))
3549 (ior (match_operand 0 "ext_sse_reg_operand")
3550 (match_operand 1 "ext_sse_reg_operand")))
3551 (const_string "V8DF")
3552 (ior (not (match_test "TARGET_SSE2"))
3553 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3554 (const_string "V4SF")
3555 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3556 (const_string "V2DF")
3557 (match_test "TARGET_AVX")
3558 (const_string "DF")
3559 (match_test "optimize_function_for_size_p (cfun)")
3560 (const_string "V4SF")
3561 ]
3562 (const_string "DF"))
3563
3564 /* For architectures resolving dependencies on register
3565 parts we may avoid extra work to zero out upper part
3566 of register. */
3567 (eq_attr "alternative" "14,18")
3568 (cond [(not (match_test "TARGET_SSE2"))
3569 (const_string "V2SF")
3570 (match_test "TARGET_AVX")
3571 (const_string "DF")
3572 (match_test "TARGET_SSE_SPLIT_REGS")
3573 (const_string "V1DF")
3574 ]
3575 (const_string "DF"))
3576
3577 (and (eq_attr "alternative" "15,19")
3578 (not (match_test "TARGET_SSE2")))
3579 (const_string "V2SF")
3580 ]
3581 (const_string "DF")))
3582 (set (attr "preferred_for_size")
3583 (cond [(eq_attr "alternative" "3,4")
3584 (symbol_ref "false")]
3585 (symbol_ref "true")))
3586 (set (attr "preferred_for_speed")
3587 (cond [(eq_attr "alternative" "3,4")
3588 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3589 (eq_attr "alternative" "20")
3590 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3591 (eq_attr "alternative" "21")
3592 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3593 ]
3594 (symbol_ref "true")))
3595 (set (attr "enabled")
3596 (cond [(eq_attr "alternative" "22,23,24,25")
3597 (if_then_else
3598 (match_test "TARGET_HARD_DF_REGS")
3599 (symbol_ref "false")
3600 (const_string "*"))
3601 (not (match_test "TARGET_HARD_DF_REGS"))
3602 (symbol_ref "false")
3603 ]
3604 (const_string "*")))])
3605
3606 (define_split
3607 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3608 (match_operand:DF 1 "general_gr_operand"))]
3609 "!TARGET_64BIT && reload_completed"
3610 [(const_int 0)]
3611 "ix86_split_long_move (operands); DONE;")
3612
3613 (define_insn "*movsf_internal"
3614 [(set (match_operand:SF 0 "nonimmediate_operand"
3615 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3616 (match_operand:SF 1 "general_operand"
3617 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3618 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3619 && (lra_in_progress || reload_completed
3620 || !CONST_DOUBLE_P (operands[1])
3621 || ((optimize_function_for_size_p (cfun)
3622 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3623 && ((IS_STACK_MODE (SFmode)
3624 && standard_80387_constant_p (operands[1]) > 0)
3625 || (TARGET_SSE && TARGET_SSE_MATH
3626 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3627 || memory_operand (operands[0], SFmode)
3628 || !TARGET_HARD_SF_REGS)"
3629 {
3630 switch (get_attr_type (insn))
3631 {
3632 case TYPE_FMOV:
3633 if (which_alternative == 2)
3634 return standard_80387_constant_opcode (operands[1]);
3635 return output_387_reg_move (insn, operands);
3636
3637 case TYPE_IMOV:
3638 return "mov{l}\t{%1, %0|%0, %1}";
3639
3640 case TYPE_SSELOG1:
3641 return standard_sse_constant_opcode (insn, operands);
3642
3643 case TYPE_SSEMOV:
3644 switch (get_attr_mode (insn))
3645 {
3646 case MODE_SF:
3647 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3648 return "vmovss\t{%d1, %0|%0, %d1}";
3649 return "%vmovss\t{%1, %0|%0, %1}";
3650
3651 case MODE_V16SF:
3652 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3653 case MODE_V4SF:
3654 return "%vmovaps\t{%1, %0|%0, %1}";
3655
3656 case MODE_SI:
3657 return "%vmovd\t{%1, %0|%0, %1}";
3658
3659 default:
3660 gcc_unreachable ();
3661 }
3662
3663 case TYPE_MMXMOV:
3664 switch (get_attr_mode (insn))
3665 {
3666 case MODE_DI:
3667 return "movq\t{%1, %0|%0, %1}";
3668 case MODE_SI:
3669 return "movd\t{%1, %0|%0, %1}";
3670
3671 default:
3672 gcc_unreachable ();
3673 }
3674
3675 default:
3676 gcc_unreachable ();
3677 }
3678 }
3679 [(set (attr "isa")
3680 (cond [(eq_attr "alternative" "14,15")
3681 (const_string "sse2")
3682 ]
3683 (const_string "*")))
3684 (set (attr "type")
3685 (cond [(eq_attr "alternative" "0,1,2")
3686 (const_string "fmov")
3687 (eq_attr "alternative" "3,4,16,17")
3688 (const_string "imov")
3689 (eq_attr "alternative" "5")
3690 (const_string "sselog1")
3691 (eq_attr "alternative" "11,12,13,14,15")
3692 (const_string "mmxmov")
3693 ]
3694 (const_string "ssemov")))
3695 (set (attr "prefix")
3696 (if_then_else (eq_attr "type" "sselog1,ssemov")
3697 (const_string "maybe_vex")
3698 (const_string "orig")))
3699 (set (attr "prefix_data16")
3700 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3701 (const_string "1")
3702 (const_string "*")))
3703 (set (attr "mode")
3704 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3705 (const_string "SI")
3706 (eq_attr "alternative" "11")
3707 (const_string "DI")
3708 (eq_attr "alternative" "5")
3709 (cond [(not (match_test "TARGET_SSE2"))
3710 (const_string "V4SF")
3711 (and (match_test "TARGET_AVX512F")
3712 (not (match_test "TARGET_PREFER_AVX256")))
3713 (const_string "V16SF")
3714 (match_test "TARGET_AVX")
3715 (const_string "V4SF")
3716 (match_test "optimize_function_for_size_p (cfun)")
3717 (const_string "V4SF")
3718 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3719 (const_string "TI")
3720 ]
3721 (const_string "V4SF"))
3722
3723 /* For architectures resolving dependencies on
3724 whole SSE registers use APS move to break dependency
3725 chains, otherwise use short move to avoid extra work.
3726
3727 Do the same for architectures resolving dependencies on
3728 the parts. While in DF mode it is better to always handle
3729 just register parts, the SF mode is different due to lack
3730 of instructions to load just part of the register. It is
3731 better to maintain the whole registers in single format
3732 to avoid problems on using packed logical operations. */
3733 (eq_attr "alternative" "6")
3734 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3735 (not (match_test "TARGET_AVX512VL")))
3736 (ior (match_operand 0 "ext_sse_reg_operand")
3737 (match_operand 1 "ext_sse_reg_operand")))
3738 (const_string "V16SF")
3739 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3740 (match_test "TARGET_SSE_SPLIT_REGS"))
3741 (const_string "V4SF")
3742 ]
3743 (const_string "SF"))
3744 ]
3745 (const_string "SF")))
3746 (set (attr "preferred_for_speed")
3747 (cond [(eq_attr "alternative" "9,14")
3748 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3749 (eq_attr "alternative" "10,15")
3750 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3751 ]
3752 (symbol_ref "true")))
3753 (set (attr "enabled")
3754 (cond [(eq_attr "alternative" "16,17")
3755 (if_then_else
3756 (match_test "TARGET_HARD_SF_REGS")
3757 (symbol_ref "false")
3758 (const_string "*"))
3759 (not (match_test "TARGET_HARD_SF_REGS"))
3760 (symbol_ref "false")
3761 ]
3762 (const_string "*")))])
3763
3764 (define_split
3765 [(set (match_operand 0 "any_fp_register_operand")
3766 (match_operand 1 "memory_operand"))]
3767 "reload_completed
3768 && (GET_MODE (operands[0]) == TFmode
3769 || GET_MODE (operands[0]) == XFmode
3770 || GET_MODE (operands[0]) == DFmode
3771 || GET_MODE (operands[0]) == SFmode)
3772 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3773 [(set (match_dup 0) (match_dup 2))]
3774 "operands[2] = find_constant_src (curr_insn);")
3775
3776 (define_split
3777 [(set (match_operand 0 "any_fp_register_operand")
3778 (float_extend (match_operand 1 "memory_operand")))]
3779 "reload_completed
3780 && (GET_MODE (operands[0]) == TFmode
3781 || GET_MODE (operands[0]) == XFmode
3782 || GET_MODE (operands[0]) == DFmode)
3783 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3784 [(set (match_dup 0) (match_dup 2))]
3785 "operands[2] = find_constant_src (curr_insn);")
3786
3787 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3788 (define_split
3789 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3790 (match_operand:X87MODEF 1 "immediate_operand"))]
3791 "reload_completed
3792 && (standard_80387_constant_p (operands[1]) == 8
3793 || standard_80387_constant_p (operands[1]) == 9)"
3794 [(set (match_dup 0)(match_dup 1))
3795 (set (match_dup 0)
3796 (neg:X87MODEF (match_dup 0)))]
3797 {
3798 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3799 operands[1] = CONST0_RTX (<MODE>mode);
3800 else
3801 operands[1] = CONST1_RTX (<MODE>mode);
3802 })
3803
3804 (define_insn "*swapxf"
3805 [(set (match_operand:XF 0 "register_operand" "+f")
3806 (match_operand:XF 1 "register_operand" "+f"))
3807 (set (match_dup 1)
3808 (match_dup 0))]
3809 "TARGET_80387"
3810 {
3811 if (STACK_TOP_P (operands[0]))
3812 return "fxch\t%1";
3813 else
3814 return "fxch\t%0";
3815 }
3816 [(set_attr "type" "fxch")
3817 (set_attr "mode" "XF")])
3818 \f
3819
3820 ;; Zero extension instructions
3821
3822 (define_expand "zero_extendsidi2"
3823 [(set (match_operand:DI 0 "nonimmediate_operand")
3824 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3825
3826 (define_insn "*zero_extendsidi2"
3827 [(set (match_operand:DI 0 "nonimmediate_operand"
3828 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
3829 (zero_extend:DI
3830 (match_operand:SI 1 "x86_64_zext_operand"
3831 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
3832 ""
3833 {
3834 switch (get_attr_type (insn))
3835 {
3836 case TYPE_IMOVX:
3837 if (ix86_use_lea_for_mov (insn, operands))
3838 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3839 else
3840 return "mov{l}\t{%1, %k0|%k0, %1}";
3841
3842 case TYPE_MULTI:
3843 return "#";
3844
3845 case TYPE_MMXMOV:
3846 return "movd\t{%1, %0|%0, %1}";
3847
3848 case TYPE_SSEMOV:
3849 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3850 {
3851 if (EXT_REX_SSE_REG_P (operands[0])
3852 || EXT_REX_SSE_REG_P (operands[1]))
3853 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3854 else
3855 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3856 }
3857
3858 if (GENERAL_REG_P (operands[0]))
3859 return "%vmovd\t{%1, %k0|%k0, %1}";
3860
3861 return "%vmovd\t{%1, %0|%0, %1}";
3862
3863 case TYPE_MSKMOV:
3864 return "kmovd\t{%1, %k0|%k0, %1}";
3865
3866 default:
3867 gcc_unreachable ();
3868 }
3869 }
3870 [(set (attr "isa")
3871 (cond [(eq_attr "alternative" "0,1,2")
3872 (const_string "nox64")
3873 (eq_attr "alternative" "3")
3874 (const_string "x64")
3875 (eq_attr "alternative" "7,8,9")
3876 (const_string "sse2")
3877 (eq_attr "alternative" "10")
3878 (const_string "sse4")
3879 (eq_attr "alternative" "11")
3880 (const_string "avx512f")
3881 (eq_attr "alternative" "12")
3882 (const_string "x64_avx512bw")
3883 (eq_attr "alternative" "13")
3884 (const_string "avx512bw")
3885 ]
3886 (const_string "*")))
3887 (set (attr "mmx_isa")
3888 (if_then_else (eq_attr "alternative" "5,6")
3889 (const_string "native")
3890 (const_string "*")))
3891 (set (attr "type")
3892 (cond [(eq_attr "alternative" "0,1,2,4")
3893 (const_string "multi")
3894 (eq_attr "alternative" "5,6")
3895 (const_string "mmxmov")
3896 (eq_attr "alternative" "7")
3897 (if_then_else (match_test "TARGET_64BIT")
3898 (const_string "ssemov")
3899 (const_string "multi"))
3900 (eq_attr "alternative" "8,9,10,11")
3901 (const_string "ssemov")
3902 (eq_attr "alternative" "12,13")
3903 (const_string "mskmov")
3904 ]
3905 (const_string "imovx")))
3906 (set (attr "prefix_extra")
3907 (if_then_else (eq_attr "alternative" "10,11")
3908 (const_string "1")
3909 (const_string "*")))
3910 (set (attr "prefix")
3911 (if_then_else (eq_attr "type" "ssemov")
3912 (const_string "maybe_vex")
3913 (const_string "orig")))
3914 (set (attr "prefix_0f")
3915 (if_then_else (eq_attr "type" "imovx")
3916 (const_string "0")
3917 (const_string "*")))
3918 (set (attr "mode")
3919 (cond [(eq_attr "alternative" "5,6")
3920 (const_string "DI")
3921 (and (eq_attr "alternative" "7")
3922 (match_test "TARGET_64BIT"))
3923 (const_string "TI")
3924 (eq_attr "alternative" "8,10,11")
3925 (const_string "TI")
3926 ]
3927 (const_string "SI")))
3928 (set (attr "preferred_for_speed")
3929 (cond [(eq_attr "alternative" "7")
3930 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3931 (eq_attr "alternative" "5,8")
3932 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3933 ]
3934 (symbol_ref "true")))])
3935
3936 (define_split
3937 [(set (match_operand:DI 0 "memory_operand")
3938 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3939 "reload_completed"
3940 [(set (match_dup 4) (const_int 0))]
3941 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3942
3943 (define_split
3944 [(set (match_operand:DI 0 "general_reg_operand")
3945 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3946 "!TARGET_64BIT && reload_completed
3947 && REGNO (operands[0]) == REGNO (operands[1])"
3948 [(set (match_dup 4) (const_int 0))]
3949 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3950
3951 (define_split
3952 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3953 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3954 "!TARGET_64BIT && reload_completed
3955 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3956 [(set (match_dup 3) (match_dup 1))
3957 (set (match_dup 4) (const_int 0))]
3958 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3959
3960 (define_mode_attr kmov_isa
3961 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3962
3963 (define_insn "zero_extend<mode>di2"
3964 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
3965 (zero_extend:DI
3966 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3967 "TARGET_64BIT"
3968 "@
3969 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3970 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
3971 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3972 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3973 (set_attr "type" "imovx,mskmov,mskmov")
3974 (set_attr "mode" "SI,<MODE>,<MODE>")])
3975
3976 (define_expand "zero_extend<mode>si2"
3977 [(set (match_operand:SI 0 "register_operand")
3978 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3979 ""
3980 {
3981 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3982 {
3983 operands[1] = force_reg (<MODE>mode, operands[1]);
3984 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3985 DONE;
3986 }
3987 })
3988
3989 (define_insn_and_split "zero_extend<mode>si2_and"
3990 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3991 (zero_extend:SI
3992 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3993 (clobber (reg:CC FLAGS_REG))]
3994 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3995 "#"
3996 "&& reload_completed"
3997 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3998 (clobber (reg:CC FLAGS_REG))])]
3999 {
4000 if (!REG_P (operands[1])
4001 || REGNO (operands[0]) != REGNO (operands[1]))
4002 {
4003 ix86_expand_clear (operands[0]);
4004
4005 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4006 emit_insn (gen_movstrict<mode>
4007 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4008 DONE;
4009 }
4010
4011 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4012 }
4013 [(set_attr "type" "alu1")
4014 (set_attr "mode" "SI")])
4015
4016 (define_insn "*zero_extend<mode>si2"
4017 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4018 (zero_extend:SI
4019 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4020 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4021 "@
4022 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4023 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4024 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4025 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4026 (set_attr "type" "imovx,mskmov,mskmov")
4027 (set_attr "mode" "SI,<MODE>,<MODE>")])
4028
4029 (define_expand "zero_extendqihi2"
4030 [(set (match_operand:HI 0 "register_operand")
4031 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4032 ""
4033 {
4034 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4035 {
4036 operands[1] = force_reg (QImode, operands[1]);
4037 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4038 DONE;
4039 }
4040 })
4041
4042 (define_insn_and_split "zero_extendqihi2_and"
4043 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4044 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4045 (clobber (reg:CC FLAGS_REG))]
4046 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4047 "#"
4048 "&& reload_completed"
4049 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4050 (clobber (reg:CC FLAGS_REG))])]
4051 {
4052 if (!REG_P (operands[1])
4053 || REGNO (operands[0]) != REGNO (operands[1]))
4054 {
4055 ix86_expand_clear (operands[0]);
4056
4057 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4058 emit_insn (gen_movstrictqi
4059 (gen_lowpart (QImode, operands[0]), operands[1]));
4060 DONE;
4061 }
4062
4063 operands[0] = gen_lowpart (SImode, operands[0]);
4064 }
4065 [(set_attr "type" "alu1")
4066 (set_attr "mode" "SI")])
4067
4068 ; zero extend to SImode to avoid partial register stalls
4069 (define_insn "*zero_extendqihi2"
4070 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4071 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4072 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4073 "@
4074 movz{bl|x}\t{%1, %k0|%k0, %1}
4075 kmovb\t{%1, %k0|%k0, %1}
4076 kmovb\t{%1, %0|%0, %1}"
4077 [(set_attr "isa" "*,avx512dq,avx512dq")
4078 (set_attr "type" "imovx,mskmov,mskmov")
4079 (set_attr "mode" "SI,QI,QI")])
4080 \f
4081 ;; Sign extension instructions
4082
4083 (define_expand "extendsidi2"
4084 [(set (match_operand:DI 0 "register_operand")
4085 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4086 ""
4087 {
4088 if (!TARGET_64BIT)
4089 {
4090 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4091 DONE;
4092 }
4093 })
4094
4095 (define_insn "*extendsidi2_rex64"
4096 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4097 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4098 "TARGET_64BIT"
4099 "@
4100 {cltq|cdqe}
4101 movs{lq|x}\t{%1, %0|%0, %1}"
4102 [(set_attr "type" "imovx")
4103 (set_attr "mode" "DI")
4104 (set_attr "prefix_0f" "0")
4105 (set_attr "modrm" "0,1")])
4106
4107 (define_insn "extendsidi2_1"
4108 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4109 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4110 (clobber (reg:CC FLAGS_REG))
4111 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4112 "!TARGET_64BIT"
4113 "#")
4114
4115 ;; Split the memory case. If the source register doesn't die, it will stay
4116 ;; this way, if it does die, following peephole2s take care of it.
4117 (define_split
4118 [(set (match_operand:DI 0 "memory_operand")
4119 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4120 (clobber (reg:CC FLAGS_REG))
4121 (clobber (match_operand:SI 2 "register_operand"))]
4122 "reload_completed"
4123 [(const_int 0)]
4124 {
4125 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4126
4127 emit_move_insn (operands[3], operands[1]);
4128
4129 /* Generate a cltd if possible and doing so it profitable. */
4130 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4131 && REGNO (operands[1]) == AX_REG
4132 && REGNO (operands[2]) == DX_REG)
4133 {
4134 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4135 }
4136 else
4137 {
4138 emit_move_insn (operands[2], operands[1]);
4139 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4140 }
4141 emit_move_insn (operands[4], operands[2]);
4142 DONE;
4143 })
4144
4145 ;; Peepholes for the case where the source register does die, after
4146 ;; being split with the above splitter.
4147 (define_peephole2
4148 [(set (match_operand:SI 0 "memory_operand")
4149 (match_operand:SI 1 "general_reg_operand"))
4150 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4151 (parallel [(set (match_dup 2)
4152 (ashiftrt:SI (match_dup 2) (const_int 31)))
4153 (clobber (reg:CC FLAGS_REG))])
4154 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4155 "REGNO (operands[1]) != REGNO (operands[2])
4156 && peep2_reg_dead_p (2, operands[1])
4157 && peep2_reg_dead_p (4, operands[2])
4158 && !reg_mentioned_p (operands[2], operands[3])"
4159 [(set (match_dup 0) (match_dup 1))
4160 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4161 (clobber (reg:CC FLAGS_REG))])
4162 (set (match_dup 3) (match_dup 1))])
4163
4164 (define_peephole2
4165 [(set (match_operand:SI 0 "memory_operand")
4166 (match_operand:SI 1 "general_reg_operand"))
4167 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4168 (ashiftrt:SI (match_dup 1) (const_int 31)))
4169 (clobber (reg:CC FLAGS_REG))])
4170 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4171 "/* cltd is shorter than sarl $31, %eax */
4172 !optimize_function_for_size_p (cfun)
4173 && REGNO (operands[1]) == AX_REG
4174 && REGNO (operands[2]) == DX_REG
4175 && peep2_reg_dead_p (2, operands[1])
4176 && peep2_reg_dead_p (3, operands[2])
4177 && !reg_mentioned_p (operands[2], operands[3])"
4178 [(set (match_dup 0) (match_dup 1))
4179 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4180 (clobber (reg:CC FLAGS_REG))])
4181 (set (match_dup 3) (match_dup 1))])
4182
4183 ;; Extend to register case. Optimize case where source and destination
4184 ;; registers match and cases where we can use cltd.
4185 (define_split
4186 [(set (match_operand:DI 0 "register_operand")
4187 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4188 (clobber (reg:CC FLAGS_REG))
4189 (clobber (match_scratch:SI 2))]
4190 "reload_completed"
4191 [(const_int 0)]
4192 {
4193 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4194
4195 if (REGNO (operands[3]) != REGNO (operands[1]))
4196 emit_move_insn (operands[3], operands[1]);
4197
4198 /* Generate a cltd if possible and doing so it profitable. */
4199 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4200 && REGNO (operands[3]) == AX_REG
4201 && REGNO (operands[4]) == DX_REG)
4202 {
4203 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4204 DONE;
4205 }
4206
4207 if (REGNO (operands[4]) != REGNO (operands[1]))
4208 emit_move_insn (operands[4], operands[1]);
4209
4210 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4211 DONE;
4212 })
4213
4214 (define_insn "extend<mode>di2"
4215 [(set (match_operand:DI 0 "register_operand" "=r")
4216 (sign_extend:DI
4217 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4218 "TARGET_64BIT"
4219 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4220 [(set_attr "type" "imovx")
4221 (set_attr "mode" "DI")])
4222
4223 (define_insn "extendhisi2"
4224 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4225 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4226 ""
4227 {
4228 switch (get_attr_prefix_0f (insn))
4229 {
4230 case 0:
4231 return "{cwtl|cwde}";
4232 default:
4233 return "movs{wl|x}\t{%1, %0|%0, %1}";
4234 }
4235 }
4236 [(set_attr "type" "imovx")
4237 (set_attr "mode" "SI")
4238 (set (attr "prefix_0f")
4239 ;; movsx is short decodable while cwtl is vector decoded.
4240 (if_then_else (and (eq_attr "cpu" "!k6")
4241 (eq_attr "alternative" "0"))
4242 (const_string "0")
4243 (const_string "1")))
4244 (set (attr "znver1_decode")
4245 (if_then_else (eq_attr "prefix_0f" "0")
4246 (const_string "double")
4247 (const_string "direct")))
4248 (set (attr "modrm")
4249 (if_then_else (eq_attr "prefix_0f" "0")
4250 (const_string "0")
4251 (const_string "1")))])
4252
4253 (define_insn "*extendhisi2_zext"
4254 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4255 (zero_extend:DI
4256 (sign_extend:SI
4257 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4258 "TARGET_64BIT"
4259 {
4260 switch (get_attr_prefix_0f (insn))
4261 {
4262 case 0:
4263 return "{cwtl|cwde}";
4264 default:
4265 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4266 }
4267 }
4268 [(set_attr "type" "imovx")
4269 (set_attr "mode" "SI")
4270 (set (attr "prefix_0f")
4271 ;; movsx is short decodable while cwtl is vector decoded.
4272 (if_then_else (and (eq_attr "cpu" "!k6")
4273 (eq_attr "alternative" "0"))
4274 (const_string "0")
4275 (const_string "1")))
4276 (set (attr "modrm")
4277 (if_then_else (eq_attr "prefix_0f" "0")
4278 (const_string "0")
4279 (const_string "1")))])
4280
4281 (define_insn "extendqisi2"
4282 [(set (match_operand:SI 0 "register_operand" "=r")
4283 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4284 ""
4285 "movs{bl|x}\t{%1, %0|%0, %1}"
4286 [(set_attr "type" "imovx")
4287 (set_attr "mode" "SI")])
4288
4289 (define_insn "*extendqisi2_zext"
4290 [(set (match_operand:DI 0 "register_operand" "=r")
4291 (zero_extend:DI
4292 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4293 "TARGET_64BIT"
4294 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4295 [(set_attr "type" "imovx")
4296 (set_attr "mode" "SI")])
4297
4298 (define_insn "extendqihi2"
4299 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4300 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4301 ""
4302 {
4303 switch (get_attr_prefix_0f (insn))
4304 {
4305 case 0:
4306 return "{cbtw|cbw}";
4307 default:
4308 return "movs{bw|x}\t{%1, %0|%0, %1}";
4309 }
4310 }
4311 [(set_attr "type" "imovx")
4312 (set_attr "mode" "HI")
4313 (set (attr "prefix_0f")
4314 ;; movsx is short decodable while cwtl is vector decoded.
4315 (if_then_else (and (eq_attr "cpu" "!k6")
4316 (eq_attr "alternative" "0"))
4317 (const_string "0")
4318 (const_string "1")))
4319 (set (attr "modrm")
4320 (if_then_else (eq_attr "prefix_0f" "0")
4321 (const_string "0")
4322 (const_string "1")))])
4323 \f
4324 ;; Conversions between float and double.
4325
4326 ;; These are all no-ops in the model used for the 80387.
4327 ;; So just emit moves.
4328
4329 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4330 (define_split
4331 [(set (match_operand:DF 0 "push_operand")
4332 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4333 "reload_completed"
4334 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4335 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4336
4337 (define_split
4338 [(set (match_operand:XF 0 "push_operand")
4339 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4340 "reload_completed"
4341 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4342 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4343 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4344
4345 (define_expand "extendsfdf2"
4346 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4347 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4348 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4349 {
4350 /* ??? Needed for compress_float_constant since all fp constants
4351 are TARGET_LEGITIMATE_CONSTANT_P. */
4352 if (CONST_DOUBLE_P (operands[1]))
4353 {
4354 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4355 && standard_80387_constant_p (operands[1]) > 0)
4356 {
4357 operands[1] = simplify_const_unary_operation
4358 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4359 emit_move_insn_1 (operands[0], operands[1]);
4360 DONE;
4361 }
4362 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4363 }
4364 })
4365
4366 (define_insn "*extendsfdf2"
4367 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
4368 (float_extend:DF
4369 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
4370 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4371 {
4372 switch (which_alternative)
4373 {
4374 case 0:
4375 case 1:
4376 return output_387_reg_move (insn, operands);
4377
4378 case 2:
4379 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
4380 case 3:
4381 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4382
4383 default:
4384 gcc_unreachable ();
4385 }
4386 }
4387 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4388 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4389 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
4390 (set_attr "mode" "SF,XF,DF,DF")
4391 (set (attr "enabled")
4392 (if_then_else
4393 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4394 (if_then_else
4395 (eq_attr "alternative" "0,1")
4396 (symbol_ref "TARGET_MIX_SSE_I387")
4397 (symbol_ref "true"))
4398 (if_then_else
4399 (eq_attr "alternative" "0,1")
4400 (symbol_ref "true")
4401 (symbol_ref "false"))))])
4402
4403 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4404 cvtss2sd:
4405 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4406 cvtps2pd xmm2,xmm1
4407 We do the conversion post reload to avoid producing of 128bit spills
4408 that might lead to ICE on 32bit target. The sequence unlikely combine
4409 anyway. */
4410 (define_split
4411 [(set (match_operand:DF 0 "sse_reg_operand")
4412 (float_extend:DF
4413 (match_operand:SF 1 "nonimmediate_operand")))]
4414 "TARGET_USE_VECTOR_FP_CONVERTS
4415 && optimize_insn_for_speed_p ()
4416 && reload_completed
4417 && (!EXT_REX_SSE_REG_P (operands[0])
4418 || TARGET_AVX512VL)"
4419 [(set (match_dup 2)
4420 (float_extend:V2DF
4421 (vec_select:V2SF
4422 (match_dup 3)
4423 (parallel [(const_int 0) (const_int 1)]))))]
4424 {
4425 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4426 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4427 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4428 Try to avoid move when unpacking can be done in source. */
4429 if (REG_P (operands[1]))
4430 {
4431 /* If it is unsafe to overwrite upper half of source, we need
4432 to move to destination and unpack there. */
4433 if (REGNO (operands[0]) != REGNO (operands[1])
4434 || (EXT_REX_SSE_REG_P (operands[1])
4435 && !TARGET_AVX512VL))
4436 {
4437 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4438 emit_move_insn (tmp, operands[1]);
4439 }
4440 else
4441 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4442 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4443 =v, v, then vbroadcastss will be only needed for AVX512F without
4444 AVX512VL. */
4445 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4446 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4447 operands[3]));
4448 else
4449 {
4450 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4451 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4452 }
4453 }
4454 else
4455 emit_insn (gen_vec_setv4sf_0 (operands[3],
4456 CONST0_RTX (V4SFmode), operands[1]));
4457 })
4458
4459 ;; It's more profitable to split and then extend in the same register.
4460 (define_peephole2
4461 [(set (match_operand:DF 0 "sse_reg_operand")
4462 (float_extend:DF
4463 (match_operand:SF 1 "memory_operand")))]
4464 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4465 && optimize_insn_for_speed_p ()"
4466 [(set (match_dup 2) (match_dup 1))
4467 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4468 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4469
4470 ;; Break partial SSE register dependency stall. This splitter should split
4471 ;; late in the pass sequence (after register rename pass), so allocated
4472 ;; registers won't change anymore
4473
4474 (define_split
4475 [(set (match_operand:DF 0 "sse_reg_operand")
4476 (float_extend:DF
4477 (match_operand:SF 1 "nonimmediate_operand")))]
4478 "!TARGET_AVX
4479 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4480 && optimize_function_for_speed_p (cfun)
4481 && (!REG_P (operands[1])
4482 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4483 && (!EXT_REX_SSE_REG_P (operands[0])
4484 || TARGET_AVX512VL)"
4485 [(set (match_dup 0)
4486 (vec_merge:V2DF
4487 (vec_duplicate:V2DF
4488 (float_extend:DF
4489 (match_dup 1)))
4490 (match_dup 0)
4491 (const_int 1)))]
4492 {
4493 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4494 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4495 })
4496
4497 (define_expand "extend<mode>xf2"
4498 [(set (match_operand:XF 0 "nonimmediate_operand")
4499 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4500 "TARGET_80387"
4501 {
4502 /* ??? Needed for compress_float_constant since all fp constants
4503 are TARGET_LEGITIMATE_CONSTANT_P. */
4504 if (CONST_DOUBLE_P (operands[1]))
4505 {
4506 if (standard_80387_constant_p (operands[1]) > 0)
4507 {
4508 operands[1] = simplify_const_unary_operation
4509 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4510 emit_move_insn_1 (operands[0], operands[1]);
4511 DONE;
4512 }
4513 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4514 }
4515 })
4516
4517 (define_insn "*extend<mode>xf2_i387"
4518 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4519 (float_extend:XF
4520 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4521 "TARGET_80387"
4522 "* return output_387_reg_move (insn, operands);"
4523 [(set_attr "type" "fmov")
4524 (set_attr "mode" "<MODE>,XF")])
4525
4526 ;; %%% This seems like bad news.
4527 ;; This cannot output into an f-reg because there is no way to be sure
4528 ;; of truncating in that case. Otherwise this is just like a simple move
4529 ;; insn. So we pretend we can output to a reg in order to get better
4530 ;; register preferencing, but we really use a stack slot.
4531
4532 ;; Conversion from DFmode to SFmode.
4533
4534 (define_insn "truncdfsf2"
4535 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
4536 (float_truncate:SF
4537 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
4538 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4539 {
4540 switch (which_alternative)
4541 {
4542 case 0:
4543 case 1:
4544 return output_387_reg_move (insn, operands);
4545
4546 case 2:
4547 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
4548 case 3:
4549 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4550
4551 default:
4552 gcc_unreachable ();
4553 }
4554 }
4555 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4556 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4557 (set_attr "mode" "SF")
4558 (set (attr "enabled")
4559 (if_then_else
4560 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4561 (cond [(eq_attr "alternative" "0")
4562 (symbol_ref "TARGET_MIX_SSE_I387")
4563 (eq_attr "alternative" "1")
4564 (symbol_ref "TARGET_MIX_SSE_I387
4565 && flag_unsafe_math_optimizations")
4566 ]
4567 (symbol_ref "true"))
4568 (cond [(eq_attr "alternative" "0")
4569 (symbol_ref "true")
4570 (eq_attr "alternative" "1")
4571 (symbol_ref "flag_unsafe_math_optimizations")
4572 ]
4573 (symbol_ref "false"))))])
4574
4575 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4576 cvtsd2ss:
4577 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4578 cvtpd2ps xmm2,xmm1
4579 We do the conversion post reload to avoid producing of 128bit spills
4580 that might lead to ICE on 32bit target. The sequence unlikely combine
4581 anyway. */
4582 (define_split
4583 [(set (match_operand:SF 0 "sse_reg_operand")
4584 (float_truncate:SF
4585 (match_operand:DF 1 "nonimmediate_operand")))]
4586 "TARGET_USE_VECTOR_FP_CONVERTS
4587 && optimize_insn_for_speed_p ()
4588 && reload_completed
4589 && (!EXT_REX_SSE_REG_P (operands[0])
4590 || TARGET_AVX512VL)"
4591 [(set (match_dup 2)
4592 (vec_concat:V4SF
4593 (float_truncate:V2SF
4594 (match_dup 4))
4595 (match_dup 3)))]
4596 {
4597 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4598 operands[3] = CONST0_RTX (V2SFmode);
4599 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4600 /* Use movsd for loading from memory, unpcklpd for registers.
4601 Try to avoid move when unpacking can be done in source, or SSE3
4602 movddup is available. */
4603 if (REG_P (operands[1]))
4604 {
4605 if (!TARGET_SSE3
4606 && REGNO (operands[0]) != REGNO (operands[1]))
4607 {
4608 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4609 emit_move_insn (tmp, operands[1]);
4610 operands[1] = tmp;
4611 }
4612 else if (!TARGET_SSE3)
4613 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4614 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4615 }
4616 else
4617 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4618 CONST0_RTX (DFmode)));
4619 })
4620
4621 ;; It's more profitable to split and then truncate in the same register.
4622 (define_peephole2
4623 [(set (match_operand:SF 0 "sse_reg_operand")
4624 (float_truncate:SF
4625 (match_operand:DF 1 "memory_operand")))]
4626 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4627 && optimize_insn_for_speed_p ()"
4628 [(set (match_dup 2) (match_dup 1))
4629 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4630 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4631
4632 ;; Break partial SSE register dependency stall. This splitter should split
4633 ;; late in the pass sequence (after register rename pass), so allocated
4634 ;; registers won't change anymore
4635
4636 (define_split
4637 [(set (match_operand:SF 0 "sse_reg_operand")
4638 (float_truncate:SF
4639 (match_operand:DF 1 "nonimmediate_operand")))]
4640 "!TARGET_AVX
4641 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4642 && optimize_function_for_speed_p (cfun)
4643 && (!REG_P (operands[1])
4644 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4645 && (!EXT_REX_SSE_REG_P (operands[0])
4646 || TARGET_AVX512VL)"
4647 [(set (match_dup 0)
4648 (vec_merge:V4SF
4649 (vec_duplicate:V4SF
4650 (float_truncate:SF
4651 (match_dup 1)))
4652 (match_dup 0)
4653 (const_int 1)))]
4654 {
4655 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4656 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4657 })
4658
4659 ;; Conversion from XFmode to {SF,DF}mode
4660
4661 (define_insn "truncxf<mode>2"
4662 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
4663 (float_truncate:MODEF
4664 (match_operand:XF 1 "register_operand" "f,f")))]
4665 "TARGET_80387"
4666 "* return output_387_reg_move (insn, operands);"
4667 [(set_attr "type" "fmov")
4668 (set_attr "mode" "<MODE>")
4669 (set (attr "enabled")
4670 (cond [(eq_attr "alternative" "1")
4671 (symbol_ref "flag_unsafe_math_optimizations")
4672 ]
4673 (symbol_ref "true")))])
4674 \f
4675 ;; Signed conversion to DImode.
4676
4677 (define_expand "fix_truncxfdi2"
4678 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4679 (fix:DI (match_operand:XF 1 "register_operand")))
4680 (clobber (reg:CC FLAGS_REG))])]
4681 "TARGET_80387"
4682 {
4683 if (TARGET_FISTTP)
4684 {
4685 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4686 DONE;
4687 }
4688 })
4689
4690 (define_expand "fix_trunc<mode>di2"
4691 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4692 (fix:DI (match_operand:MODEF 1 "register_operand")))
4693 (clobber (reg:CC FLAGS_REG))])]
4694 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4695 {
4696 if (TARGET_FISTTP
4697 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4698 {
4699 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4700 DONE;
4701 }
4702 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4703 {
4704 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4705 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4706 if (out != operands[0])
4707 emit_move_insn (operands[0], out);
4708 DONE;
4709 }
4710 })
4711
4712 ;; Signed conversion to SImode.
4713
4714 (define_expand "fix_truncxfsi2"
4715 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4716 (fix:SI (match_operand:XF 1 "register_operand")))
4717 (clobber (reg:CC FLAGS_REG))])]
4718 "TARGET_80387"
4719 {
4720 if (TARGET_FISTTP)
4721 {
4722 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4723 DONE;
4724 }
4725 })
4726
4727 (define_expand "fix_trunc<mode>si2"
4728 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4729 (fix:SI (match_operand:MODEF 1 "register_operand")))
4730 (clobber (reg:CC FLAGS_REG))])]
4731 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4732 {
4733 if (TARGET_FISTTP
4734 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4735 {
4736 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4737 DONE;
4738 }
4739 if (SSE_FLOAT_MODE_P (<MODE>mode))
4740 {
4741 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4742 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4743 if (out != operands[0])
4744 emit_move_insn (operands[0], out);
4745 DONE;
4746 }
4747 })
4748
4749 ;; Signed conversion to HImode.
4750
4751 (define_expand "fix_trunc<mode>hi2"
4752 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4753 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4754 (clobber (reg:CC FLAGS_REG))])]
4755 "TARGET_80387
4756 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4757 {
4758 if (TARGET_FISTTP)
4759 {
4760 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
4761 DONE;
4762 }
4763 })
4764
4765 ;; Unsigned conversion to DImode
4766
4767 (define_insn "fixuns_trunc<mode>di2"
4768 [(set (match_operand:DI 0 "register_operand" "=r")
4769 (unsigned_fix:DI
4770 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4771 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4772 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4773 [(set_attr "type" "sseicvt")
4774 (set_attr "prefix" "evex")
4775 (set_attr "mode" "DI")])
4776
4777 ;; Unsigned conversion to SImode.
4778
4779 (define_expand "fixuns_trunc<mode>si2"
4780 [(parallel
4781 [(set (match_operand:SI 0 "register_operand")
4782 (unsigned_fix:SI
4783 (match_operand:MODEF 1 "nonimmediate_operand")))
4784 (use (match_dup 2))
4785 (clobber (match_scratch:<ssevecmode> 3))
4786 (clobber (match_scratch:<ssevecmode> 4))])]
4787 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
4788 {
4789 machine_mode mode = <MODE>mode;
4790 machine_mode vecmode = <ssevecmode>mode;
4791 REAL_VALUE_TYPE TWO31r;
4792 rtx two31;
4793
4794 if (TARGET_AVX512F)
4795 {
4796 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
4797 DONE;
4798 }
4799
4800 if (optimize_insn_for_size_p ())
4801 FAIL;
4802
4803 real_ldexp (&TWO31r, &dconst1, 31);
4804 two31 = const_double_from_real_value (TWO31r, mode);
4805 two31 = ix86_build_const_vector (vecmode, true, two31);
4806 operands[2] = force_reg (vecmode, two31);
4807 })
4808
4809 (define_insn "fixuns_trunc<mode>si2_avx512f"
4810 [(set (match_operand:SI 0 "register_operand" "=r")
4811 (unsigned_fix:SI
4812 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4813 "TARGET_AVX512F && TARGET_SSE_MATH"
4814 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4815 [(set_attr "type" "sseicvt")
4816 (set_attr "prefix" "evex")
4817 (set_attr "mode" "SI")])
4818
4819 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
4820 [(set (match_operand:DI 0 "register_operand" "=r")
4821 (zero_extend:DI
4822 (unsigned_fix:SI
4823 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
4824 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4825 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
4826 [(set_attr "type" "sseicvt")
4827 (set_attr "prefix" "evex")
4828 (set_attr "mode" "SI")])
4829
4830 (define_insn_and_split "*fixuns_trunc<mode>_1"
4831 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4832 (unsigned_fix:SI
4833 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4834 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4835 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4836 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4837 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4838 && optimize_function_for_speed_p (cfun)"
4839 "#"
4840 "&& reload_completed"
4841 [(const_int 0)]
4842 {
4843 ix86_split_convert_uns_si_sse (operands);
4844 DONE;
4845 })
4846
4847 ;; Unsigned conversion to HImode.
4848 ;; Without these patterns, we'll try the unsigned SI conversion which
4849 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4850
4851 (define_expand "fixuns_trunc<mode>hi2"
4852 [(set (match_dup 2)
4853 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4854 (set (match_operand:HI 0 "nonimmediate_operand")
4855 (subreg:HI (match_dup 2) 0))]
4856 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4857 "operands[2] = gen_reg_rtx (SImode);")
4858
4859 ;; When SSE is available, it is always faster to use it!
4860 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4861 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4862 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4863 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4864 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4865 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4866 [(set_attr "type" "sseicvt")
4867 (set_attr "prefix" "maybe_vex")
4868 (set (attr "prefix_rex")
4869 (if_then_else
4870 (match_test "<SWI48:MODE>mode == DImode")
4871 (const_string "1")
4872 (const_string "*")))
4873 (set_attr "mode" "<MODEF:MODE>")
4874 (set_attr "athlon_decode" "double,vector")
4875 (set_attr "amdfam10_decode" "double,double")
4876 (set_attr "bdver1_decode" "double,double")])
4877
4878 ;; Avoid vector decoded forms of the instruction.
4879 (define_peephole2
4880 [(match_scratch:MODEF 2 "x")
4881 (set (match_operand:SWI48 0 "register_operand")
4882 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4883 "TARGET_AVOID_VECTOR_DECODE
4884 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4885 && optimize_insn_for_speed_p ()"
4886 [(set (match_dup 2) (match_dup 1))
4887 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4888
4889 (define_insn "fix_trunc<mode>_i387_fisttp"
4890 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
4891 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4892 (clobber (match_scratch:XF 2 "=&f"))]
4893 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4894 && TARGET_FISTTP
4895 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4896 && (TARGET_64BIT || <MODE>mode != DImode))
4897 && TARGET_SSE_MATH)"
4898 "* return output_fix_trunc (insn, operands, true);"
4899 [(set_attr "type" "fisttp")
4900 (set_attr "mode" "<MODE>")])
4901
4902 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4903 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4904 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4905 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4906 ;; function in i386.c.
4907 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4908 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4909 (fix:SWI248x (match_operand 1 "register_operand")))
4910 (clobber (reg:CC FLAGS_REG))]
4911 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4912 && !TARGET_FISTTP
4913 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4914 && (TARGET_64BIT || <MODE>mode != DImode))
4915 && can_create_pseudo_p ()"
4916 "#"
4917 "&& 1"
4918 [(const_int 0)]
4919 {
4920 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4921
4922 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4923 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4924
4925 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4926 operands[2], operands[3]));
4927 DONE;
4928 }
4929 [(set_attr "type" "fistp")
4930 (set_attr "i387_cw" "trunc")
4931 (set_attr "mode" "<MODE>")])
4932
4933 (define_insn "fix_truncdi_i387"
4934 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
4935 (fix:DI (match_operand 1 "register_operand" "f")))
4936 (use (match_operand:HI 2 "memory_operand" "m"))
4937 (use (match_operand:HI 3 "memory_operand" "m"))
4938 (clobber (match_scratch:XF 4 "=&f"))]
4939 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4940 && !TARGET_FISTTP
4941 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4942 "* return output_fix_trunc (insn, operands, false);"
4943 [(set_attr "type" "fistp")
4944 (set_attr "i387_cw" "trunc")
4945 (set_attr "mode" "DI")])
4946
4947 (define_insn "fix_trunc<mode>_i387"
4948 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
4949 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4950 (use (match_operand:HI 2 "memory_operand" "m"))
4951 (use (match_operand:HI 3 "memory_operand" "m"))]
4952 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4953 && !TARGET_FISTTP
4954 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4955 "* return output_fix_trunc (insn, operands, false);"
4956 [(set_attr "type" "fistp")
4957 (set_attr "i387_cw" "trunc")
4958 (set_attr "mode" "<MODE>")])
4959
4960 (define_insn "x86_fnstcw_1"
4961 [(set (match_operand:HI 0 "memory_operand" "=m")
4962 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
4963 "TARGET_80387"
4964 "fnstcw\t%0"
4965 [(set (attr "length")
4966 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4967 (set_attr "mode" "HI")
4968 (set_attr "unit" "i387")
4969 (set_attr "bdver1_decode" "vector")])
4970 \f
4971 ;; Conversion between fixed point and floating point.
4972
4973 ;; Even though we only accept memory inputs, the backend _really_
4974 ;; wants to be able to do this between registers. Thankfully, LRA
4975 ;; will fix this up for us during register allocation.
4976
4977 (define_insn "floathi<mode>2"
4978 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4979 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4980 "TARGET_80387
4981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4982 || TARGET_MIX_SSE_I387)"
4983 "fild%Z1\t%1"
4984 [(set_attr "type" "fmov")
4985 (set_attr "mode" "<MODE>")
4986 (set_attr "znver1_decode" "double")
4987 (set_attr "fp_int_src" "true")])
4988
4989 (define_insn "float<SWI48x:mode>xf2"
4990 [(set (match_operand:XF 0 "register_operand" "=f")
4991 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4992 "TARGET_80387"
4993 "fild%Z1\t%1"
4994 [(set_attr "type" "fmov")
4995 (set_attr "mode" "XF")
4996 (set_attr "znver1_decode" "double")
4997 (set_attr "fp_int_src" "true")])
4998
4999 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5000 [(set (match_operand:MODEF 0 "register_operand")
5001 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5002 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5003 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5004 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5005
5006 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5007 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5008 (float:MODEF
5009 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5010 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5011 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5012 "@
5013 fild%Z1\t%1
5014 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5015 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5016 [(set_attr "type" "fmov,sseicvt,sseicvt")
5017 (set_attr "avx_partial_xmm_update" "false,true,true")
5018 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5019 (set_attr "mode" "<MODEF:MODE>")
5020 (set (attr "prefix_rex")
5021 (if_then_else
5022 (and (eq_attr "prefix" "maybe_vex")
5023 (match_test "<SWI48:MODE>mode == DImode"))
5024 (const_string "1")
5025 (const_string "*")))
5026 (set_attr "unit" "i387,*,*")
5027 (set_attr "athlon_decode" "*,double,direct")
5028 (set_attr "amdfam10_decode" "*,vector,double")
5029 (set_attr "bdver1_decode" "*,double,direct")
5030 (set_attr "znver1_decode" "double,*,*")
5031 (set_attr "fp_int_src" "true")
5032 (set (attr "enabled")
5033 (if_then_else
5034 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5035 (if_then_else
5036 (eq_attr "alternative" "0")
5037 (symbol_ref "TARGET_MIX_SSE_I387
5038 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5039 <SWI48:MODE>mode)")
5040 (symbol_ref "true"))
5041 (if_then_else
5042 (eq_attr "alternative" "0")
5043 (symbol_ref "true")
5044 (symbol_ref "false"))))
5045 (set (attr "preferred_for_speed")
5046 (cond [(eq_attr "alternative" "1")
5047 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5048 (symbol_ref "true")))])
5049
5050 (define_insn "*floatdi<MODEF:mode>2_i387"
5051 [(set (match_operand:MODEF 0 "register_operand" "=f")
5052 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5053 "!TARGET_64BIT
5054 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5055 "fild%Z1\t%1"
5056 [(set_attr "type" "fmov")
5057 (set_attr "mode" "<MODEF:MODE>")
5058 (set_attr "znver1_decode" "double")
5059 (set_attr "fp_int_src" "true")])
5060
5061 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5062 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5063 ;; alternative in sse2_loadld.
5064 (define_split
5065 [(set (match_operand:MODEF 0 "sse_reg_operand")
5066 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5067 "TARGET_SSE2
5068 && TARGET_USE_VECTOR_CONVERTS
5069 && optimize_function_for_speed_p (cfun)
5070 && reload_completed
5071 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5072 && (!EXT_REX_SSE_REG_P (operands[0])
5073 || TARGET_AVX512VL)"
5074 [(const_int 0)]
5075 {
5076 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5077 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5078
5079 emit_insn (gen_sse2_loadld (operands[4],
5080 CONST0_RTX (V4SImode), operands[1]));
5081
5082 if (<ssevecmode>mode == V4SFmode)
5083 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5084 else
5085 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5086 DONE;
5087 })
5088
5089 ;; Avoid store forwarding (partial memory) stall penalty
5090 ;; by passing DImode value through XMM registers. */
5091
5092 (define_split
5093 [(set (match_operand:X87MODEF 0 "register_operand")
5094 (float:X87MODEF
5095 (match_operand:DI 1 "register_operand")))]
5096 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5097 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5098 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5099 && can_create_pseudo_p ()"
5100 [(const_int 0)]
5101 {
5102 emit_insn (gen_floatdi<mode>2_i387_with_xmm
5103 (operands[0], operands[1],
5104 assign_386_stack_local (DImode, SLOT_TEMP)));
5105 DONE;
5106 })
5107
5108 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5109 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5110 (float:X87MODEF
5111 (match_operand:DI 1 "register_operand" "r,r")))
5112 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5113 (clobber (match_scratch:V4SI 3 "=x,x"))
5114 (clobber (match_scratch:V4SI 4 "=X,x"))]
5115 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5116 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5117 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5118 "#"
5119 "&& reload_completed"
5120 [(set (match_dup 2) (match_dup 3))
5121 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5122 {
5123 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5124 Assemble the 64-bit DImode value in an xmm register. */
5125 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5126 gen_lowpart (SImode, operands[1])));
5127 if (TARGET_SSE4_1)
5128 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5129 gen_highpart (SImode, operands[1]),
5130 GEN_INT (2)));
5131 else
5132 {
5133 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5134 gen_highpart (SImode, operands[1])));
5135 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5136 operands[4]));
5137 }
5138 operands[3] = gen_lowpart (DImode, operands[3]);
5139 }
5140 [(set_attr "isa" "sse4,*")
5141 (set_attr "type" "multi")
5142 (set_attr "mode" "<X87MODEF:MODE>")
5143 (set_attr "unit" "i387")
5144 (set_attr "fp_int_src" "true")])
5145
5146 ;; Break partial SSE register dependency stall. This splitter should split
5147 ;; late in the pass sequence (after register rename pass), so allocated
5148 ;; registers won't change anymore
5149
5150 (define_split
5151 [(set (match_operand:MODEF 0 "sse_reg_operand")
5152 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5153 "!TARGET_AVX
5154 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5155 && optimize_function_for_speed_p (cfun)
5156 && (!EXT_REX_SSE_REG_P (operands[0])
5157 || TARGET_AVX512VL)"
5158 [(set (match_dup 0)
5159 (vec_merge:<MODEF:ssevecmode>
5160 (vec_duplicate:<MODEF:ssevecmode>
5161 (float:MODEF
5162 (match_dup 1)))
5163 (match_dup 0)
5164 (const_int 1)))]
5165 {
5166 const machine_mode vmode = <MODEF:ssevecmode>mode;
5167
5168 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5169 emit_move_insn (operands[0], CONST0_RTX (vmode));
5170 })
5171
5172 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5173 [(set (match_operand:MODEF 0 "register_operand")
5174 (unsigned_float:MODEF
5175 (match_operand:SWI12 1 "nonimmediate_operand")))]
5176 "!TARGET_64BIT
5177 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5178 {
5179 operands[1] = convert_to_mode (SImode, operands[1], 1);
5180 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5181 DONE;
5182 })
5183
5184 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5185 [(set (match_operand:MODEF 0 "register_operand" "=v")
5186 (unsigned_float:MODEF
5187 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5188 "TARGET_AVX512F && TARGET_SSE_MATH"
5189 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5190 [(set_attr "type" "sseicvt")
5191 (set_attr "prefix" "evex")
5192 (set_attr "mode" "<MODEF:MODE>")])
5193
5194 ;; Avoid store forwarding (partial memory) stall penalty by extending
5195 ;; SImode value to DImode through XMM register instead of pushing two
5196 ;; SImode values to stack. Also note that fild loads from memory only.
5197
5198 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5199 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5200 (unsigned_float:X87MODEF
5201 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5202 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5203 (clobber (match_scratch:DI 3 "=x"))]
5204 "!TARGET_64BIT
5205 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5206 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5207 "#"
5208 "&& reload_completed"
5209 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5210 (set (match_dup 2) (match_dup 3))
5211 (set (match_dup 0)
5212 (float:X87MODEF (match_dup 2)))]
5213 ""
5214 [(set_attr "type" "multi")
5215 (set_attr "mode" "<MODE>")])
5216
5217 (define_expand "floatunssi<mode>2"
5218 [(set (match_operand:X87MODEF 0 "register_operand")
5219 (unsigned_float:X87MODEF
5220 (match_operand:SI 1 "nonimmediate_operand")))]
5221 "(!TARGET_64BIT
5222 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5223 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5224 || ((!TARGET_64BIT || TARGET_AVX512F)
5225 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5226 {
5227 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5228 {
5229 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5230 (operands[0], operands[1],
5231 assign_386_stack_local (DImode, SLOT_TEMP)));
5232 DONE;
5233 }
5234 if (!TARGET_AVX512F)
5235 {
5236 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5237 DONE;
5238 }
5239 })
5240
5241 (define_expand "floatunsdisf2"
5242 [(set (match_operand:SF 0 "register_operand")
5243 (unsigned_float:SF
5244 (match_operand:DI 1 "nonimmediate_operand")))]
5245 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5246 {
5247 if (!TARGET_AVX512F)
5248 {
5249 x86_emit_floatuns (operands);
5250 DONE;
5251 }
5252 })
5253
5254 (define_expand "floatunsdidf2"
5255 [(set (match_operand:DF 0 "register_operand")
5256 (unsigned_float:DF
5257 (match_operand:DI 1 "nonimmediate_operand")))]
5258 "((TARGET_64BIT && TARGET_AVX512F)
5259 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5260 && TARGET_SSE2 && TARGET_SSE_MATH"
5261 {
5262 if (!TARGET_64BIT)
5263 {
5264 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5265 DONE;
5266 }
5267 if (!TARGET_AVX512F)
5268 {
5269 x86_emit_floatuns (operands);
5270 DONE;
5271 }
5272 })
5273 \f
5274 ;; Load effective address instructions
5275
5276 (define_insn_and_split "*lea<mode>"
5277 [(set (match_operand:SWI48 0 "register_operand" "=r")
5278 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5279 ""
5280 {
5281 if (SImode_address_operand (operands[1], VOIDmode))
5282 {
5283 gcc_assert (TARGET_64BIT);
5284 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5285 }
5286 else
5287 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5288 }
5289 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5290 [(const_int 0)]
5291 {
5292 machine_mode mode = <MODE>mode;
5293 rtx pat;
5294
5295 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5296 change operands[] array behind our back. */
5297 pat = PATTERN (curr_insn);
5298
5299 operands[0] = SET_DEST (pat);
5300 operands[1] = SET_SRC (pat);
5301
5302 /* Emit all operations in SImode for zero-extended addresses. */
5303 if (SImode_address_operand (operands[1], VOIDmode))
5304 mode = SImode;
5305
5306 ix86_split_lea_for_addr (curr_insn, operands, mode);
5307
5308 /* Zero-extend return register to DImode for zero-extended addresses. */
5309 if (mode != <MODE>mode)
5310 emit_insn (gen_zero_extendsidi2
5311 (operands[0], gen_lowpart (mode, operands[0])));
5312
5313 DONE;
5314 }
5315 [(set_attr "type" "lea")
5316 (set (attr "mode")
5317 (if_then_else
5318 (match_operand 1 "SImode_address_operand")
5319 (const_string "SI")
5320 (const_string "<MODE>")))])
5321 \f
5322 ;; Add instructions
5323
5324 (define_expand "add<mode>3"
5325 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5326 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5327 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5328 ""
5329 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5330
5331 (define_insn_and_split "*add<dwi>3_doubleword"
5332 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5333 (plus:<DWI>
5334 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5335 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5336 "ro<di>,r<di>")))
5337 (clobber (reg:CC FLAGS_REG))]
5338 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5339 "#"
5340 "reload_completed"
5341 [(parallel [(set (reg:CCC FLAGS_REG)
5342 (compare:CCC
5343 (plus:DWIH (match_dup 1) (match_dup 2))
5344 (match_dup 1)))
5345 (set (match_dup 0)
5346 (plus:DWIH (match_dup 1) (match_dup 2)))])
5347 (parallel [(set (match_dup 3)
5348 (plus:DWIH
5349 (plus:DWIH
5350 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5351 (match_dup 4))
5352 (match_dup 5)))
5353 (clobber (reg:CC FLAGS_REG))])]
5354 {
5355 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5356 if (operands[2] == const0_rtx)
5357 {
5358 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5359 DONE;
5360 }
5361 })
5362
5363 (define_insn "*add<mode>_1"
5364 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5365 (plus:SWI48
5366 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5367 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5368 (clobber (reg:CC FLAGS_REG))]
5369 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5370 {
5371 switch (get_attr_type (insn))
5372 {
5373 case TYPE_LEA:
5374 return "#";
5375
5376 case TYPE_INCDEC:
5377 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5378 if (operands[2] == const1_rtx)
5379 return "inc{<imodesuffix>}\t%0";
5380 else
5381 {
5382 gcc_assert (operands[2] == constm1_rtx);
5383 return "dec{<imodesuffix>}\t%0";
5384 }
5385
5386 default:
5387 /* For most processors, ADD is faster than LEA. This alternative
5388 was added to use ADD as much as possible. */
5389 if (which_alternative == 2)
5390 std::swap (operands[1], operands[2]);
5391
5392 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5393 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5394 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5395
5396 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5397 }
5398 }
5399 [(set (attr "type")
5400 (cond [(eq_attr "alternative" "3")
5401 (const_string "lea")
5402 (match_operand:SWI48 2 "incdec_operand")
5403 (const_string "incdec")
5404 ]
5405 (const_string "alu")))
5406 (set (attr "length_immediate")
5407 (if_then_else
5408 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5409 (const_string "1")
5410 (const_string "*")))
5411 (set_attr "mode" "<MODE>")])
5412
5413 ;; It may seem that nonimmediate operand is proper one for operand 1.
5414 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5415 ;; we take care in ix86_binary_operator_ok to not allow two memory
5416 ;; operands so proper swapping will be done in reload. This allow
5417 ;; patterns constructed from addsi_1 to match.
5418
5419 (define_insn "addsi_1_zext"
5420 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5421 (zero_extend:DI
5422 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5423 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5424 (clobber (reg:CC FLAGS_REG))]
5425 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5426 {
5427 switch (get_attr_type (insn))
5428 {
5429 case TYPE_LEA:
5430 return "#";
5431
5432 case TYPE_INCDEC:
5433 if (operands[2] == const1_rtx)
5434 return "inc{l}\t%k0";
5435 else
5436 {
5437 gcc_assert (operands[2] == constm1_rtx);
5438 return "dec{l}\t%k0";
5439 }
5440
5441 default:
5442 /* For most processors, ADD is faster than LEA. This alternative
5443 was added to use ADD as much as possible. */
5444 if (which_alternative == 1)
5445 std::swap (operands[1], operands[2]);
5446
5447 if (x86_maybe_negate_const_int (&operands[2], SImode))
5448 return "sub{l}\t{%2, %k0|%k0, %2}";
5449
5450 return "add{l}\t{%2, %k0|%k0, %2}";
5451 }
5452 }
5453 [(set (attr "type")
5454 (cond [(eq_attr "alternative" "2")
5455 (const_string "lea")
5456 (match_operand:SI 2 "incdec_operand")
5457 (const_string "incdec")
5458 ]
5459 (const_string "alu")))
5460 (set (attr "length_immediate")
5461 (if_then_else
5462 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5463 (const_string "1")
5464 (const_string "*")))
5465 (set_attr "mode" "SI")])
5466
5467 (define_insn "*addhi_1"
5468 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5469 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5470 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5471 (clobber (reg:CC FLAGS_REG))]
5472 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5473 {
5474 switch (get_attr_type (insn))
5475 {
5476 case TYPE_LEA:
5477 return "#";
5478
5479 case TYPE_INCDEC:
5480 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5481 if (operands[2] == const1_rtx)
5482 return "inc{w}\t%0";
5483 else
5484 {
5485 gcc_assert (operands[2] == constm1_rtx);
5486 return "dec{w}\t%0";
5487 }
5488
5489 default:
5490 /* For most processors, ADD is faster than LEA. This alternative
5491 was added to use ADD as much as possible. */
5492 if (which_alternative == 2)
5493 std::swap (operands[1], operands[2]);
5494
5495 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5496 if (x86_maybe_negate_const_int (&operands[2], HImode))
5497 return "sub{w}\t{%2, %0|%0, %2}";
5498
5499 return "add{w}\t{%2, %0|%0, %2}";
5500 }
5501 }
5502 [(set (attr "type")
5503 (cond [(eq_attr "alternative" "3")
5504 (const_string "lea")
5505 (match_operand:HI 2 "incdec_operand")
5506 (const_string "incdec")
5507 ]
5508 (const_string "alu")))
5509 (set (attr "length_immediate")
5510 (if_then_else
5511 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5512 (const_string "1")
5513 (const_string "*")))
5514 (set_attr "mode" "HI,HI,HI,SI")])
5515
5516 (define_insn "*addqi_1"
5517 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5518 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5519 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5520 (clobber (reg:CC FLAGS_REG))]
5521 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5522 {
5523 bool widen = (get_attr_mode (insn) != MODE_QI);
5524
5525 switch (get_attr_type (insn))
5526 {
5527 case TYPE_LEA:
5528 return "#";
5529
5530 case TYPE_INCDEC:
5531 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5532 if (operands[2] == const1_rtx)
5533 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5534 else
5535 {
5536 gcc_assert (operands[2] == constm1_rtx);
5537 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5538 }
5539
5540 default:
5541 /* For most processors, ADD is faster than LEA. These alternatives
5542 were added to use ADD as much as possible. */
5543 if (which_alternative == 2 || which_alternative == 4)
5544 std::swap (operands[1], operands[2]);
5545
5546 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5547 if (x86_maybe_negate_const_int (&operands[2], QImode))
5548 {
5549 if (widen)
5550 return "sub{l}\t{%2, %k0|%k0, %2}";
5551 else
5552 return "sub{b}\t{%2, %0|%0, %2}";
5553 }
5554 if (widen)
5555 return "add{l}\t{%k2, %k0|%k0, %k2}";
5556 else
5557 return "add{b}\t{%2, %0|%0, %2}";
5558 }
5559 }
5560 [(set (attr "type")
5561 (cond [(eq_attr "alternative" "5")
5562 (const_string "lea")
5563 (match_operand:QI 2 "incdec_operand")
5564 (const_string "incdec")
5565 ]
5566 (const_string "alu")))
5567 (set (attr "length_immediate")
5568 (if_then_else
5569 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5570 (const_string "1")
5571 (const_string "*")))
5572 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5573 ;; Potential partial reg stall on alternatives 3 and 4.
5574 (set (attr "preferred_for_speed")
5575 (cond [(eq_attr "alternative" "3,4")
5576 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5577 (symbol_ref "true")))])
5578
5579 (define_insn "*addqi_1_slp"
5580 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5581 (plus:QI (match_dup 0)
5582 (match_operand:QI 1 "general_operand" "qn,qm")))
5583 (clobber (reg:CC FLAGS_REG))]
5584 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5585 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5586 {
5587 switch (get_attr_type (insn))
5588 {
5589 case TYPE_INCDEC:
5590 if (operands[1] == const1_rtx)
5591 return "inc{b}\t%0";
5592 else
5593 {
5594 gcc_assert (operands[1] == constm1_rtx);
5595 return "dec{b}\t%0";
5596 }
5597
5598 default:
5599 if (x86_maybe_negate_const_int (&operands[1], QImode))
5600 return "sub{b}\t{%1, %0|%0, %1}";
5601
5602 return "add{b}\t{%1, %0|%0, %1}";
5603 }
5604 }
5605 [(set (attr "type")
5606 (if_then_else (match_operand:QI 1 "incdec_operand")
5607 (const_string "incdec")
5608 (const_string "alu1")))
5609 (set (attr "memory")
5610 (if_then_else (match_operand 1 "memory_operand")
5611 (const_string "load")
5612 (const_string "none")))
5613 (set_attr "mode" "QI")])
5614
5615 ;; Split non destructive adds if we cannot use lea.
5616 (define_split
5617 [(set (match_operand:SWI48 0 "register_operand")
5618 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5619 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5620 (clobber (reg:CC FLAGS_REG))]
5621 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5622 [(set (match_dup 0) (match_dup 1))
5623 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5624 (clobber (reg:CC FLAGS_REG))])])
5625
5626 ;; Split non destructive adds if we cannot use lea.
5627 (define_split
5628 [(set (match_operand:DI 0 "register_operand")
5629 (zero_extend:DI
5630 (plus:SI (match_operand:SI 1 "register_operand")
5631 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5632 (clobber (reg:CC FLAGS_REG))]
5633 "TARGET_64BIT
5634 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5635 [(set (match_dup 3) (match_dup 1))
5636 (parallel [(set (match_dup 0)
5637 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5638 (clobber (reg:CC FLAGS_REG))])]
5639 "operands[3] = gen_lowpart (SImode, operands[0]);")
5640
5641 ;; Convert add to the lea pattern to avoid flags dependency.
5642 (define_split
5643 [(set (match_operand:SWI 0 "register_operand")
5644 (plus:SWI (match_operand:SWI 1 "register_operand")
5645 (match_operand:SWI 2 "<nonmemory_operand>")))
5646 (clobber (reg:CC FLAGS_REG))]
5647 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5648 [(set (match_dup 0)
5649 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5650 {
5651 if (<MODE>mode != <LEAMODE>mode)
5652 {
5653 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5654 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5655 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5656 }
5657 })
5658
5659 ;; Convert add to the lea pattern to avoid flags dependency.
5660 (define_split
5661 [(set (match_operand:DI 0 "register_operand")
5662 (zero_extend:DI
5663 (plus:SI (match_operand:SI 1 "register_operand")
5664 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5665 (clobber (reg:CC FLAGS_REG))]
5666 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5667 [(set (match_dup 0)
5668 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5669
5670 (define_insn "*add<mode>_2"
5671 [(set (reg FLAGS_REG)
5672 (compare
5673 (plus:SWI
5674 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5675 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5676 (const_int 0)))
5677 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5678 (plus:SWI (match_dup 1) (match_dup 2)))]
5679 "ix86_match_ccmode (insn, CCGOCmode)
5680 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5681 {
5682 switch (get_attr_type (insn))
5683 {
5684 case TYPE_INCDEC:
5685 if (operands[2] == const1_rtx)
5686 return "inc{<imodesuffix>}\t%0";
5687 else
5688 {
5689 gcc_assert (operands[2] == constm1_rtx);
5690 return "dec{<imodesuffix>}\t%0";
5691 }
5692
5693 default:
5694 if (which_alternative == 2)
5695 std::swap (operands[1], operands[2]);
5696
5697 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5698 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5699 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5700
5701 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5702 }
5703 }
5704 [(set (attr "type")
5705 (if_then_else (match_operand:SWI 2 "incdec_operand")
5706 (const_string "incdec")
5707 (const_string "alu")))
5708 (set (attr "length_immediate")
5709 (if_then_else
5710 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5711 (const_string "1")
5712 (const_string "*")))
5713 (set_attr "mode" "<MODE>")])
5714
5715 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5716 (define_insn "*addsi_2_zext"
5717 [(set (reg FLAGS_REG)
5718 (compare
5719 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5720 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5721 (const_int 0)))
5722 (set (match_operand:DI 0 "register_operand" "=r,r")
5723 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5724 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5725 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5726 {
5727 switch (get_attr_type (insn))
5728 {
5729 case TYPE_INCDEC:
5730 if (operands[2] == const1_rtx)
5731 return "inc{l}\t%k0";
5732 else
5733 {
5734 gcc_assert (operands[2] == constm1_rtx);
5735 return "dec{l}\t%k0";
5736 }
5737
5738 default:
5739 if (which_alternative == 1)
5740 std::swap (operands[1], operands[2]);
5741
5742 if (x86_maybe_negate_const_int (&operands[2], SImode))
5743 return "sub{l}\t{%2, %k0|%k0, %2}";
5744
5745 return "add{l}\t{%2, %k0|%k0, %2}";
5746 }
5747 }
5748 [(set (attr "type")
5749 (if_then_else (match_operand:SI 2 "incdec_operand")
5750 (const_string "incdec")
5751 (const_string "alu")))
5752 (set (attr "length_immediate")
5753 (if_then_else
5754 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5755 (const_string "1")
5756 (const_string "*")))
5757 (set_attr "mode" "SI")])
5758
5759 (define_insn "*add<mode>_3"
5760 [(set (reg FLAGS_REG)
5761 (compare
5762 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5763 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5764 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5765 "ix86_match_ccmode (insn, CCZmode)
5766 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5767 {
5768 switch (get_attr_type (insn))
5769 {
5770 case TYPE_INCDEC:
5771 if (operands[2] == const1_rtx)
5772 return "inc{<imodesuffix>}\t%0";
5773 else
5774 {
5775 gcc_assert (operands[2] == constm1_rtx);
5776 return "dec{<imodesuffix>}\t%0";
5777 }
5778
5779 default:
5780 if (which_alternative == 1)
5781 std::swap (operands[1], operands[2]);
5782
5783 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5785 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5786
5787 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5788 }
5789 }
5790 [(set (attr "type")
5791 (if_then_else (match_operand:SWI 2 "incdec_operand")
5792 (const_string "incdec")
5793 (const_string "alu")))
5794 (set (attr "length_immediate")
5795 (if_then_else
5796 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5797 (const_string "1")
5798 (const_string "*")))
5799 (set_attr "mode" "<MODE>")])
5800
5801 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5802 (define_insn "*addsi_3_zext"
5803 [(set (reg FLAGS_REG)
5804 (compare
5805 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5806 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5807 (set (match_operand:DI 0 "register_operand" "=r,r")
5808 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5809 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5810 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5811 {
5812 switch (get_attr_type (insn))
5813 {
5814 case TYPE_INCDEC:
5815 if (operands[2] == const1_rtx)
5816 return "inc{l}\t%k0";
5817 else
5818 {
5819 gcc_assert (operands[2] == constm1_rtx);
5820 return "dec{l}\t%k0";
5821 }
5822
5823 default:
5824 if (which_alternative == 1)
5825 std::swap (operands[1], operands[2]);
5826
5827 if (x86_maybe_negate_const_int (&operands[2], SImode))
5828 return "sub{l}\t{%2, %k0|%k0, %2}";
5829
5830 return "add{l}\t{%2, %k0|%k0, %2}";
5831 }
5832 }
5833 [(set (attr "type")
5834 (if_then_else (match_operand:SI 2 "incdec_operand")
5835 (const_string "incdec")
5836 (const_string "alu")))
5837 (set (attr "length_immediate")
5838 (if_then_else
5839 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5840 (const_string "1")
5841 (const_string "*")))
5842 (set_attr "mode" "SI")])
5843
5844 ; For comparisons against 1, -1 and 128, we may generate better code
5845 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5846 ; is matched then. We can't accept general immediate, because for
5847 ; case of overflows, the result is messed up.
5848 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5849 ; only for comparisons not depending on it.
5850
5851 (define_insn "*adddi_4"
5852 [(set (reg FLAGS_REG)
5853 (compare
5854 (match_operand:DI 1 "nonimmediate_operand" "0")
5855 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5856 (clobber (match_scratch:DI 0 "=rm"))]
5857 "TARGET_64BIT
5858 && ix86_match_ccmode (insn, CCGCmode)"
5859 {
5860 switch (get_attr_type (insn))
5861 {
5862 case TYPE_INCDEC:
5863 if (operands[2] == constm1_rtx)
5864 return "inc{q}\t%0";
5865 else
5866 {
5867 gcc_assert (operands[2] == const1_rtx);
5868 return "dec{q}\t%0";
5869 }
5870
5871 default:
5872 if (x86_maybe_negate_const_int (&operands[2], DImode))
5873 return "add{q}\t{%2, %0|%0, %2}";
5874
5875 return "sub{q}\t{%2, %0|%0, %2}";
5876 }
5877 }
5878 [(set (attr "type")
5879 (if_then_else (match_operand:DI 2 "incdec_operand")
5880 (const_string "incdec")
5881 (const_string "alu")))
5882 (set (attr "length_immediate")
5883 (if_then_else
5884 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5885 (const_string "1")
5886 (const_string "*")))
5887 (set_attr "mode" "DI")])
5888
5889 ; For comparisons against 1, -1 and 128, we may generate better code
5890 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5891 ; is matched then. We can't accept general immediate, because for
5892 ; case of overflows, the result is messed up.
5893 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5894 ; only for comparisons not depending on it.
5895
5896 (define_insn "*add<mode>_4"
5897 [(set (reg FLAGS_REG)
5898 (compare
5899 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5900 (match_operand:SWI124 2 "const_int_operand" "n")))
5901 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5902 "ix86_match_ccmode (insn, CCGCmode)"
5903 {
5904 switch (get_attr_type (insn))
5905 {
5906 case TYPE_INCDEC:
5907 if (operands[2] == constm1_rtx)
5908 return "inc{<imodesuffix>}\t%0";
5909 else
5910 {
5911 gcc_assert (operands[2] == const1_rtx);
5912 return "dec{<imodesuffix>}\t%0";
5913 }
5914
5915 default:
5916 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5917 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5918
5919 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5920 }
5921 }
5922 [(set (attr "type")
5923 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5924 (const_string "incdec")
5925 (const_string "alu")))
5926 (set (attr "length_immediate")
5927 (if_then_else
5928 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5929 (const_string "1")
5930 (const_string "*")))
5931 (set_attr "mode" "<MODE>")])
5932
5933 (define_insn "*add<mode>_5"
5934 [(set (reg FLAGS_REG)
5935 (compare
5936 (plus:SWI
5937 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5938 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5939 (const_int 0)))
5940 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5941 "ix86_match_ccmode (insn, CCGOCmode)
5942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5943 {
5944 switch (get_attr_type (insn))
5945 {
5946 case TYPE_INCDEC:
5947 if (operands[2] == const1_rtx)
5948 return "inc{<imodesuffix>}\t%0";
5949 else
5950 {
5951 gcc_assert (operands[2] == constm1_rtx);
5952 return "dec{<imodesuffix>}\t%0";
5953 }
5954
5955 default:
5956 if (which_alternative == 1)
5957 std::swap (operands[1], operands[2]);
5958
5959 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5960 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5961 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5962
5963 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5964 }
5965 }
5966 [(set (attr "type")
5967 (if_then_else (match_operand:SWI 2 "incdec_operand")
5968 (const_string "incdec")
5969 (const_string "alu")))
5970 (set (attr "length_immediate")
5971 (if_then_else
5972 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5973 (const_string "1")
5974 (const_string "*")))
5975 (set_attr "mode" "<MODE>")])
5976
5977 (define_insn "addqi_ext_1"
5978 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
5979 (const_int 8)
5980 (const_int 8))
5981 (subreg:SI
5982 (plus:QI
5983 (subreg:QI
5984 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
5985 (const_int 8)
5986 (const_int 8)) 0)
5987 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
5988 (clobber (reg:CC FLAGS_REG))]
5989 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
5990 rtx_equal_p (operands[0], operands[1])"
5991 {
5992 switch (get_attr_type (insn))
5993 {
5994 case TYPE_INCDEC:
5995 if (operands[2] == const1_rtx)
5996 return "inc{b}\t%h0";
5997 else
5998 {
5999 gcc_assert (operands[2] == constm1_rtx);
6000 return "dec{b}\t%h0";
6001 }
6002
6003 default:
6004 return "add{b}\t{%2, %h0|%h0, %2}";
6005 }
6006 }
6007 [(set_attr "isa" "*,nox64")
6008 (set (attr "type")
6009 (if_then_else (match_operand:QI 2 "incdec_operand")
6010 (const_string "incdec")
6011 (const_string "alu")))
6012 (set_attr "mode" "QI")])
6013
6014 (define_insn "*addqi_ext_2"
6015 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6016 (const_int 8)
6017 (const_int 8))
6018 (subreg:SI
6019 (plus:QI
6020 (subreg:QI
6021 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6022 (const_int 8)
6023 (const_int 8)) 0)
6024 (subreg:QI
6025 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6026 (const_int 8)
6027 (const_int 8)) 0)) 0))
6028 (clobber (reg:CC FLAGS_REG))]
6029 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6030 rtx_equal_p (operands[0], operands[1])
6031 || rtx_equal_p (operands[0], operands[2])"
6032 "add{b}\t{%h2, %h0|%h0, %h2}"
6033 [(set_attr "type" "alu")
6034 (set_attr "mode" "QI")])
6035
6036 ;; Add with jump on overflow.
6037 (define_expand "addv<mode>4"
6038 [(parallel [(set (reg:CCO FLAGS_REG)
6039 (eq:CCO (plus:<DWI>
6040 (sign_extend:<DWI>
6041 (match_operand:SWI 1 "nonimmediate_operand"))
6042 (match_dup 4))
6043 (sign_extend:<DWI>
6044 (plus:SWI (match_dup 1)
6045 (match_operand:SWI 2
6046 "<general_operand>")))))
6047 (set (match_operand:SWI 0 "register_operand")
6048 (plus:SWI (match_dup 1) (match_dup 2)))])
6049 (set (pc) (if_then_else
6050 (eq (reg:CCO FLAGS_REG) (const_int 0))
6051 (label_ref (match_operand 3))
6052 (pc)))]
6053 ""
6054 {
6055 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6056 if (CONST_INT_P (operands[2]))
6057 operands[4] = operands[2];
6058 else
6059 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6060 })
6061
6062 (define_insn "*addv<mode>4"
6063 [(set (reg:CCO FLAGS_REG)
6064 (eq:CCO (plus:<DWI>
6065 (sign_extend:<DWI>
6066 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6067 (sign_extend:<DWI>
6068 (match_operand:SWI 2 "<general_sext_operand>"
6069 "<r>mWe,<r>We")))
6070 (sign_extend:<DWI>
6071 (plus:SWI (match_dup 1) (match_dup 2)))))
6072 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6073 (plus:SWI (match_dup 1) (match_dup 2)))]
6074 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6075 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6076 [(set_attr "type" "alu")
6077 (set_attr "mode" "<MODE>")])
6078
6079 (define_insn "*addv<mode>4_1"
6080 [(set (reg:CCO FLAGS_REG)
6081 (eq:CCO (plus:<DWI>
6082 (sign_extend:<DWI>
6083 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6084 (match_operand:<DWI> 3 "const_int_operand" "i"))
6085 (sign_extend:<DWI>
6086 (plus:SWI (match_dup 1)
6087 (match_operand:SWI 2 "x86_64_immediate_operand"
6088 "<i>")))))
6089 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6090 (plus:SWI (match_dup 1) (match_dup 2)))]
6091 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6092 && CONST_INT_P (operands[2])
6093 && INTVAL (operands[2]) == INTVAL (operands[3])"
6094 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6095 [(set_attr "type" "alu")
6096 (set_attr "mode" "<MODE>")
6097 (set (attr "length_immediate")
6098 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6099 (const_string "1")
6100 (match_test "<MODE_SIZE> == 8")
6101 (const_string "4")]
6102 (const_string "<MODE_SIZE>")))])
6103
6104 (define_expand "uaddv<mode>4"
6105 [(parallel [(set (reg:CCC FLAGS_REG)
6106 (compare:CCC
6107 (plus:SWI
6108 (match_operand:SWI 1 "nonimmediate_operand")
6109 (match_operand:SWI 2 "<general_operand>"))
6110 (match_dup 1)))
6111 (set (match_operand:SWI 0 "register_operand")
6112 (plus:SWI (match_dup 1) (match_dup 2)))])
6113 (set (pc) (if_then_else
6114 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6115 (label_ref (match_operand 3))
6116 (pc)))]
6117 ""
6118 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6119
6120 ;; The lea patterns for modes less than 32 bits need to be matched by
6121 ;; several insns converted to real lea by splitters.
6122
6123 (define_insn_and_split "*lea<mode>_general_1"
6124 [(set (match_operand:SWI12 0 "register_operand" "=r")
6125 (plus:SWI12
6126 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6127 (match_operand:SWI12 2 "register_operand" "r"))
6128 (match_operand:SWI12 3 "immediate_operand" "i")))]
6129 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6130 "#"
6131 "&& reload_completed"
6132 [(set (match_dup 0)
6133 (plus:SI
6134 (plus:SI (match_dup 1) (match_dup 2))
6135 (match_dup 3)))]
6136 {
6137 operands[0] = gen_lowpart (SImode, operands[0]);
6138 operands[1] = gen_lowpart (SImode, operands[1]);
6139 operands[2] = gen_lowpart (SImode, operands[2]);
6140 operands[3] = gen_lowpart (SImode, operands[3]);
6141 }
6142 [(set_attr "type" "lea")
6143 (set_attr "mode" "SI")])
6144
6145 (define_insn_and_split "*lea<mode>_general_2"
6146 [(set (match_operand:SWI12 0 "register_operand" "=r")
6147 (plus:SWI12
6148 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6149 (match_operand 2 "const248_operand" "n"))
6150 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6151 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6152 "#"
6153 "&& reload_completed"
6154 [(set (match_dup 0)
6155 (plus:SI
6156 (mult:SI (match_dup 1) (match_dup 2))
6157 (match_dup 3)))]
6158 {
6159 operands[0] = gen_lowpart (SImode, operands[0]);
6160 operands[1] = gen_lowpart (SImode, operands[1]);
6161 operands[3] = gen_lowpart (SImode, operands[3]);
6162 }
6163 [(set_attr "type" "lea")
6164 (set_attr "mode" "SI")])
6165
6166 (define_insn_and_split "*lea<mode>_general_2b"
6167 [(set (match_operand:SWI12 0 "register_operand" "=r")
6168 (plus:SWI12
6169 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6170 (match_operand 2 "const123_operand" "n"))
6171 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6172 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6173 "#"
6174 "&& reload_completed"
6175 [(set (match_dup 0)
6176 (plus:SI
6177 (ashift:SI (match_dup 1) (match_dup 2))
6178 (match_dup 3)))]
6179 {
6180 operands[0] = gen_lowpart (SImode, operands[0]);
6181 operands[1] = gen_lowpart (SImode, operands[1]);
6182 operands[3] = gen_lowpart (SImode, operands[3]);
6183 }
6184 [(set_attr "type" "lea")
6185 (set_attr "mode" "SI")])
6186
6187 (define_insn_and_split "*lea<mode>_general_3"
6188 [(set (match_operand:SWI12 0 "register_operand" "=r")
6189 (plus:SWI12
6190 (plus:SWI12
6191 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6192 (match_operand 2 "const248_operand" "n"))
6193 (match_operand:SWI12 3 "register_operand" "r"))
6194 (match_operand:SWI12 4 "immediate_operand" "i")))]
6195 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6196 "#"
6197 "&& reload_completed"
6198 [(set (match_dup 0)
6199 (plus:SI
6200 (plus:SI
6201 (mult:SI (match_dup 1) (match_dup 2))
6202 (match_dup 3))
6203 (match_dup 4)))]
6204 {
6205 operands[0] = gen_lowpart (SImode, operands[0]);
6206 operands[1] = gen_lowpart (SImode, operands[1]);
6207 operands[3] = gen_lowpart (SImode, operands[3]);
6208 operands[4] = gen_lowpart (SImode, operands[4]);
6209 }
6210 [(set_attr "type" "lea")
6211 (set_attr "mode" "SI")])
6212
6213 (define_insn_and_split "*lea<mode>_general_3b"
6214 [(set (match_operand:SWI12 0 "register_operand" "=r")
6215 (plus:SWI12
6216 (plus:SWI12
6217 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6218 (match_operand 2 "const123_operand" "n"))
6219 (match_operand:SWI12 3 "register_operand" "r"))
6220 (match_operand:SWI12 4 "immediate_operand" "i")))]
6221 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6222 "#"
6223 "&& reload_completed"
6224 [(set (match_dup 0)
6225 (plus:SI
6226 (plus:SI
6227 (ashift:SI (match_dup 1) (match_dup 2))
6228 (match_dup 3))
6229 (match_dup 4)))]
6230 {
6231 operands[0] = gen_lowpart (SImode, operands[0]);
6232 operands[1] = gen_lowpart (SImode, operands[1]);
6233 operands[3] = gen_lowpart (SImode, operands[3]);
6234 operands[4] = gen_lowpart (SImode, operands[4]);
6235 }
6236 [(set_attr "type" "lea")
6237 (set_attr "mode" "SI")])
6238
6239 (define_insn_and_split "*lea<mode>_general_4"
6240 [(set (match_operand:SWI12 0 "register_operand" "=r")
6241 (any_or:SWI12
6242 (ashift:SWI12
6243 (match_operand:SWI12 1 "index_register_operand" "l")
6244 (match_operand 2 "const_0_to_3_operand" "n"))
6245 (match_operand 3 "const_int_operand" "n")))]
6246 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6247 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6248 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6249 "#"
6250 "&& reload_completed"
6251 [(set (match_dup 0)
6252 (plus:SI
6253 (mult:SI (match_dup 1) (match_dup 2))
6254 (match_dup 3)))]
6255 {
6256 operands[0] = gen_lowpart (SImode, operands[0]);
6257 operands[1] = gen_lowpart (SImode, operands[1]);
6258 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6259 }
6260 [(set_attr "type" "lea")
6261 (set_attr "mode" "SI")])
6262
6263 (define_insn_and_split "*lea<mode>_general_4"
6264 [(set (match_operand:SWI48 0 "register_operand" "=r")
6265 (any_or:SWI48
6266 (ashift:SWI48
6267 (match_operand:SWI48 1 "index_register_operand" "l")
6268 (match_operand 2 "const_0_to_3_operand" "n"))
6269 (match_operand 3 "const_int_operand" "n")))]
6270 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6271 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6272 "#"
6273 "&& reload_completed"
6274 [(set (match_dup 0)
6275 (plus:SWI48
6276 (mult:SWI48 (match_dup 1) (match_dup 2))
6277 (match_dup 3)))]
6278 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6279 [(set_attr "type" "lea")
6280 (set_attr "mode" "<MODE>")])
6281 \f
6282 ;; Subtract instructions
6283
6284 (define_expand "sub<mode>3"
6285 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6286 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6287 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6288 ""
6289 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6290
6291 (define_insn_and_split "*sub<dwi>3_doubleword"
6292 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6293 (minus:<DWI>
6294 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6295 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6296 "ro<di>,r<di>")))
6297 (clobber (reg:CC FLAGS_REG))]
6298 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6299 "#"
6300 "reload_completed"
6301 [(parallel [(set (reg:CC FLAGS_REG)
6302 (compare:CC (match_dup 1) (match_dup 2)))
6303 (set (match_dup 0)
6304 (minus:DWIH (match_dup 1) (match_dup 2)))])
6305 (parallel [(set (match_dup 3)
6306 (minus:DWIH
6307 (minus:DWIH
6308 (match_dup 4)
6309 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6310 (match_dup 5)))
6311 (clobber (reg:CC FLAGS_REG))])]
6312 {
6313 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6314 if (operands[2] == const0_rtx)
6315 {
6316 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6317 DONE;
6318 }
6319 })
6320
6321 (define_insn "*sub<mode>_1"
6322 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6323 (minus:SWI
6324 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6325 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6326 (clobber (reg:CC FLAGS_REG))]
6327 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6328 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6329 [(set_attr "type" "alu")
6330 (set_attr "mode" "<MODE>")])
6331
6332 (define_insn "*subsi_1_zext"
6333 [(set (match_operand:DI 0 "register_operand" "=r")
6334 (zero_extend:DI
6335 (minus:SI (match_operand:SI 1 "register_operand" "0")
6336 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6337 (clobber (reg:CC FLAGS_REG))]
6338 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6339 "sub{l}\t{%2, %k0|%k0, %2}"
6340 [(set_attr "type" "alu")
6341 (set_attr "mode" "SI")])
6342
6343 (define_insn "*subqi_1_slp"
6344 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6345 (minus:QI (match_dup 0)
6346 (match_operand:QI 1 "general_operand" "qn,qm")))
6347 (clobber (reg:CC FLAGS_REG))]
6348 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6349 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6350 "sub{b}\t{%1, %0|%0, %1}"
6351 [(set_attr "type" "alu1")
6352 (set_attr "mode" "QI")])
6353
6354 (define_insn "*sub<mode>_2"
6355 [(set (reg FLAGS_REG)
6356 (compare
6357 (minus:SWI
6358 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6359 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6360 (const_int 0)))
6361 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6362 (minus:SWI (match_dup 1) (match_dup 2)))]
6363 "ix86_match_ccmode (insn, CCGOCmode)
6364 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6365 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6366 [(set_attr "type" "alu")
6367 (set_attr "mode" "<MODE>")])
6368
6369 (define_insn "*subsi_2_zext"
6370 [(set (reg FLAGS_REG)
6371 (compare
6372 (minus:SI (match_operand:SI 1 "register_operand" "0")
6373 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6374 (const_int 0)))
6375 (set (match_operand:DI 0 "register_operand" "=r")
6376 (zero_extend:DI
6377 (minus:SI (match_dup 1)
6378 (match_dup 2))))]
6379 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6380 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6381 "sub{l}\t{%2, %k0|%k0, %2}"
6382 [(set_attr "type" "alu")
6383 (set_attr "mode" "SI")])
6384
6385 ;; Subtract with jump on overflow.
6386 (define_expand "subv<mode>4"
6387 [(parallel [(set (reg:CCO FLAGS_REG)
6388 (eq:CCO (minus:<DWI>
6389 (sign_extend:<DWI>
6390 (match_operand:SWI 1 "nonimmediate_operand"))
6391 (match_dup 4))
6392 (sign_extend:<DWI>
6393 (minus:SWI (match_dup 1)
6394 (match_operand:SWI 2
6395 "<general_operand>")))))
6396 (set (match_operand:SWI 0 "register_operand")
6397 (minus:SWI (match_dup 1) (match_dup 2)))])
6398 (set (pc) (if_then_else
6399 (eq (reg:CCO FLAGS_REG) (const_int 0))
6400 (label_ref (match_operand 3))
6401 (pc)))]
6402 ""
6403 {
6404 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6405 if (CONST_INT_P (operands[2]))
6406 operands[4] = operands[2];
6407 else
6408 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6409 })
6410
6411 (define_insn "*subv<mode>4"
6412 [(set (reg:CCO FLAGS_REG)
6413 (eq:CCO (minus:<DWI>
6414 (sign_extend:<DWI>
6415 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6416 (sign_extend:<DWI>
6417 (match_operand:SWI 2 "<general_sext_operand>"
6418 "<r>We,<r>m")))
6419 (sign_extend:<DWI>
6420 (minus:SWI (match_dup 1) (match_dup 2)))))
6421 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6422 (minus:SWI (match_dup 1) (match_dup 2)))]
6423 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6424 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6425 [(set_attr "type" "alu")
6426 (set_attr "mode" "<MODE>")])
6427
6428 (define_insn "*subv<mode>4_1"
6429 [(set (reg:CCO FLAGS_REG)
6430 (eq:CCO (minus:<DWI>
6431 (sign_extend:<DWI>
6432 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6433 (match_operand:<DWI> 3 "const_int_operand" "i"))
6434 (sign_extend:<DWI>
6435 (minus:SWI (match_dup 1)
6436 (match_operand:SWI 2 "x86_64_immediate_operand"
6437 "<i>")))))
6438 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6439 (minus:SWI (match_dup 1) (match_dup 2)))]
6440 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6441 && CONST_INT_P (operands[2])
6442 && INTVAL (operands[2]) == INTVAL (operands[3])"
6443 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6444 [(set_attr "type" "alu")
6445 (set_attr "mode" "<MODE>")
6446 (set (attr "length_immediate")
6447 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6448 (const_string "1")
6449 (match_test "<MODE_SIZE> == 8")
6450 (const_string "4")]
6451 (const_string "<MODE_SIZE>")))])
6452
6453 (define_expand "usubv<mode>4"
6454 [(parallel [(set (reg:CC FLAGS_REG)
6455 (compare:CC
6456 (match_operand:SWI 1 "nonimmediate_operand")
6457 (match_operand:SWI 2 "<general_operand>")))
6458 (set (match_operand:SWI 0 "register_operand")
6459 (minus:SWI (match_dup 1) (match_dup 2)))])
6460 (set (pc) (if_then_else
6461 (ltu (reg:CC FLAGS_REG) (const_int 0))
6462 (label_ref (match_operand 3))
6463 (pc)))]
6464 ""
6465 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6466
6467 (define_insn "*sub<mode>_3"
6468 [(set (reg FLAGS_REG)
6469 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6470 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6471 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6472 (minus:SWI (match_dup 1) (match_dup 2)))]
6473 "ix86_match_ccmode (insn, CCmode)
6474 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6475 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6476 [(set_attr "type" "alu")
6477 (set_attr "mode" "<MODE>")])
6478
6479 (define_peephole2
6480 [(parallel
6481 [(set (reg:CC FLAGS_REG)
6482 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6483 (match_operand:SWI 1 "general_gr_operand")))
6484 (set (match_dup 0)
6485 (minus:SWI (match_dup 0) (match_dup 1)))])]
6486 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6487 [(set (reg:CC FLAGS_REG)
6488 (compare:CC (match_dup 0) (match_dup 1)))])
6489
6490 (define_insn "*subsi_3_zext"
6491 [(set (reg FLAGS_REG)
6492 (compare (match_operand:SI 1 "register_operand" "0")
6493 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6494 (set (match_operand:DI 0 "register_operand" "=r")
6495 (zero_extend:DI
6496 (minus:SI (match_dup 1)
6497 (match_dup 2))))]
6498 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6499 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6500 "sub{l}\t{%2, %1|%1, %2}"
6501 [(set_attr "type" "alu")
6502 (set_attr "mode" "SI")])
6503 \f
6504 ;; Add with carry and subtract with borrow
6505
6506 (define_insn "add<mode>3_carry"
6507 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6508 (plus:SWI
6509 (plus:SWI
6510 (match_operator:SWI 4 "ix86_carry_flag_operator"
6511 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6512 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6513 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6514 (clobber (reg:CC FLAGS_REG))]
6515 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6516 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6517 [(set_attr "type" "alu")
6518 (set_attr "use_carry" "1")
6519 (set_attr "pent_pair" "pu")
6520 (set_attr "mode" "<MODE>")])
6521
6522 (define_insn "*add<mode>3_carry_0"
6523 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6524 (plus:SWI
6525 (match_operator:SWI 3 "ix86_carry_flag_operator"
6526 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6527 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6528 (clobber (reg:CC FLAGS_REG))]
6529 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6530 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6531 [(set_attr "type" "alu")
6532 (set_attr "use_carry" "1")
6533 (set_attr "pent_pair" "pu")
6534 (set_attr "mode" "<MODE>")])
6535
6536 (define_insn "*addsi3_carry_zext"
6537 [(set (match_operand:DI 0 "register_operand" "=r")
6538 (zero_extend:DI
6539 (plus:SI
6540 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6541 [(reg FLAGS_REG) (const_int 0)])
6542 (match_operand:SI 1 "register_operand" "%0"))
6543 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6544 (clobber (reg:CC FLAGS_REG))]
6545 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6546 "adc{l}\t{%2, %k0|%k0, %2}"
6547 [(set_attr "type" "alu")
6548 (set_attr "use_carry" "1")
6549 (set_attr "pent_pair" "pu")
6550 (set_attr "mode" "SI")])
6551
6552 (define_insn "*addsi3_carry_zext_0"
6553 [(set (match_operand:DI 0 "register_operand" "=r")
6554 (zero_extend:DI
6555 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6556 [(reg FLAGS_REG) (const_int 0)])
6557 (match_operand:SI 1 "register_operand" "0"))))
6558 (clobber (reg:CC FLAGS_REG))]
6559 "TARGET_64BIT"
6560 "adc{l}\t{$0, %k0|%k0, 0}"
6561 [(set_attr "type" "alu")
6562 (set_attr "use_carry" "1")
6563 (set_attr "pent_pair" "pu")
6564 (set_attr "mode" "SI")])
6565
6566 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6567
6568 (define_insn "addcarry<mode>"
6569 [(set (reg:CCC FLAGS_REG)
6570 (compare:CCC
6571 (zero_extend:<DWI>
6572 (plus:SWI48
6573 (plus:SWI48
6574 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6575 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6576 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6577 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6578 (plus:<DWI>
6579 (zero_extend:<DWI> (match_dup 2))
6580 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6581 [(match_dup 3) (const_int 0)]))))
6582 (set (match_operand:SWI48 0 "register_operand" "=r")
6583 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6584 [(match_dup 3) (const_int 0)])
6585 (match_dup 1))
6586 (match_dup 2)))]
6587 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6588 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6589 [(set_attr "type" "alu")
6590 (set_attr "use_carry" "1")
6591 (set_attr "pent_pair" "pu")
6592 (set_attr "mode" "<MODE>")])
6593
6594 (define_expand "addcarry<mode>_0"
6595 [(parallel
6596 [(set (reg:CCC FLAGS_REG)
6597 (compare:CCC
6598 (plus:SWI48
6599 (match_operand:SWI48 1 "nonimmediate_operand")
6600 (match_operand:SWI48 2 "x86_64_general_operand"))
6601 (match_dup 1)))
6602 (set (match_operand:SWI48 0 "register_operand")
6603 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6604 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6605
6606 (define_insn "@sub<mode>3_carry"
6607 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6608 (minus:SWI
6609 (minus:SWI
6610 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6611 (match_operator:SWI 4 "ix86_carry_flag_operator"
6612 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6613 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6614 (clobber (reg:CC FLAGS_REG))]
6615 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6616 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6617 [(set_attr "type" "alu")
6618 (set_attr "use_carry" "1")
6619 (set_attr "pent_pair" "pu")
6620 (set_attr "mode" "<MODE>")])
6621
6622 (define_insn "*sub<mode>3_carry_0"
6623 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6624 (minus:SWI
6625 (match_operand:SWI 1 "nonimmediate_operand" "0")
6626 (match_operator:SWI 3 "ix86_carry_flag_operator"
6627 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6628 (clobber (reg:CC FLAGS_REG))]
6629 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6630 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6631 [(set_attr "type" "alu")
6632 (set_attr "use_carry" "1")
6633 (set_attr "pent_pair" "pu")
6634 (set_attr "mode" "<MODE>")])
6635
6636 (define_insn "*subsi3_carry_zext"
6637 [(set (match_operand:DI 0 "register_operand" "=r")
6638 (zero_extend:DI
6639 (minus:SI
6640 (minus:SI
6641 (match_operand:SI 1 "register_operand" "0")
6642 (match_operator:SI 3 "ix86_carry_flag_operator"
6643 [(reg FLAGS_REG) (const_int 0)]))
6644 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6645 (clobber (reg:CC FLAGS_REG))]
6646 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6647 "sbb{l}\t{%2, %k0|%k0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "use_carry" "1")
6650 (set_attr "pent_pair" "pu")
6651 (set_attr "mode" "SI")])
6652
6653 (define_insn "*subsi3_carry_zext_0"
6654 [(set (match_operand:DI 0 "register_operand" "=r")
6655 (zero_extend:DI
6656 (minus:SI
6657 (match_operand:SI 1 "register_operand" "0")
6658 (match_operator:SI 2 "ix86_carry_flag_operator"
6659 [(reg FLAGS_REG) (const_int 0)]))))
6660 (clobber (reg:CC FLAGS_REG))]
6661 "TARGET_64BIT"
6662 "sbb{l}\t{$0, %k0|%k0, 0}"
6663 [(set_attr "type" "alu")
6664 (set_attr "use_carry" "1")
6665 (set_attr "pent_pair" "pu")
6666 (set_attr "mode" "SI")])
6667
6668 (define_insn "sub<mode>3_carry_ccc"
6669 [(set (reg:CCC FLAGS_REG)
6670 (compare:CCC
6671 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6672 (plus:<DWI>
6673 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6674 (zero_extend:<DWI>
6675 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6676 (clobber (match_scratch:DWIH 0 "=r"))]
6677 ""
6678 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "mode" "<MODE>")])
6681
6682 (define_insn "*sub<mode>3_carry_ccc_1"
6683 [(set (reg:CCC FLAGS_REG)
6684 (compare:CCC
6685 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6686 (plus:<DWI>
6687 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6688 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6689 (clobber (match_scratch:DWIH 0 "=r"))]
6690 ""
6691 {
6692 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6693 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6694 }
6695 [(set_attr "type" "alu")
6696 (set_attr "mode" "<MODE>")])
6697
6698 ;; The sign flag is set from the
6699 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6700 ;; result, the overflow flag likewise, but the overflow flag is also
6701 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6702 (define_insn "sub<mode>3_carry_ccgz"
6703 [(set (reg:CCGZ FLAGS_REG)
6704 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6705 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6706 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6707 UNSPEC_SBB))
6708 (clobber (match_scratch:DWIH 0 "=r"))]
6709 ""
6710 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6711 [(set_attr "type" "alu")
6712 (set_attr "mode" "<MODE>")])
6713
6714 (define_insn "subborrow<mode>"
6715 [(set (reg:CCC FLAGS_REG)
6716 (compare:CCC
6717 (zero_extend:<DWI>
6718 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6719 (plus:<DWI>
6720 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6721 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6722 (zero_extend:<DWI>
6723 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6724 (set (match_operand:SWI48 0 "register_operand" "=r")
6725 (minus:SWI48 (minus:SWI48
6726 (match_dup 1)
6727 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6728 [(match_dup 3) (const_int 0)]))
6729 (match_dup 2)))]
6730 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6731 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6732 [(set_attr "type" "alu")
6733 (set_attr "use_carry" "1")
6734 (set_attr "pent_pair" "pu")
6735 (set_attr "mode" "<MODE>")])
6736
6737 (define_expand "subborrow<mode>_0"
6738 [(parallel
6739 [(set (reg:CC FLAGS_REG)
6740 (compare:CC
6741 (match_operand:SWI48 1 "nonimmediate_operand")
6742 (match_operand:SWI48 2 "<general_operand>")))
6743 (set (match_operand:SWI48 0 "register_operand")
6744 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
6745 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
6746 \f
6747 ;; Overflow setting add instructions
6748
6749 (define_expand "addqi3_cconly_overflow"
6750 [(parallel
6751 [(set (reg:CCC FLAGS_REG)
6752 (compare:CCC
6753 (plus:QI
6754 (match_operand:QI 0 "nonimmediate_operand")
6755 (match_operand:QI 1 "general_operand"))
6756 (match_dup 0)))
6757 (clobber (match_scratch:QI 2))])]
6758 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6759
6760 (define_insn "*add<mode>3_cconly_overflow_1"
6761 [(set (reg:CCC FLAGS_REG)
6762 (compare:CCC
6763 (plus:SWI
6764 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6765 (match_operand:SWI 2 "<general_operand>" "<g>"))
6766 (match_dup 1)))
6767 (clobber (match_scratch:SWI 0 "=<r>"))]
6768 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6769 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6770 [(set_attr "type" "alu")
6771 (set_attr "mode" "<MODE>")])
6772
6773 (define_insn "*add<mode>3_cc_overflow_1"
6774 [(set (reg:CCC FLAGS_REG)
6775 (compare:CCC
6776 (plus:SWI
6777 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6778 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6779 (match_dup 1)))
6780 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6781 (plus:SWI (match_dup 1) (match_dup 2)))]
6782 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6783 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6784 [(set_attr "type" "alu")
6785 (set_attr "mode" "<MODE>")])
6786
6787 (define_insn "*addsi3_zext_cc_overflow_1"
6788 [(set (reg:CCC FLAGS_REG)
6789 (compare:CCC
6790 (plus:SI
6791 (match_operand:SI 1 "nonimmediate_operand" "%0")
6792 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6793 (match_dup 1)))
6794 (set (match_operand:DI 0 "register_operand" "=r")
6795 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6796 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6797 "add{l}\t{%2, %k0|%k0, %2}"
6798 [(set_attr "type" "alu")
6799 (set_attr "mode" "SI")])
6800
6801 (define_insn "*add<mode>3_cconly_overflow_2"
6802 [(set (reg:CCC FLAGS_REG)
6803 (compare:CCC
6804 (plus:SWI
6805 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6806 (match_operand:SWI 2 "<general_operand>" "<g>"))
6807 (match_dup 2)))
6808 (clobber (match_scratch:SWI 0 "=<r>"))]
6809 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6810 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6811 [(set_attr "type" "alu")
6812 (set_attr "mode" "<MODE>")])
6813
6814 (define_insn "*add<mode>3_cc_overflow_2"
6815 [(set (reg:CCC FLAGS_REG)
6816 (compare:CCC
6817 (plus:SWI
6818 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6819 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6820 (match_dup 2)))
6821 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6822 (plus:SWI (match_dup 1) (match_dup 2)))]
6823 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6824 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6825 [(set_attr "type" "alu")
6826 (set_attr "mode" "<MODE>")])
6827
6828 (define_insn "*addsi3_zext_cc_overflow_2"
6829 [(set (reg:CCC FLAGS_REG)
6830 (compare:CCC
6831 (plus:SI
6832 (match_operand:SI 1 "nonimmediate_operand" "%0")
6833 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6834 (match_dup 2)))
6835 (set (match_operand:DI 0 "register_operand" "=r")
6836 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6837 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6838 "add{l}\t{%2, %k0|%k0, %2}"
6839 [(set_attr "type" "alu")
6840 (set_attr "mode" "SI")])
6841
6842 ;; The patterns that match these are at the end of this file.
6843
6844 (define_expand "<plusminus_insn>xf3"
6845 [(set (match_operand:XF 0 "register_operand")
6846 (plusminus:XF
6847 (match_operand:XF 1 "register_operand")
6848 (match_operand:XF 2 "register_operand")))]
6849 "TARGET_80387")
6850
6851 (define_expand "<plusminus_insn><mode>3"
6852 [(set (match_operand:MODEF 0 "register_operand")
6853 (plusminus:MODEF
6854 (match_operand:MODEF 1 "register_operand")
6855 (match_operand:MODEF 2 "nonimmediate_operand")))]
6856 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6857 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6858 \f
6859 ;; Multiply instructions
6860
6861 (define_expand "mul<mode>3"
6862 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6863 (mult:SWIM248
6864 (match_operand:SWIM248 1 "register_operand")
6865 (match_operand:SWIM248 2 "<general_operand>")))
6866 (clobber (reg:CC FLAGS_REG))])])
6867
6868 (define_expand "mulqi3"
6869 [(parallel [(set (match_operand:QI 0 "register_operand")
6870 (mult:QI
6871 (match_operand:QI 1 "register_operand")
6872 (match_operand:QI 2 "nonimmediate_operand")))
6873 (clobber (reg:CC FLAGS_REG))])]
6874 "TARGET_QIMODE_MATH")
6875
6876 ;; On AMDFAM10
6877 ;; IMUL reg32/64, reg32/64, imm8 Direct
6878 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6879 ;; IMUL reg32/64, reg32/64, imm32 Direct
6880 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6881 ;; IMUL reg32/64, reg32/64 Direct
6882 ;; IMUL reg32/64, mem32/64 Direct
6883 ;;
6884 ;; On BDVER1, all above IMULs use DirectPath
6885 ;;
6886 ;; On AMDFAM10
6887 ;; IMUL reg16, reg16, imm8 VectorPath
6888 ;; IMUL reg16, mem16, imm8 VectorPath
6889 ;; IMUL reg16, reg16, imm16 VectorPath
6890 ;; IMUL reg16, mem16, imm16 VectorPath
6891 ;; IMUL reg16, reg16 Direct
6892 ;; IMUL reg16, mem16 Direct
6893 ;;
6894 ;; On BDVER1, all HI MULs use DoublePath
6895
6896 (define_insn "*mul<mode>3_1"
6897 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6898 (mult:SWIM248
6899 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6900 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6901 (clobber (reg:CC FLAGS_REG))]
6902 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6903 "@
6904 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6905 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6906 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6907 [(set_attr "type" "imul")
6908 (set_attr "prefix_0f" "0,0,1")
6909 (set (attr "athlon_decode")
6910 (cond [(eq_attr "cpu" "athlon")
6911 (const_string "vector")
6912 (eq_attr "alternative" "1")
6913 (const_string "vector")
6914 (and (eq_attr "alternative" "2")
6915 (ior (match_test "<MODE>mode == HImode")
6916 (match_operand 1 "memory_operand")))
6917 (const_string "vector")]
6918 (const_string "direct")))
6919 (set (attr "amdfam10_decode")
6920 (cond [(and (eq_attr "alternative" "0,1")
6921 (ior (match_test "<MODE>mode == HImode")
6922 (match_operand 1 "memory_operand")))
6923 (const_string "vector")]
6924 (const_string "direct")))
6925 (set (attr "bdver1_decode")
6926 (if_then_else
6927 (match_test "<MODE>mode == HImode")
6928 (const_string "double")
6929 (const_string "direct")))
6930 (set_attr "mode" "<MODE>")])
6931
6932 (define_insn "*mulsi3_1_zext"
6933 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6934 (zero_extend:DI
6935 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6936 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6937 (clobber (reg:CC FLAGS_REG))]
6938 "TARGET_64BIT
6939 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6940 "@
6941 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6942 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6943 imul{l}\t{%2, %k0|%k0, %2}"
6944 [(set_attr "type" "imul")
6945 (set_attr "prefix_0f" "0,0,1")
6946 (set (attr "athlon_decode")
6947 (cond [(eq_attr "cpu" "athlon")
6948 (const_string "vector")
6949 (eq_attr "alternative" "1")
6950 (const_string "vector")
6951 (and (eq_attr "alternative" "2")
6952 (match_operand 1 "memory_operand"))
6953 (const_string "vector")]
6954 (const_string "direct")))
6955 (set (attr "amdfam10_decode")
6956 (cond [(and (eq_attr "alternative" "0,1")
6957 (match_operand 1 "memory_operand"))
6958 (const_string "vector")]
6959 (const_string "direct")))
6960 (set_attr "bdver1_decode" "direct")
6961 (set_attr "mode" "SI")])
6962
6963 ;;On AMDFAM10 and BDVER1
6964 ;; MUL reg8 Direct
6965 ;; MUL mem8 Direct
6966
6967 (define_insn "*mulqi3_1"
6968 [(set (match_operand:QI 0 "register_operand" "=a")
6969 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6970 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6971 (clobber (reg:CC FLAGS_REG))]
6972 "TARGET_QIMODE_MATH
6973 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6974 "mul{b}\t%2"
6975 [(set_attr "type" "imul")
6976 (set_attr "length_immediate" "0")
6977 (set (attr "athlon_decode")
6978 (if_then_else (eq_attr "cpu" "athlon")
6979 (const_string "vector")
6980 (const_string "direct")))
6981 (set_attr "amdfam10_decode" "direct")
6982 (set_attr "bdver1_decode" "direct")
6983 (set_attr "mode" "QI")])
6984
6985 ;; Multiply with jump on overflow.
6986 (define_expand "mulv<mode>4"
6987 [(parallel [(set (reg:CCO FLAGS_REG)
6988 (eq:CCO (mult:<DWI>
6989 (sign_extend:<DWI>
6990 (match_operand:SWI248 1 "register_operand"))
6991 (match_dup 4))
6992 (sign_extend:<DWI>
6993 (mult:SWI248 (match_dup 1)
6994 (match_operand:SWI248 2
6995 "<general_operand>")))))
6996 (set (match_operand:SWI248 0 "register_operand")
6997 (mult:SWI248 (match_dup 1) (match_dup 2)))])
6998 (set (pc) (if_then_else
6999 (eq (reg:CCO FLAGS_REG) (const_int 0))
7000 (label_ref (match_operand 3))
7001 (pc)))]
7002 ""
7003 {
7004 if (CONST_INT_P (operands[2]))
7005 operands[4] = operands[2];
7006 else
7007 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7008 })
7009
7010 (define_insn "*mulv<mode>4"
7011 [(set (reg:CCO FLAGS_REG)
7012 (eq:CCO (mult:<DWI>
7013 (sign_extend:<DWI>
7014 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7015 (sign_extend:<DWI>
7016 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7017 (sign_extend:<DWI>
7018 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7019 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7020 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7021 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7022 "@
7023 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7024 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7025 [(set_attr "type" "imul")
7026 (set_attr "prefix_0f" "0,1")
7027 (set (attr "athlon_decode")
7028 (cond [(eq_attr "cpu" "athlon")
7029 (const_string "vector")
7030 (eq_attr "alternative" "0")
7031 (const_string "vector")
7032 (and (eq_attr "alternative" "1")
7033 (match_operand 1 "memory_operand"))
7034 (const_string "vector")]
7035 (const_string "direct")))
7036 (set (attr "amdfam10_decode")
7037 (cond [(and (eq_attr "alternative" "1")
7038 (match_operand 1 "memory_operand"))
7039 (const_string "vector")]
7040 (const_string "direct")))
7041 (set_attr "bdver1_decode" "direct")
7042 (set_attr "mode" "<MODE>")])
7043
7044 (define_insn "*mulvhi4"
7045 [(set (reg:CCO FLAGS_REG)
7046 (eq:CCO (mult:SI
7047 (sign_extend:SI
7048 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7049 (sign_extend:SI
7050 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7051 (sign_extend:SI
7052 (mult:HI (match_dup 1) (match_dup 2)))))
7053 (set (match_operand:HI 0 "register_operand" "=r")
7054 (mult:HI (match_dup 1) (match_dup 2)))]
7055 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7056 "imul{w}\t{%2, %0|%0, %2}"
7057 [(set_attr "type" "imul")
7058 (set_attr "prefix_0f" "1")
7059 (set_attr "athlon_decode" "vector")
7060 (set_attr "amdfam10_decode" "direct")
7061 (set_attr "bdver1_decode" "double")
7062 (set_attr "mode" "HI")])
7063
7064 (define_insn "*mulv<mode>4_1"
7065 [(set (reg:CCO FLAGS_REG)
7066 (eq:CCO (mult:<DWI>
7067 (sign_extend:<DWI>
7068 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7069 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7070 (sign_extend:<DWI>
7071 (mult:SWI248 (match_dup 1)
7072 (match_operand:SWI248 2
7073 "<immediate_operand>" "K,<i>")))))
7074 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7075 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7076 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7077 && CONST_INT_P (operands[2])
7078 && INTVAL (operands[2]) == INTVAL (operands[3])"
7079 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7080 [(set_attr "type" "imul")
7081 (set (attr "prefix_0f")
7082 (if_then_else
7083 (match_test "<MODE>mode == HImode")
7084 (const_string "0")
7085 (const_string "*")))
7086 (set (attr "athlon_decode")
7087 (cond [(eq_attr "cpu" "athlon")
7088 (const_string "vector")
7089 (eq_attr "alternative" "1")
7090 (const_string "vector")]
7091 (const_string "direct")))
7092 (set (attr "amdfam10_decode")
7093 (cond [(ior (match_test "<MODE>mode == HImode")
7094 (match_operand 1 "memory_operand"))
7095 (const_string "vector")]
7096 (const_string "direct")))
7097 (set (attr "bdver1_decode")
7098 (if_then_else
7099 (match_test "<MODE>mode == HImode")
7100 (const_string "double")
7101 (const_string "direct")))
7102 (set_attr "mode" "<MODE>")
7103 (set (attr "length_immediate")
7104 (cond [(eq_attr "alternative" "0")
7105 (const_string "1")
7106 (match_test "<MODE_SIZE> == 8")
7107 (const_string "4")]
7108 (const_string "<MODE_SIZE>")))])
7109
7110 (define_expand "umulv<mode>4"
7111 [(parallel [(set (reg:CCO FLAGS_REG)
7112 (eq:CCO (mult:<DWI>
7113 (zero_extend:<DWI>
7114 (match_operand:SWI248 1
7115 "nonimmediate_operand"))
7116 (zero_extend:<DWI>
7117 (match_operand:SWI248 2
7118 "nonimmediate_operand")))
7119 (zero_extend:<DWI>
7120 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7121 (set (match_operand:SWI248 0 "register_operand")
7122 (mult:SWI248 (match_dup 1) (match_dup 2)))
7123 (clobber (match_scratch:SWI248 4))])
7124 (set (pc) (if_then_else
7125 (eq (reg:CCO FLAGS_REG) (const_int 0))
7126 (label_ref (match_operand 3))
7127 (pc)))]
7128 ""
7129 {
7130 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7131 operands[1] = force_reg (<MODE>mode, operands[1]);
7132 })
7133
7134 (define_insn "*umulv<mode>4"
7135 [(set (reg:CCO FLAGS_REG)
7136 (eq:CCO (mult:<DWI>
7137 (zero_extend:<DWI>
7138 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7139 (zero_extend:<DWI>
7140 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7141 (zero_extend:<DWI>
7142 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7143 (set (match_operand:SWI248 0 "register_operand" "=a")
7144 (mult:SWI248 (match_dup 1) (match_dup 2)))
7145 (clobber (match_scratch:SWI248 3 "=d"))]
7146 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7147 "mul{<imodesuffix>}\t%2"
7148 [(set_attr "type" "imul")
7149 (set_attr "length_immediate" "0")
7150 (set (attr "athlon_decode")
7151 (if_then_else (eq_attr "cpu" "athlon")
7152 (const_string "vector")
7153 (const_string "double")))
7154 (set_attr "amdfam10_decode" "double")
7155 (set_attr "bdver1_decode" "direct")
7156 (set_attr "mode" "<MODE>")])
7157
7158 (define_expand "<u>mulvqi4"
7159 [(parallel [(set (reg:CCO FLAGS_REG)
7160 (eq:CCO (mult:HI
7161 (any_extend:HI
7162 (match_operand:QI 1 "nonimmediate_operand"))
7163 (any_extend:HI
7164 (match_operand:QI 2 "nonimmediate_operand")))
7165 (any_extend:HI
7166 (mult:QI (match_dup 1) (match_dup 2)))))
7167 (set (match_operand:QI 0 "register_operand")
7168 (mult:QI (match_dup 1) (match_dup 2)))])
7169 (set (pc) (if_then_else
7170 (eq (reg:CCO FLAGS_REG) (const_int 0))
7171 (label_ref (match_operand 3))
7172 (pc)))]
7173 "TARGET_QIMODE_MATH"
7174 {
7175 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7176 operands[1] = force_reg (QImode, operands[1]);
7177 })
7178
7179 (define_insn "*<u>mulvqi4"
7180 [(set (reg:CCO FLAGS_REG)
7181 (eq:CCO (mult:HI
7182 (any_extend:HI
7183 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7184 (any_extend:HI
7185 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7186 (any_extend:HI
7187 (mult:QI (match_dup 1) (match_dup 2)))))
7188 (set (match_operand:QI 0 "register_operand" "=a")
7189 (mult:QI (match_dup 1) (match_dup 2)))]
7190 "TARGET_QIMODE_MATH
7191 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7192 "<sgnprefix>mul{b}\t%2"
7193 [(set_attr "type" "imul")
7194 (set_attr "length_immediate" "0")
7195 (set (attr "athlon_decode")
7196 (if_then_else (eq_attr "cpu" "athlon")
7197 (const_string "vector")
7198 (const_string "direct")))
7199 (set_attr "amdfam10_decode" "direct")
7200 (set_attr "bdver1_decode" "direct")
7201 (set_attr "mode" "QI")])
7202
7203 (define_expand "<u>mul<mode><dwi>3"
7204 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7205 (mult:<DWI>
7206 (any_extend:<DWI>
7207 (match_operand:DWIH 1 "nonimmediate_operand"))
7208 (any_extend:<DWI>
7209 (match_operand:DWIH 2 "register_operand"))))
7210 (clobber (reg:CC FLAGS_REG))])])
7211
7212 (define_expand "<u>mulqihi3"
7213 [(parallel [(set (match_operand:HI 0 "register_operand")
7214 (mult:HI
7215 (any_extend:HI
7216 (match_operand:QI 1 "nonimmediate_operand"))
7217 (any_extend:HI
7218 (match_operand:QI 2 "register_operand"))))
7219 (clobber (reg:CC FLAGS_REG))])]
7220 "TARGET_QIMODE_MATH")
7221
7222 (define_insn "*bmi2_umul<mode><dwi>3_1"
7223 [(set (match_operand:DWIH 0 "register_operand" "=r")
7224 (mult:DWIH
7225 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7226 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7227 (set (match_operand:DWIH 1 "register_operand" "=r")
7228 (truncate:DWIH
7229 (lshiftrt:<DWI>
7230 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7231 (zero_extend:<DWI> (match_dup 3)))
7232 (match_operand:QI 4 "const_int_operand" "n"))))]
7233 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7234 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7235 "mulx\t{%3, %0, %1|%1, %0, %3}"
7236 [(set_attr "type" "imulx")
7237 (set_attr "prefix" "vex")
7238 (set_attr "mode" "<MODE>")])
7239
7240 (define_insn "*umul<mode><dwi>3_1"
7241 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7242 (mult:<DWI>
7243 (zero_extend:<DWI>
7244 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7245 (zero_extend:<DWI>
7246 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7247 (clobber (reg:CC FLAGS_REG))]
7248 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7249 "@
7250 #
7251 mul{<imodesuffix>}\t%2"
7252 [(set_attr "isa" "bmi2,*")
7253 (set_attr "type" "imulx,imul")
7254 (set_attr "length_immediate" "*,0")
7255 (set (attr "athlon_decode")
7256 (cond [(eq_attr "alternative" "1")
7257 (if_then_else (eq_attr "cpu" "athlon")
7258 (const_string "vector")
7259 (const_string "double"))]
7260 (const_string "*")))
7261 (set_attr "amdfam10_decode" "*,double")
7262 (set_attr "bdver1_decode" "*,direct")
7263 (set_attr "prefix" "vex,orig")
7264 (set_attr "mode" "<MODE>")])
7265
7266 ;; Convert mul to the mulx pattern to avoid flags dependency.
7267 (define_split
7268 [(set (match_operand:<DWI> 0 "register_operand")
7269 (mult:<DWI>
7270 (zero_extend:<DWI>
7271 (match_operand:DWIH 1 "register_operand"))
7272 (zero_extend:<DWI>
7273 (match_operand:DWIH 2 "nonimmediate_operand"))))
7274 (clobber (reg:CC FLAGS_REG))]
7275 "TARGET_BMI2 && reload_completed
7276 && REGNO (operands[1]) == DX_REG"
7277 [(parallel [(set (match_dup 3)
7278 (mult:DWIH (match_dup 1) (match_dup 2)))
7279 (set (match_dup 4)
7280 (truncate:DWIH
7281 (lshiftrt:<DWI>
7282 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7283 (zero_extend:<DWI> (match_dup 2)))
7284 (match_dup 5))))])]
7285 {
7286 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7287
7288 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7289 })
7290
7291 (define_insn "*mul<mode><dwi>3_1"
7292 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7293 (mult:<DWI>
7294 (sign_extend:<DWI>
7295 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7296 (sign_extend:<DWI>
7297 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7298 (clobber (reg:CC FLAGS_REG))]
7299 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7300 "imul{<imodesuffix>}\t%2"
7301 [(set_attr "type" "imul")
7302 (set_attr "length_immediate" "0")
7303 (set (attr "athlon_decode")
7304 (if_then_else (eq_attr "cpu" "athlon")
7305 (const_string "vector")
7306 (const_string "double")))
7307 (set_attr "amdfam10_decode" "double")
7308 (set_attr "bdver1_decode" "direct")
7309 (set_attr "mode" "<MODE>")])
7310
7311 (define_insn "*<u>mulqihi3_1"
7312 [(set (match_operand:HI 0 "register_operand" "=a")
7313 (mult:HI
7314 (any_extend:HI
7315 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7316 (any_extend:HI
7317 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7318 (clobber (reg:CC FLAGS_REG))]
7319 "TARGET_QIMODE_MATH
7320 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7321 "<sgnprefix>mul{b}\t%2"
7322 [(set_attr "type" "imul")
7323 (set_attr "length_immediate" "0")
7324 (set (attr "athlon_decode")
7325 (if_then_else (eq_attr "cpu" "athlon")
7326 (const_string "vector")
7327 (const_string "direct")))
7328 (set_attr "amdfam10_decode" "direct")
7329 (set_attr "bdver1_decode" "direct")
7330 (set_attr "mode" "QI")])
7331
7332 (define_expand "<s>mul<mode>3_highpart"
7333 [(parallel [(set (match_operand:DWIH 0 "register_operand")
7334 (truncate:DWIH
7335 (lshiftrt:<DWI>
7336 (mult:<DWI>
7337 (any_extend:<DWI>
7338 (match_operand:DWIH 1 "nonimmediate_operand"))
7339 (any_extend:<DWI>
7340 (match_operand:DWIH 2 "register_operand")))
7341 (match_dup 3))))
7342 (clobber (match_scratch:DWIH 4))
7343 (clobber (reg:CC FLAGS_REG))])]
7344 ""
7345 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7346
7347 (define_insn "*<s>muldi3_highpart_1"
7348 [(set (match_operand:DI 0 "register_operand" "=d")
7349 (truncate:DI
7350 (lshiftrt:TI
7351 (mult:TI
7352 (any_extend:TI
7353 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7354 (any_extend:TI
7355 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7356 (const_int 64))))
7357 (clobber (match_scratch:DI 3 "=1"))
7358 (clobber (reg:CC FLAGS_REG))]
7359 "TARGET_64BIT
7360 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7361 "<sgnprefix>mul{q}\t%2"
7362 [(set_attr "type" "imul")
7363 (set_attr "length_immediate" "0")
7364 (set (attr "athlon_decode")
7365 (if_then_else (eq_attr "cpu" "athlon")
7366 (const_string "vector")
7367 (const_string "double")))
7368 (set_attr "amdfam10_decode" "double")
7369 (set_attr "bdver1_decode" "direct")
7370 (set_attr "mode" "DI")])
7371
7372 (define_insn "*<s>mulsi3_highpart_zext"
7373 [(set (match_operand:DI 0 "register_operand" "=d")
7374 (zero_extend:DI (truncate:SI
7375 (lshiftrt:DI
7376 (mult:DI (any_extend:DI
7377 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7378 (any_extend:DI
7379 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7380 (const_int 32)))))
7381 (clobber (match_scratch:SI 3 "=1"))
7382 (clobber (reg:CC FLAGS_REG))]
7383 "TARGET_64BIT
7384 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7385 "<sgnprefix>mul{l}\t%2"
7386 [(set_attr "type" "imul")
7387 (set_attr "length_immediate" "0")
7388 (set (attr "athlon_decode")
7389 (if_then_else (eq_attr "cpu" "athlon")
7390 (const_string "vector")
7391 (const_string "double")))
7392 (set_attr "amdfam10_decode" "double")
7393 (set_attr "bdver1_decode" "direct")
7394 (set_attr "mode" "SI")])
7395
7396 (define_insn "*<s>mulsi3_highpart_1"
7397 [(set (match_operand:SI 0 "register_operand" "=d")
7398 (truncate:SI
7399 (lshiftrt:DI
7400 (mult:DI
7401 (any_extend:DI
7402 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7403 (any_extend:DI
7404 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7405 (const_int 32))))
7406 (clobber (match_scratch:SI 3 "=1"))
7407 (clobber (reg:CC FLAGS_REG))]
7408 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7409 "<sgnprefix>mul{l}\t%2"
7410 [(set_attr "type" "imul")
7411 (set_attr "length_immediate" "0")
7412 (set (attr "athlon_decode")
7413 (if_then_else (eq_attr "cpu" "athlon")
7414 (const_string "vector")
7415 (const_string "double")))
7416 (set_attr "amdfam10_decode" "double")
7417 (set_attr "bdver1_decode" "direct")
7418 (set_attr "mode" "SI")])
7419
7420 ;; The patterns that match these are at the end of this file.
7421
7422 (define_expand "mulxf3"
7423 [(set (match_operand:XF 0 "register_operand")
7424 (mult:XF (match_operand:XF 1 "register_operand")
7425 (match_operand:XF 2 "register_operand")))]
7426 "TARGET_80387")
7427
7428 (define_expand "mul<mode>3"
7429 [(set (match_operand:MODEF 0 "register_operand")
7430 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7431 (match_operand:MODEF 2 "nonimmediate_operand")))]
7432 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7433 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7434 \f
7435 ;; Divide instructions
7436
7437 ;; The patterns that match these are at the end of this file.
7438
7439 (define_expand "divxf3"
7440 [(set (match_operand:XF 0 "register_operand")
7441 (div:XF (match_operand:XF 1 "register_operand")
7442 (match_operand:XF 2 "register_operand")))]
7443 "TARGET_80387")
7444
7445 (define_expand "div<mode>3"
7446 [(set (match_operand:MODEF 0 "register_operand")
7447 (div:MODEF (match_operand:MODEF 1 "register_operand")
7448 (match_operand:MODEF 2 "nonimmediate_operand")))]
7449 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7450 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7451 {
7452 if (<MODE>mode == SFmode
7453 && TARGET_SSE && TARGET_SSE_MATH
7454 && TARGET_RECIP_DIV
7455 && optimize_insn_for_speed_p ()
7456 && flag_finite_math_only && !flag_trapping_math
7457 && flag_unsafe_math_optimizations)
7458 {
7459 ix86_emit_swdivsf (operands[0], operands[1],
7460 operands[2], SFmode);
7461 DONE;
7462 }
7463 })
7464 \f
7465 ;; Divmod instructions.
7466
7467 (define_code_iterator any_div [div udiv])
7468 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
7469
7470 (define_expand "<u>divmod<mode>4"
7471 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7472 (any_div:SWIM248
7473 (match_operand:SWIM248 1 "register_operand")
7474 (match_operand:SWIM248 2 "nonimmediate_operand")))
7475 (set (match_operand:SWIM248 3 "register_operand")
7476 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
7477 (clobber (reg:CC FLAGS_REG))])])
7478
7479 ;; Split with 8bit unsigned divide:
7480 ;; if (dividend an divisor are in [0-255])
7481 ;; use 8bit unsigned integer divide
7482 ;; else
7483 ;; use original integer divide
7484 (define_split
7485 [(set (match_operand:SWI48 0 "register_operand")
7486 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
7487 (match_operand:SWI48 3 "nonimmediate_operand")))
7488 (set (match_operand:SWI48 1 "register_operand")
7489 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
7490 (clobber (reg:CC FLAGS_REG))]
7491 "TARGET_USE_8BIT_IDIV
7492 && TARGET_QIMODE_MATH
7493 && can_create_pseudo_p ()
7494 && !optimize_insn_for_size_p ()"
7495 [(const_int 0)]
7496 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
7497
7498 (define_split
7499 [(set (match_operand:DI 0 "register_operand")
7500 (zero_extend:DI
7501 (any_div:SI (match_operand:SI 2 "register_operand")
7502 (match_operand:SI 3 "nonimmediate_operand"))))
7503 (set (match_operand:SI 1 "register_operand")
7504 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "TARGET_64BIT
7507 && TARGET_USE_8BIT_IDIV
7508 && TARGET_QIMODE_MATH
7509 && can_create_pseudo_p ()
7510 && !optimize_insn_for_size_p ()"
7511 [(const_int 0)]
7512 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7513
7514 (define_split
7515 [(set (match_operand:DI 1 "register_operand")
7516 (zero_extend:DI
7517 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
7518 (match_operand:SI 3 "nonimmediate_operand"))))
7519 (set (match_operand:SI 0 "register_operand")
7520 (any_div:SI (match_dup 2) (match_dup 3)))
7521 (clobber (reg:CC FLAGS_REG))]
7522 "TARGET_64BIT
7523 && TARGET_USE_8BIT_IDIV
7524 && TARGET_QIMODE_MATH
7525 && can_create_pseudo_p ()
7526 && !optimize_insn_for_size_p ()"
7527 [(const_int 0)]
7528 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7529
7530 (define_insn_and_split "divmod<mode>4_1"
7531 [(set (match_operand:SWI48 0 "register_operand" "=a")
7532 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7533 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7534 (set (match_operand:SWI48 1 "register_operand" "=&d")
7535 (mod:SWI48 (match_dup 2) (match_dup 3)))
7536 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7537 (clobber (reg:CC FLAGS_REG))]
7538 ""
7539 "#"
7540 "reload_completed"
7541 [(parallel [(set (match_dup 1)
7542 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7543 (clobber (reg:CC FLAGS_REG))])
7544 (parallel [(set (match_dup 0)
7545 (div:SWI48 (match_dup 2) (match_dup 3)))
7546 (set (match_dup 1)
7547 (mod:SWI48 (match_dup 2) (match_dup 3)))
7548 (use (match_dup 1))
7549 (clobber (reg:CC FLAGS_REG))])]
7550 {
7551 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7552
7553 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7554 operands[4] = operands[2];
7555 else
7556 {
7557 /* Avoid use of cltd in favor of a mov+shift. */
7558 emit_move_insn (operands[1], operands[2]);
7559 operands[4] = operands[1];
7560 }
7561 }
7562 [(set_attr "type" "multi")
7563 (set_attr "mode" "<MODE>")])
7564
7565 (define_insn_and_split "udivmod<mode>4_1"
7566 [(set (match_operand:SWI48 0 "register_operand" "=a")
7567 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7568 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7569 (set (match_operand:SWI48 1 "register_operand" "=&d")
7570 (umod:SWI48 (match_dup 2) (match_dup 3)))
7571 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7572 (clobber (reg:CC FLAGS_REG))]
7573 ""
7574 "#"
7575 "reload_completed"
7576 [(set (match_dup 1) (const_int 0))
7577 (parallel [(set (match_dup 0)
7578 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7579 (set (match_dup 1)
7580 (umod:SWI48 (match_dup 2) (match_dup 3)))
7581 (use (match_dup 1))
7582 (clobber (reg:CC FLAGS_REG))])]
7583 ""
7584 [(set_attr "type" "multi")
7585 (set_attr "mode" "<MODE>")])
7586
7587 (define_insn_and_split "divmodsi4_zext_1"
7588 [(set (match_operand:DI 0 "register_operand" "=a")
7589 (zero_extend:DI
7590 (div:SI (match_operand:SI 2 "register_operand" "0")
7591 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7592 (set (match_operand:SI 1 "register_operand" "=&d")
7593 (mod:SI (match_dup 2) (match_dup 3)))
7594 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7595 (clobber (reg:CC FLAGS_REG))]
7596 "TARGET_64BIT"
7597 "#"
7598 "&& reload_completed"
7599 [(parallel [(set (match_dup 1)
7600 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7601 (clobber (reg:CC FLAGS_REG))])
7602 (parallel [(set (match_dup 0)
7603 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7604 (set (match_dup 1)
7605 (mod:SI (match_dup 2) (match_dup 3)))
7606 (use (match_dup 1))
7607 (clobber (reg:CC FLAGS_REG))])]
7608 {
7609 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7610
7611 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7612 operands[4] = operands[2];
7613 else
7614 {
7615 /* Avoid use of cltd in favor of a mov+shift. */
7616 emit_move_insn (operands[1], operands[2]);
7617 operands[4] = operands[1];
7618 }
7619 }
7620 [(set_attr "type" "multi")
7621 (set_attr "mode" "SI")])
7622
7623 (define_insn_and_split "udivmodsi4_zext_1"
7624 [(set (match_operand:DI 0 "register_operand" "=a")
7625 (zero_extend:DI
7626 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7627 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7628 (set (match_operand:SI 1 "register_operand" "=&d")
7629 (umod:SI (match_dup 2) (match_dup 3)))
7630 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7631 (clobber (reg:CC FLAGS_REG))]
7632 "TARGET_64BIT"
7633 "#"
7634 "&& reload_completed"
7635 [(set (match_dup 1) (const_int 0))
7636 (parallel [(set (match_dup 0)
7637 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7638 (set (match_dup 1)
7639 (umod:SI (match_dup 2) (match_dup 3)))
7640 (use (match_dup 1))
7641 (clobber (reg:CC FLAGS_REG))])]
7642 ""
7643 [(set_attr "type" "multi")
7644 (set_attr "mode" "SI")])
7645
7646 (define_insn_and_split "divmodsi4_zext_2"
7647 [(set (match_operand:DI 1 "register_operand" "=&d")
7648 (zero_extend:DI
7649 (mod:SI (match_operand:SI 2 "register_operand" "0")
7650 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7651 (set (match_operand:SI 0 "register_operand" "=a")
7652 (div:SI (match_dup 2) (match_dup 3)))
7653 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7654 (clobber (reg:CC FLAGS_REG))]
7655 "TARGET_64BIT"
7656 "#"
7657 "&& reload_completed"
7658 [(parallel [(set (match_dup 6)
7659 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7660 (clobber (reg:CC FLAGS_REG))])
7661 (parallel [(set (match_dup 1)
7662 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7663 (set (match_dup 0)
7664 (div:SI (match_dup 2) (match_dup 3)))
7665 (use (match_dup 6))
7666 (clobber (reg:CC FLAGS_REG))])]
7667 {
7668 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7669 operands[6] = gen_lowpart (SImode, operands[1]);
7670
7671 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7672 operands[4] = operands[2];
7673 else
7674 {
7675 /* Avoid use of cltd in favor of a mov+shift. */
7676 emit_move_insn (operands[6], operands[2]);
7677 operands[4] = operands[6];
7678 }
7679 }
7680 [(set_attr "type" "multi")
7681 (set_attr "mode" "SI")])
7682
7683 (define_insn_and_split "udivmodsi4_zext_2"
7684 [(set (match_operand:DI 1 "register_operand" "=&d")
7685 (zero_extend:DI
7686 (umod:SI (match_operand:SI 2 "register_operand" "0")
7687 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7688 (set (match_operand:SI 0 "register_operand" "=a")
7689 (udiv:SI (match_dup 2) (match_dup 3)))
7690 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7691 (clobber (reg:CC FLAGS_REG))]
7692 "TARGET_64BIT"
7693 "#"
7694 "&& reload_completed"
7695 [(set (match_dup 4) (const_int 0))
7696 (parallel [(set (match_dup 1)
7697 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7698 (set (match_dup 0)
7699 (udiv:SI (match_dup 2) (match_dup 3)))
7700 (use (match_dup 4))
7701 (clobber (reg:CC FLAGS_REG))])]
7702 "operands[4] = gen_lowpart (SImode, operands[1]);"
7703 [(set_attr "type" "multi")
7704 (set_attr "mode" "SI")])
7705
7706 (define_insn_and_split "*divmod<mode>4"
7707 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7708 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7709 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7710 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7711 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7712 (clobber (reg:CC FLAGS_REG))]
7713 ""
7714 "#"
7715 "reload_completed"
7716 [(parallel [(set (match_dup 1)
7717 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7718 (clobber (reg:CC FLAGS_REG))])
7719 (parallel [(set (match_dup 0)
7720 (div:SWIM248 (match_dup 2) (match_dup 3)))
7721 (set (match_dup 1)
7722 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7723 (use (match_dup 1))
7724 (clobber (reg:CC FLAGS_REG))])]
7725 {
7726 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7727
7728 if (<MODE>mode != HImode
7729 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7730 operands[4] = operands[2];
7731 else
7732 {
7733 /* Avoid use of cltd in favor of a mov+shift. */
7734 emit_move_insn (operands[1], operands[2]);
7735 operands[4] = operands[1];
7736 }
7737 }
7738 [(set_attr "type" "multi")
7739 (set_attr "mode" "<MODE>")])
7740
7741 (define_insn_and_split "*udivmod<mode>4"
7742 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7743 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7744 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7745 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7746 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7747 (clobber (reg:CC FLAGS_REG))]
7748 ""
7749 "#"
7750 "reload_completed"
7751 [(set (match_dup 1) (const_int 0))
7752 (parallel [(set (match_dup 0)
7753 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7754 (set (match_dup 1)
7755 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7756 (use (match_dup 1))
7757 (clobber (reg:CC FLAGS_REG))])]
7758 ""
7759 [(set_attr "type" "multi")
7760 (set_attr "mode" "<MODE>")])
7761
7762 ;; Optimize division or modulo by constant power of 2, if the constant
7763 ;; materializes only after expansion.
7764 (define_insn_and_split "*udivmod<mode>4_pow2"
7765 [(set (match_operand:SWI48 0 "register_operand" "=r")
7766 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7767 (match_operand:SWI48 3 "const_int_operand" "n")))
7768 (set (match_operand:SWI48 1 "register_operand" "=r")
7769 (umod:SWI48 (match_dup 2) (match_dup 3)))
7770 (clobber (reg:CC FLAGS_REG))]
7771 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
7772 "#"
7773 "&& reload_completed"
7774 [(set (match_dup 1) (match_dup 2))
7775 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7776 (clobber (reg:CC FLAGS_REG))])
7777 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7778 (clobber (reg:CC FLAGS_REG))])]
7779 {
7780 int v = exact_log2 (UINTVAL (operands[3]));
7781 operands[4] = GEN_INT (v);
7782 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7783 }
7784 [(set_attr "type" "multi")
7785 (set_attr "mode" "<MODE>")])
7786
7787 (define_insn_and_split "*divmodsi4_zext_1"
7788 [(set (match_operand:DI 0 "register_operand" "=a")
7789 (zero_extend:DI
7790 (div:SI (match_operand:SI 2 "register_operand" "0")
7791 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7792 (set (match_operand:SI 1 "register_operand" "=&d")
7793 (mod:SI (match_dup 2) (match_dup 3)))
7794 (clobber (reg:CC FLAGS_REG))]
7795 "TARGET_64BIT"
7796 "#"
7797 "&& reload_completed"
7798 [(parallel [(set (match_dup 1)
7799 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7800 (clobber (reg:CC FLAGS_REG))])
7801 (parallel [(set (match_dup 0)
7802 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7803 (set (match_dup 1)
7804 (mod:SI (match_dup 2) (match_dup 3)))
7805 (use (match_dup 1))
7806 (clobber (reg:CC FLAGS_REG))])]
7807 {
7808 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7809
7810 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7811 operands[4] = operands[2];
7812 else
7813 {
7814 /* Avoid use of cltd in favor of a mov+shift. */
7815 emit_move_insn (operands[1], operands[2]);
7816 operands[4] = operands[1];
7817 }
7818 }
7819 [(set_attr "type" "multi")
7820 (set_attr "mode" "SI")])
7821
7822 (define_insn_and_split "*udivmodsi4_zext_1"
7823 [(set (match_operand:DI 0 "register_operand" "=a")
7824 (zero_extend:DI
7825 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7826 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7827 (set (match_operand:SI 1 "register_operand" "=&d")
7828 (umod:SI (match_dup 2) (match_dup 3)))
7829 (clobber (reg:CC FLAGS_REG))]
7830 "TARGET_64BIT"
7831 "#"
7832 "&& reload_completed"
7833 [(set (match_dup 1) (const_int 0))
7834 (parallel [(set (match_dup 0)
7835 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7836 (set (match_dup 1)
7837 (umod:SI (match_dup 2) (match_dup 3)))
7838 (use (match_dup 1))
7839 (clobber (reg:CC FLAGS_REG))])]
7840 ""
7841 [(set_attr "type" "multi")
7842 (set_attr "mode" "SI")])
7843
7844 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
7845 [(set (match_operand:DI 0 "register_operand" "=r")
7846 (zero_extend:DI
7847 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7848 (match_operand:SI 3 "const_int_operand" "n"))))
7849 (set (match_operand:SI 1 "register_operand" "=r")
7850 (umod:SI (match_dup 2) (match_dup 3)))
7851 (clobber (reg:CC FLAGS_REG))]
7852 "TARGET_64BIT
7853 && exact_log2 (UINTVAL (operands[3])) > 0"
7854 "#"
7855 "&& reload_completed"
7856 [(set (match_dup 1) (match_dup 2))
7857 (parallel [(set (match_dup 0)
7858 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
7859 (clobber (reg:CC FLAGS_REG))])
7860 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
7861 (clobber (reg:CC FLAGS_REG))])]
7862 {
7863 int v = exact_log2 (UINTVAL (operands[3]));
7864 operands[4] = GEN_INT (v);
7865 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7866 }
7867 [(set_attr "type" "multi")
7868 (set_attr "mode" "SI")])
7869
7870 (define_insn_and_split "*divmodsi4_zext_2"
7871 [(set (match_operand:DI 1 "register_operand" "=&d")
7872 (zero_extend:DI
7873 (mod:SI (match_operand:SI 2 "register_operand" "0")
7874 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7875 (set (match_operand:SI 0 "register_operand" "=a")
7876 (div:SI (match_dup 2) (match_dup 3)))
7877 (clobber (reg:CC FLAGS_REG))]
7878 "TARGET_64BIT"
7879 "#"
7880 "&& reload_completed"
7881 [(parallel [(set (match_dup 6)
7882 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7883 (clobber (reg:CC FLAGS_REG))])
7884 (parallel [(set (match_dup 1)
7885 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7886 (set (match_dup 0)
7887 (div:SI (match_dup 2) (match_dup 3)))
7888 (use (match_dup 6))
7889 (clobber (reg:CC FLAGS_REG))])]
7890 {
7891 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7892 operands[6] = gen_lowpart (SImode, operands[1]);
7893
7894 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7895 operands[4] = operands[2];
7896 else
7897 {
7898 /* Avoid use of cltd in favor of a mov+shift. */
7899 emit_move_insn (operands[6], operands[2]);
7900 operands[4] = operands[6];
7901 }
7902 }
7903 [(set_attr "type" "multi")
7904 (set_attr "mode" "SI")])
7905
7906 (define_insn_and_split "*udivmodsi4_zext_2"
7907 [(set (match_operand:DI 1 "register_operand" "=&d")
7908 (zero_extend:DI
7909 (umod:SI (match_operand:SI 2 "register_operand" "0")
7910 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7911 (set (match_operand:SI 0 "register_operand" "=a")
7912 (udiv:SI (match_dup 2) (match_dup 3)))
7913 (clobber (reg:CC FLAGS_REG))]
7914 "TARGET_64BIT"
7915 "#"
7916 "&& reload_completed"
7917 [(set (match_dup 4) (const_int 0))
7918 (parallel [(set (match_dup 1)
7919 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7920 (set (match_dup 0)
7921 (udiv:SI (match_dup 2) (match_dup 3)))
7922 (use (match_dup 4))
7923 (clobber (reg:CC FLAGS_REG))])]
7924 "operands[4] = gen_lowpart (SImode, operands[1]);"
7925 [(set_attr "type" "multi")
7926 (set_attr "mode" "SI")])
7927
7928 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
7929 [(set (match_operand:DI 1 "register_operand" "=r")
7930 (zero_extend:DI
7931 (umod:SI (match_operand:SI 2 "register_operand" "0")
7932 (match_operand:SI 3 "const_int_operand" "n"))))
7933 (set (match_operand:SI 0 "register_operand" "=r")
7934 (umod:SI (match_dup 2) (match_dup 3)))
7935 (clobber (reg:CC FLAGS_REG))]
7936 "TARGET_64BIT
7937 && exact_log2 (UINTVAL (operands[3])) > 0"
7938 "#"
7939 "&& reload_completed"
7940 [(set (match_dup 1) (match_dup 2))
7941 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
7942 (clobber (reg:CC FLAGS_REG))])
7943 (parallel [(set (match_dup 1)
7944 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
7945 (clobber (reg:CC FLAGS_REG))])]
7946 {
7947 int v = exact_log2 (UINTVAL (operands[3]));
7948 operands[4] = GEN_INT (v);
7949 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7950 }
7951 [(set_attr "type" "multi")
7952 (set_attr "mode" "SI")])
7953
7954 (define_insn "*<u>divmod<mode>4_noext"
7955 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7956 (any_div:SWIM248
7957 (match_operand:SWIM248 2 "register_operand" "0")
7958 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7959 (set (match_operand:SWIM248 1 "register_operand" "=d")
7960 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
7961 (use (match_operand:SWIM248 4 "register_operand" "1"))
7962 (clobber (reg:CC FLAGS_REG))]
7963 ""
7964 "<sgnprefix>div{<imodesuffix>}\t%3"
7965 [(set_attr "type" "idiv")
7966 (set_attr "mode" "<MODE>")])
7967
7968 (define_insn "*<u>divmodsi4_noext_zext_1"
7969 [(set (match_operand:DI 0 "register_operand" "=a")
7970 (zero_extend:DI
7971 (any_div:SI (match_operand:SI 2 "register_operand" "0")
7972 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7973 (set (match_operand:SI 1 "register_operand" "=d")
7974 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
7975 (use (match_operand:SI 4 "register_operand" "1"))
7976 (clobber (reg:CC FLAGS_REG))]
7977 "TARGET_64BIT"
7978 "<sgnprefix>div{l}\t%3"
7979 [(set_attr "type" "idiv")
7980 (set_attr "mode" "SI")])
7981
7982 (define_insn "*<u>divmodsi4_noext_zext_2"
7983 [(set (match_operand:DI 1 "register_operand" "=d")
7984 (zero_extend:DI
7985 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
7986 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7987 (set (match_operand:SI 0 "register_operand" "=a")
7988 (any_div:SI (match_dup 2) (match_dup 3)))
7989 (use (match_operand:SI 4 "register_operand" "1"))
7990 (clobber (reg:CC FLAGS_REG))]
7991 "TARGET_64BIT"
7992 "<sgnprefix>div{l}\t%3"
7993 [(set_attr "type" "idiv")
7994 (set_attr "mode" "SI")])
7995
7996 (define_expand "divmodqi4"
7997 [(parallel [(set (match_operand:QI 0 "register_operand")
7998 (div:QI
7999 (match_operand:QI 1 "register_operand")
8000 (match_operand:QI 2 "nonimmediate_operand")))
8001 (set (match_operand:QI 3 "register_operand")
8002 (mod:QI (match_dup 1) (match_dup 2)))
8003 (clobber (reg:CC FLAGS_REG))])]
8004 "TARGET_QIMODE_MATH"
8005 {
8006 rtx div, mod;
8007 rtx tmp0, tmp1;
8008
8009 tmp0 = gen_reg_rtx (HImode);
8010 tmp1 = gen_reg_rtx (HImode);
8011
8012 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8013 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8014 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8015
8016 /* Extract remainder from AH. */
8017 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8018 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8019 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8020
8021 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8022 set_unique_reg_note (insn, REG_EQUAL, mod);
8023
8024 /* Extract quotient from AL. */
8025 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8026
8027 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8028 set_unique_reg_note (insn, REG_EQUAL, div);
8029
8030 DONE;
8031 })
8032
8033 (define_expand "udivmodqi4"
8034 [(parallel [(set (match_operand:QI 0 "register_operand")
8035 (udiv:QI
8036 (match_operand:QI 1 "register_operand")
8037 (match_operand:QI 2 "nonimmediate_operand")))
8038 (set (match_operand:QI 3 "register_operand")
8039 (umod:QI (match_dup 1) (match_dup 2)))
8040 (clobber (reg:CC FLAGS_REG))])]
8041 "TARGET_QIMODE_MATH"
8042 {
8043 rtx div, mod;
8044 rtx tmp0, tmp1;
8045
8046 tmp0 = gen_reg_rtx (HImode);
8047 tmp1 = gen_reg_rtx (HImode);
8048
8049 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8050 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8051 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8052
8053 /* Extract remainder from AH. */
8054 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8055 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8056 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8057
8058 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8059 set_unique_reg_note (insn, REG_EQUAL, mod);
8060
8061 /* Extract quotient from AL. */
8062 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8063
8064 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8065 set_unique_reg_note (insn, REG_EQUAL, div);
8066
8067 DONE;
8068 })
8069
8070 ;; Divide AX by r/m8, with result stored in
8071 ;; AL <- Quotient
8072 ;; AH <- Remainder
8073 ;; Change div/mod to HImode and extend the second argument to HImode
8074 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8075 ;; combine may fail.
8076 (define_insn "<u>divmodhiqi3"
8077 [(set (match_operand:HI 0 "register_operand" "=a")
8078 (ior:HI
8079 (ashift:HI
8080 (zero_extend:HI
8081 (truncate:QI
8082 (mod:HI (match_operand:HI 1 "register_operand" "0")
8083 (any_extend:HI
8084 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8085 (const_int 8))
8086 (zero_extend:HI
8087 (truncate:QI
8088 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
8089 (clobber (reg:CC FLAGS_REG))]
8090 "TARGET_QIMODE_MATH"
8091 "<sgnprefix>div{b}\t%2"
8092 [(set_attr "type" "idiv")
8093 (set_attr "mode" "QI")])
8094
8095 ;; We cannot use div/idiv for double division, because it causes
8096 ;; "division by zero" on the overflow and that's not what we expect
8097 ;; from truncate. Because true (non truncating) double division is
8098 ;; never generated, we can't create this insn anyway.
8099 ;
8100 ;(define_insn ""
8101 ; [(set (match_operand:SI 0 "register_operand" "=a")
8102 ; (truncate:SI
8103 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8104 ; (zero_extend:DI
8105 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8106 ; (set (match_operand:SI 3 "register_operand" "=d")
8107 ; (truncate:SI
8108 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8109 ; (clobber (reg:CC FLAGS_REG))]
8110 ; ""
8111 ; "div{l}\t{%2, %0|%0, %2}"
8112 ; [(set_attr "type" "idiv")])
8113 \f
8114 ;;- Logical AND instructions
8115
8116 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8117 ;; Note that this excludes ah.
8118
8119 (define_expand "testsi_ccno_1"
8120 [(set (reg:CCNO FLAGS_REG)
8121 (compare:CCNO
8122 (and:SI (match_operand:SI 0 "nonimmediate_operand")
8123 (match_operand:SI 1 "x86_64_nonmemory_operand"))
8124 (const_int 0)))])
8125
8126 (define_expand "testqi_ccz_1"
8127 [(set (reg:CCZ FLAGS_REG)
8128 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8129 (match_operand:QI 1 "nonmemory_operand"))
8130 (const_int 0)))])
8131
8132 (define_expand "testdi_ccno_1"
8133 [(set (reg:CCNO FLAGS_REG)
8134 (compare:CCNO
8135 (and:DI (match_operand:DI 0 "nonimmediate_operand")
8136 (match_operand:DI 1 "x86_64_szext_general_operand"))
8137 (const_int 0)))]
8138 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8139
8140 (define_insn "*testdi_1"
8141 [(set (reg FLAGS_REG)
8142 (compare
8143 (and:DI
8144 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8145 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8146 (const_int 0)))]
8147 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8148 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8149 "@
8150 test{l}\t{%k1, %k0|%k0, %k1}
8151 test{l}\t{%k1, %k0|%k0, %k1}
8152 test{q}\t{%1, %0|%0, %1}
8153 test{q}\t{%1, %0|%0, %1}
8154 test{q}\t{%1, %0|%0, %1}"
8155 [(set_attr "type" "test")
8156 (set_attr "modrm" "0,1,0,1,1")
8157 (set_attr "mode" "SI,SI,DI,DI,DI")])
8158
8159 (define_insn "*testqi_1_maybe_si"
8160 [(set (reg FLAGS_REG)
8161 (compare
8162 (and:QI
8163 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8164 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8165 (const_int 0)))]
8166 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8167 && ix86_match_ccmode (insn,
8168 CONST_INT_P (operands[1])
8169 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8170 {
8171 if (which_alternative == 3)
8172 {
8173 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8174 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8175 return "test{l}\t{%1, %k0|%k0, %1}";
8176 }
8177 return "test{b}\t{%1, %0|%0, %1}";
8178 }
8179 [(set_attr "type" "test")
8180 (set_attr "modrm" "0,1,1,1")
8181 (set_attr "mode" "QI,QI,QI,SI")
8182 (set_attr "pent_pair" "uv,np,uv,np")])
8183
8184 (define_insn "*test<mode>_1"
8185 [(set (reg FLAGS_REG)
8186 (compare
8187 (and:SWI124
8188 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8189 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8190 (const_int 0)))]
8191 "ix86_match_ccmode (insn, CCNOmode)
8192 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8193 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8194 [(set_attr "type" "test")
8195 (set_attr "modrm" "0,1,1")
8196 (set_attr "mode" "<MODE>")
8197 (set_attr "pent_pair" "uv,np,uv")])
8198
8199 (define_expand "testqi_ext_1_ccno"
8200 [(set (reg:CCNO FLAGS_REG)
8201 (compare:CCNO
8202 (and:QI
8203 (subreg:QI
8204 (zero_extract:SI (match_operand 0 "ext_register_operand")
8205 (const_int 8)
8206 (const_int 8)) 0)
8207 (match_operand 1 "const_int_operand"))
8208 (const_int 0)))])
8209
8210 (define_insn "*testqi_ext_1"
8211 [(set (reg FLAGS_REG)
8212 (compare
8213 (and:QI
8214 (subreg:QI
8215 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8216 (const_int 8)
8217 (const_int 8)) 0)
8218 (match_operand:QI 1 "general_operand" "QnBc,m"))
8219 (const_int 0)))]
8220 "ix86_match_ccmode (insn, CCNOmode)"
8221 "test{b}\t{%1, %h0|%h0, %1}"
8222 [(set_attr "isa" "*,nox64")
8223 (set_attr "type" "test")
8224 (set_attr "mode" "QI")])
8225
8226 (define_insn "*testqi_ext_2"
8227 [(set (reg FLAGS_REG)
8228 (compare
8229 (and:QI
8230 (subreg:QI
8231 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8232 (const_int 8)
8233 (const_int 8)) 0)
8234 (subreg:QI
8235 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8236 (const_int 8)
8237 (const_int 8)) 0))
8238 (const_int 0)))]
8239 "ix86_match_ccmode (insn, CCNOmode)"
8240 "test{b}\t{%h1, %h0|%h0, %h1}"
8241 [(set_attr "type" "test")
8242 (set_attr "mode" "QI")])
8243
8244 ;; Combine likes to form bit extractions for some tests. Humor it.
8245 (define_insn_and_split "*testqi_ext_3"
8246 [(set (match_operand 0 "flags_reg_operand")
8247 (match_operator 1 "compare_operator"
8248 [(zero_extract:SWI248
8249 (match_operand 2 "nonimmediate_operand" "rm")
8250 (match_operand 3 "const_int_operand" "n")
8251 (match_operand 4 "const_int_operand" "n"))
8252 (const_int 0)]))]
8253 "ix86_match_ccmode (insn, CCNOmode)
8254 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8255 || GET_MODE (operands[2]) == SImode
8256 || GET_MODE (operands[2]) == HImode
8257 || GET_MODE (operands[2]) == QImode)
8258 /* Ensure that resulting mask is zero or sign extended operand. */
8259 && INTVAL (operands[4]) >= 0
8260 && ((INTVAL (operands[3]) > 0
8261 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8262 || (<MODE>mode == DImode
8263 && INTVAL (operands[3]) > 32
8264 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8265 "#"
8266 "&& 1"
8267 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8268 {
8269 rtx val = operands[2];
8270 HOST_WIDE_INT len = INTVAL (operands[3]);
8271 HOST_WIDE_INT pos = INTVAL (operands[4]);
8272 machine_mode mode = GET_MODE (val);
8273
8274 if (SUBREG_P (val))
8275 {
8276 machine_mode submode = GET_MODE (SUBREG_REG (val));
8277
8278 /* Narrow paradoxical subregs to prevent partial register stalls. */
8279 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8280 && GET_MODE_CLASS (submode) == MODE_INT)
8281 {
8282 val = SUBREG_REG (val);
8283 mode = submode;
8284 }
8285 }
8286
8287 /* Small HImode tests can be converted to QImode. */
8288 if (register_operand (val, HImode) && pos + len <= 8)
8289 {
8290 val = gen_lowpart (QImode, val);
8291 mode = QImode;
8292 }
8293
8294 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8295
8296 wide_int mask
8297 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8298
8299 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8300 })
8301
8302 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8303 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8304 ;; this is relatively important trick.
8305 ;; Do the conversion only post-reload to avoid limiting of the register class
8306 ;; to QI regs.
8307 (define_split
8308 [(set (match_operand 0 "flags_reg_operand")
8309 (match_operator 1 "compare_operator"
8310 [(and (match_operand 2 "QIreg_operand")
8311 (match_operand 3 "const_int_operand"))
8312 (const_int 0)]))]
8313 "reload_completed
8314 && GET_MODE (operands[2]) != QImode
8315 && ((ix86_match_ccmode (insn, CCZmode)
8316 && !(INTVAL (operands[3]) & ~(255 << 8)))
8317 || (ix86_match_ccmode (insn, CCNOmode)
8318 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8319 [(set (match_dup 0)
8320 (match_op_dup 1
8321 [(and:QI
8322 (subreg:QI
8323 (zero_extract:SI (match_dup 2)
8324 (const_int 8)
8325 (const_int 8)) 0)
8326 (match_dup 3))
8327 (const_int 0)]))]
8328 {
8329 operands[2] = gen_lowpart (SImode, operands[2]);
8330 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8331 })
8332
8333 (define_split
8334 [(set (match_operand 0 "flags_reg_operand")
8335 (match_operator 1 "compare_operator"
8336 [(and (match_operand 2 "nonimmediate_operand")
8337 (match_operand 3 "const_int_operand"))
8338 (const_int 0)]))]
8339 "reload_completed
8340 && GET_MODE (operands[2]) != QImode
8341 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8342 && ((ix86_match_ccmode (insn, CCZmode)
8343 && !(INTVAL (operands[3]) & ~255))
8344 || (ix86_match_ccmode (insn, CCNOmode)
8345 && !(INTVAL (operands[3]) & ~127)))"
8346 [(set (match_dup 0)
8347 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8348 (const_int 0)]))]
8349 {
8350 operands[2] = gen_lowpart (QImode, operands[2]);
8351 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8352 })
8353
8354 ;; %%% This used to optimize known byte-wide and operations to memory,
8355 ;; and sometimes to QImode registers. If this is considered useful,
8356 ;; it should be done with splitters.
8357
8358 (define_expand "and<mode>3"
8359 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
8360 (and:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
8361 (match_operand:SWIM1248s 2 "<general_szext_operand>")))]
8362 ""
8363 {
8364 machine_mode mode = <MODE>mode;
8365
8366 if (<MODE>mode == DImode && !TARGET_64BIT)
8367 ;
8368 else if (const_int_operand (operands[2], <MODE>mode)
8369 && register_operand (operands[0], <MODE>mode)
8370 && !(TARGET_ZERO_EXTEND_WITH_AND
8371 && optimize_function_for_speed_p (cfun)))
8372 {
8373 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
8374
8375 if (ival == GET_MODE_MASK (SImode))
8376 mode = SImode;
8377 else if (ival == GET_MODE_MASK (HImode))
8378 mode = HImode;
8379 else if (ival == GET_MODE_MASK (QImode))
8380 mode = QImode;
8381 }
8382
8383 if (mode != <MODE>mode)
8384 emit_insn (gen_extend_insn
8385 (operands[0], gen_lowpart (mode, operands[1]),
8386 <MODE>mode, mode, 1));
8387 else
8388 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8389
8390 DONE;
8391 })
8392
8393 (define_insn_and_split "*anddi3_doubleword"
8394 [(set (match_operand:DI 0 "nonimmediate_operand")
8395 (and:DI
8396 (match_operand:DI 1 "nonimmediate_operand")
8397 (match_operand:DI 2 "x86_64_szext_general_operand")))
8398 (clobber (reg:CC FLAGS_REG))]
8399 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8400 && ix86_binary_operator_ok (AND, DImode, operands)
8401 && can_create_pseudo_p ()"
8402 "#"
8403 "&& 1"
8404 [(const_int 0)]
8405 {
8406 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8407
8408 if (operands[2] == const0_rtx)
8409 emit_move_insn (operands[0], const0_rtx);
8410 else if (operands[2] == constm1_rtx)
8411 emit_move_insn (operands[0], operands[1]);
8412 else
8413 emit_insn (gen_andsi3 (operands[0], operands[1], operands[2]));
8414
8415 if (operands[5] == const0_rtx)
8416 emit_move_insn (operands[3], const0_rtx);
8417 else if (operands[5] == constm1_rtx)
8418 emit_move_insn (operands[3], operands[4]);
8419 else
8420 emit_insn (gen_andsi3 (operands[3], operands[4], operands[5]));
8421
8422 DONE;
8423 })
8424
8425 (define_insn "*anddi_1"
8426 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8427 (and:DI
8428 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8429 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8430 (clobber (reg:CC FLAGS_REG))]
8431 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8432 "@
8433 and{l}\t{%k2, %k0|%k0, %k2}
8434 and{q}\t{%2, %0|%0, %2}
8435 and{q}\t{%2, %0|%0, %2}
8436 #"
8437 [(set_attr "type" "alu,alu,alu,imovx")
8438 (set_attr "length_immediate" "*,*,*,0")
8439 (set (attr "prefix_rex")
8440 (if_then_else
8441 (and (eq_attr "type" "imovx")
8442 (and (match_test "INTVAL (operands[2]) == 0xff")
8443 (match_operand 1 "ext_QIreg_operand")))
8444 (const_string "1")
8445 (const_string "*")))
8446 (set_attr "mode" "SI,DI,DI,SI")])
8447
8448 (define_insn_and_split "*anddi_1_btr"
8449 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8450 (and:DI
8451 (match_operand:DI 1 "nonimmediate_operand" "%0")
8452 (match_operand:DI 2 "const_int_operand" "n")))
8453 (clobber (reg:CC FLAGS_REG))]
8454 "TARGET_64BIT && TARGET_USE_BT
8455 && ix86_binary_operator_ok (AND, DImode, operands)
8456 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8457 "#"
8458 "&& reload_completed"
8459 [(parallel [(set (zero_extract:DI (match_dup 0)
8460 (const_int 1)
8461 (match_dup 3))
8462 (const_int 0))
8463 (clobber (reg:CC FLAGS_REG))])]
8464 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8465 [(set_attr "type" "alu1")
8466 (set_attr "prefix_0f" "1")
8467 (set_attr "znver1_decode" "double")
8468 (set_attr "mode" "DI")])
8469
8470 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8471 (define_split
8472 [(set (match_operand:DI 0 "register_operand")
8473 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8474 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8475 (clobber (reg:CC FLAGS_REG))]
8476 "TARGET_64BIT"
8477 [(parallel [(set (match_dup 0)
8478 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8479 (clobber (reg:CC FLAGS_REG))])]
8480 {
8481 if (GET_CODE (operands[2]) == SYMBOL_REF
8482 || GET_CODE (operands[2]) == LABEL_REF)
8483 {
8484 operands[2] = shallow_copy_rtx (operands[2]);
8485 PUT_MODE (operands[2], SImode);
8486 }
8487 else if (GET_CODE (operands[2]) == CONST)
8488 {
8489 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
8490 operands[2] = copy_rtx (operands[2]);
8491 PUT_MODE (operands[2], SImode);
8492 PUT_MODE (XEXP (operands[2], 0), SImode);
8493 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
8494 }
8495 else
8496 operands[2] = gen_lowpart (SImode, operands[2]);
8497 })
8498
8499 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8500 (define_insn "*andsi_1_zext"
8501 [(set (match_operand:DI 0 "register_operand" "=r")
8502 (zero_extend:DI
8503 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8504 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8505 (clobber (reg:CC FLAGS_REG))]
8506 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8507 "and{l}\t{%2, %k0|%k0, %2}"
8508 [(set_attr "type" "alu")
8509 (set_attr "mode" "SI")])
8510
8511 (define_insn "*and<mode>_1"
8512 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8513 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8514 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8515 (clobber (reg:CC FLAGS_REG))]
8516 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8517 "@
8518 and{<imodesuffix>}\t{%2, %0|%0, %2}
8519 and{<imodesuffix>}\t{%2, %0|%0, %2}
8520 #"
8521 [(set_attr "type" "alu,alu,imovx")
8522 (set_attr "length_immediate" "*,*,0")
8523 (set (attr "prefix_rex")
8524 (if_then_else
8525 (and (eq_attr "type" "imovx")
8526 (and (match_test "INTVAL (operands[2]) == 0xff")
8527 (match_operand 1 "ext_QIreg_operand")))
8528 (const_string "1")
8529 (const_string "*")))
8530 (set_attr "mode" "<MODE>,<MODE>,SI")])
8531
8532 (define_insn "*andqi_1"
8533 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8534 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8535 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8536 (clobber (reg:CC FLAGS_REG))]
8537 "ix86_binary_operator_ok (AND, QImode, operands)"
8538 "@
8539 and{b}\t{%2, %0|%0, %2}
8540 and{b}\t{%2, %0|%0, %2}
8541 and{l}\t{%k2, %k0|%k0, %k2}"
8542 [(set_attr "type" "alu")
8543 (set_attr "mode" "QI,QI,SI")
8544 ;; Potential partial reg stall on alternative 2.
8545 (set (attr "preferred_for_speed")
8546 (cond [(eq_attr "alternative" "2")
8547 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8548 (symbol_ref "true")))])
8549
8550 (define_insn "*andqi_1_slp"
8551 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8552 (and:QI (match_dup 0)
8553 (match_operand:QI 1 "general_operand" "qn,qmn")))
8554 (clobber (reg:CC FLAGS_REG))]
8555 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8556 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8557 "and{b}\t{%1, %0|%0, %1}"
8558 [(set_attr "type" "alu1")
8559 (set_attr "mode" "QI")])
8560
8561 (define_split
8562 [(set (match_operand:SWI248 0 "register_operand")
8563 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8564 (match_operand:SWI248 2 "const_int_operand")))
8565 (clobber (reg:CC FLAGS_REG))]
8566 "reload_completed
8567 && (!REG_P (operands[1])
8568 || REGNO (operands[0]) != REGNO (operands[1]))"
8569 [(const_int 0)]
8570 {
8571 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
8572 machine_mode mode;
8573
8574 if (ival == GET_MODE_MASK (SImode))
8575 mode = SImode;
8576 else if (ival == GET_MODE_MASK (HImode))
8577 mode = HImode;
8578 else if (ival == GET_MODE_MASK (QImode))
8579 mode = QImode;
8580 else
8581 gcc_unreachable ();
8582
8583 /* Zero extend to SImode to avoid partial register stalls. */
8584 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
8585 operands[0] = gen_lowpart (SImode, operands[0]);
8586
8587 emit_insn (gen_extend_insn
8588 (operands[0], gen_lowpart (mode, operands[1]),
8589 GET_MODE (operands[0]), mode, 1));
8590 DONE;
8591 })
8592
8593 (define_split
8594 [(set (match_operand:SWI48 0 "register_operand")
8595 (and:SWI48 (match_dup 0)
8596 (const_int -65536)))
8597 (clobber (reg:CC FLAGS_REG))]
8598 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8599 || optimize_function_for_size_p (cfun)"
8600 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8601 "operands[1] = gen_lowpart (HImode, operands[0]);")
8602
8603 (define_split
8604 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8605 (and:SWI248 (match_dup 0)
8606 (const_int -256)))
8607 (clobber (reg:CC FLAGS_REG))]
8608 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8609 && reload_completed"
8610 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8611 "operands[1] = gen_lowpart (QImode, operands[0]);")
8612
8613 (define_split
8614 [(set (match_operand:SWI248 0 "QIreg_operand")
8615 (and:SWI248 (match_dup 0)
8616 (const_int -65281)))
8617 (clobber (reg:CC FLAGS_REG))]
8618 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8619 && reload_completed"
8620 [(parallel
8621 [(set (zero_extract:SI (match_dup 0)
8622 (const_int 8)
8623 (const_int 8))
8624 (subreg:SI
8625 (xor:QI
8626 (subreg:QI
8627 (zero_extract:SI (match_dup 0)
8628 (const_int 8)
8629 (const_int 8)) 0)
8630 (subreg:QI
8631 (zero_extract:SI (match_dup 0)
8632 (const_int 8)
8633 (const_int 8)) 0)) 0))
8634 (clobber (reg:CC FLAGS_REG))])]
8635 "operands[0] = gen_lowpart (SImode, operands[0]);")
8636
8637 (define_insn "*anddi_2"
8638 [(set (reg FLAGS_REG)
8639 (compare
8640 (and:DI
8641 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8642 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8643 (const_int 0)))
8644 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8645 (and:DI (match_dup 1) (match_dup 2)))]
8646 "TARGET_64BIT
8647 && ix86_match_ccmode
8648 (insn,
8649 /* If we are going to emit andl instead of andq, and the operands[2]
8650 constant might have the SImode sign bit set, make sure the sign
8651 flag isn't tested, because the instruction will set the sign flag
8652 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8653 conservatively assume it might have bit 31 set. */
8654 (satisfies_constraint_Z (operands[2])
8655 && (!CONST_INT_P (operands[2])
8656 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8657 ? CCZmode : CCNOmode)
8658 && ix86_binary_operator_ok (AND, DImode, operands)"
8659 "@
8660 and{l}\t{%k2, %k0|%k0, %k2}
8661 and{q}\t{%2, %0|%0, %2}
8662 and{q}\t{%2, %0|%0, %2}"
8663 [(set_attr "type" "alu")
8664 (set_attr "mode" "SI,DI,DI")])
8665
8666 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8667 (define_insn "*andsi_2_zext"
8668 [(set (reg FLAGS_REG)
8669 (compare (and:SI
8670 (match_operand:SI 1 "nonimmediate_operand" "%0")
8671 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8672 (const_int 0)))
8673 (set (match_operand:DI 0 "register_operand" "=r")
8674 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8675 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8676 && ix86_binary_operator_ok (AND, SImode, operands)"
8677 "and{l}\t{%2, %k0|%k0, %2}"
8678 [(set_attr "type" "alu")
8679 (set_attr "mode" "SI")])
8680
8681 (define_insn "*andqi_2_maybe_si"
8682 [(set (reg FLAGS_REG)
8683 (compare (and:QI
8684 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8685 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8686 (const_int 0)))
8687 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8688 (and:QI (match_dup 1) (match_dup 2)))]
8689 "ix86_binary_operator_ok (AND, QImode, operands)
8690 && ix86_match_ccmode (insn,
8691 CONST_INT_P (operands[2])
8692 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8693 {
8694 if (which_alternative == 2)
8695 {
8696 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8697 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8698 return "and{l}\t{%2, %k0|%k0, %2}";
8699 }
8700 return "and{b}\t{%2, %0|%0, %2}";
8701 }
8702 [(set_attr "type" "alu")
8703 (set_attr "mode" "QI,QI,SI")])
8704
8705 (define_insn "*and<mode>_2"
8706 [(set (reg FLAGS_REG)
8707 (compare (and:SWI124
8708 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8709 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8710 (const_int 0)))
8711 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8712 (and:SWI124 (match_dup 1) (match_dup 2)))]
8713 "ix86_match_ccmode (insn, CCNOmode)
8714 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8715 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8716 [(set_attr "type" "alu")
8717 (set_attr "mode" "<MODE>")])
8718
8719 (define_insn "*andqi_2_slp"
8720 [(set (reg FLAGS_REG)
8721 (compare (and:QI
8722 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8723 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8724 (const_int 0)))
8725 (set (strict_low_part (match_dup 0))
8726 (and:QI (match_dup 0) (match_dup 1)))]
8727 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8728 && ix86_match_ccmode (insn, CCNOmode)
8729 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8730 "and{b}\t{%1, %0|%0, %1}"
8731 [(set_attr "type" "alu1")
8732 (set_attr "mode" "QI")])
8733
8734 (define_insn "andqi_ext_1"
8735 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8736 (const_int 8)
8737 (const_int 8))
8738 (subreg:SI
8739 (and:QI
8740 (subreg:QI
8741 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8742 (const_int 8)
8743 (const_int 8)) 0)
8744 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8745 (clobber (reg:CC FLAGS_REG))]
8746 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
8747 rtx_equal_p (operands[0], operands[1])"
8748 "and{b}\t{%2, %h0|%h0, %2}"
8749 [(set_attr "isa" "*,nox64")
8750 (set_attr "type" "alu")
8751 (set_attr "mode" "QI")])
8752
8753 ;; Generated by peephole translating test to and. This shows up
8754 ;; often in fp comparisons.
8755 (define_insn "*andqi_ext_1_cc"
8756 [(set (reg FLAGS_REG)
8757 (compare
8758 (and:QI
8759 (subreg:QI
8760 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8761 (const_int 8)
8762 (const_int 8)) 0)
8763 (match_operand:QI 2 "general_operand" "QnBc,m"))
8764 (const_int 0)))
8765 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8766 (const_int 8)
8767 (const_int 8))
8768 (subreg:SI
8769 (and:QI
8770 (subreg:QI
8771 (zero_extract:SI (match_dup 1)
8772 (const_int 8)
8773 (const_int 8)) 0)
8774 (match_dup 2)) 0))]
8775 "ix86_match_ccmode (insn, CCNOmode)
8776 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
8777 && rtx_equal_p (operands[0], operands[1])"
8778 "and{b}\t{%2, %h0|%h0, %2}"
8779 [(set_attr "isa" "*,nox64")
8780 (set_attr "type" "alu")
8781 (set_attr "mode" "QI")])
8782
8783 (define_insn "*andqi_ext_2"
8784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
8785 (const_int 8)
8786 (const_int 8))
8787 (subreg:SI
8788 (and:QI
8789 (subreg:QI
8790 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
8791 (const_int 8)
8792 (const_int 8)) 0)
8793 (subreg:QI
8794 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8795 (const_int 8)
8796 (const_int 8)) 0)) 0))
8797 (clobber (reg:CC FLAGS_REG))]
8798 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
8799 rtx_equal_p (operands[0], operands[1])
8800 || rtx_equal_p (operands[0], operands[2])"
8801 "and{b}\t{%h2, %h0|%h0, %h2}"
8802 [(set_attr "type" "alu")
8803 (set_attr "mode" "QI")])
8804
8805 ;; Convert wide AND instructions with immediate operand to shorter QImode
8806 ;; equivalents when possible.
8807 ;; Don't do the splitting with memory operands, since it introduces risk
8808 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8809 ;; for size, but that can (should?) be handled by generic code instead.
8810 (define_split
8811 [(set (match_operand:SWI248 0 "QIreg_operand")
8812 (and:SWI248 (match_operand:SWI248 1 "register_operand")
8813 (match_operand:SWI248 2 "const_int_operand")))
8814 (clobber (reg:CC FLAGS_REG))]
8815 "reload_completed
8816 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8817 && !(~INTVAL (operands[2]) & ~(255 << 8))"
8818 [(parallel
8819 [(set (zero_extract:SI (match_dup 0)
8820 (const_int 8)
8821 (const_int 8))
8822 (subreg:SI
8823 (and:QI
8824 (subreg:QI
8825 (zero_extract:SI (match_dup 1)
8826 (const_int 8)
8827 (const_int 8)) 0)
8828 (match_dup 2)) 0))
8829 (clobber (reg:CC FLAGS_REG))])]
8830 {
8831 operands[0] = gen_lowpart (SImode, operands[0]);
8832 operands[1] = gen_lowpart (SImode, operands[1]);
8833 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
8834 })
8835
8836 ;; Since AND can be encoded with sign extended immediate, this is only
8837 ;; profitable when 7th bit is not set.
8838 (define_split
8839 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8840 (and:SWI248 (match_operand:SWI248 1 "general_operand")
8841 (match_operand:SWI248 2 "const_int_operand")))
8842 (clobber (reg:CC FLAGS_REG))]
8843 "reload_completed
8844 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8845 && !(~INTVAL (operands[2]) & ~255)
8846 && !(INTVAL (operands[2]) & 128)"
8847 [(parallel [(set (strict_low_part (match_dup 0))
8848 (and:QI (match_dup 1)
8849 (match_dup 2)))
8850 (clobber (reg:CC FLAGS_REG))])]
8851 {
8852 operands[0] = gen_lowpart (QImode, operands[0]);
8853 operands[1] = gen_lowpart (QImode, operands[1]);
8854 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
8855 })
8856
8857 (define_insn "*andndi3_doubleword"
8858 [(set (match_operand:DI 0 "register_operand")
8859 (and:DI
8860 (not:DI (match_operand:DI 1 "register_operand"))
8861 (match_operand:DI 2 "nonimmediate_operand")))
8862 (clobber (reg:CC FLAGS_REG))]
8863 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8864 && can_create_pseudo_p ()"
8865 "#")
8866
8867 (define_split
8868 [(set (match_operand:DI 0 "register_operand")
8869 (and:DI
8870 (not:DI (match_operand:DI 1 "register_operand"))
8871 (match_operand:DI 2 "nonimmediate_operand")))
8872 (clobber (reg:CC FLAGS_REG))]
8873 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
8874 && can_create_pseudo_p ()"
8875 [(parallel [(set (match_dup 0)
8876 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8877 (clobber (reg:CC FLAGS_REG))])
8878 (parallel [(set (match_dup 3)
8879 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8880 (clobber (reg:CC FLAGS_REG))])]
8881 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8882
8883 (define_split
8884 [(set (match_operand:DI 0 "register_operand")
8885 (and:DI
8886 (not:DI (match_operand:DI 1 "register_operand"))
8887 (match_operand:DI 2 "nonimmediate_operand")))
8888 (clobber (reg:CC FLAGS_REG))]
8889 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
8890 && can_create_pseudo_p ()"
8891 [(set (match_dup 6) (not:SI (match_dup 1)))
8892 (parallel [(set (match_dup 0)
8893 (and:SI (match_dup 6) (match_dup 2)))
8894 (clobber (reg:CC FLAGS_REG))])
8895 (set (match_dup 7) (not:SI (match_dup 4)))
8896 (parallel [(set (match_dup 3)
8897 (and:SI (match_dup 7) (match_dup 5)))
8898 (clobber (reg:CC FLAGS_REG))])]
8899 {
8900 operands[6] = gen_reg_rtx (SImode);
8901 operands[7] = gen_reg_rtx (SImode);
8902
8903 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8904 })
8905
8906 (define_insn "*andn<mode>_1"
8907 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
8908 (and:SWI48
8909 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8910 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
8911 (clobber (reg:CC FLAGS_REG))]
8912 "TARGET_BMI"
8913 "andn\t{%2, %1, %0|%0, %1, %2}"
8914 [(set_attr "type" "bitmanip")
8915 (set_attr "btver2_decode" "direct, double")
8916 (set_attr "mode" "<MODE>")])
8917
8918 (define_insn "*andn<mode>_1"
8919 [(set (match_operand:SWI12 0 "register_operand" "=r")
8920 (and:SWI12
8921 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
8922 (match_operand:SWI12 2 "register_operand" "r")))
8923 (clobber (reg:CC FLAGS_REG))]
8924 "TARGET_BMI"
8925 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
8926 [(set_attr "type" "bitmanip")
8927 (set_attr "btver2_decode" "direct")
8928 (set_attr "mode" "SI")])
8929
8930 (define_insn "*andn_<mode>_ccno"
8931 [(set (reg FLAGS_REG)
8932 (compare
8933 (and:SWI48
8934 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8935 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
8936 (const_int 0)))
8937 (clobber (match_scratch:SWI48 0 "=r,r"))]
8938 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
8939 "andn\t{%2, %1, %0|%0, %1, %2}"
8940 [(set_attr "type" "bitmanip")
8941 (set_attr "btver2_decode" "direct, double")
8942 (set_attr "mode" "<MODE>")])
8943 \f
8944 ;; Logical inclusive and exclusive OR instructions
8945
8946 ;; %%% This used to optimize known byte-wide and operations to memory.
8947 ;; If this is considered useful, it should be done with splitters.
8948
8949 (define_expand "<code><mode>3"
8950 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
8951 (any_or:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
8952 (match_operand:SWIM1248s 2 "<general_operand>")))]
8953 ""
8954 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8955
8956 (define_insn_and_split "*<code>di3_doubleword"
8957 [(set (match_operand:DI 0 "nonimmediate_operand")
8958 (any_or:DI
8959 (match_operand:DI 1 "nonimmediate_operand")
8960 (match_operand:DI 2 "x86_64_szext_general_operand")))
8961 (clobber (reg:CC FLAGS_REG))]
8962 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8963 && ix86_binary_operator_ok (<CODE>, DImode, operands)
8964 && can_create_pseudo_p ()"
8965 "#"
8966 "&& 1"
8967 [(const_int 0)]
8968 {
8969 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8970
8971 if (operands[2] == const0_rtx)
8972 emit_move_insn (operands[0], operands[1]);
8973 else if (operands[2] == constm1_rtx)
8974 {
8975 if (<CODE> == IOR)
8976 emit_move_insn (operands[0], constm1_rtx);
8977 else
8978 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8979 }
8980 else
8981 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8982
8983 if (operands[5] == const0_rtx)
8984 emit_move_insn (operands[3], operands[4]);
8985 else if (operands[5] == constm1_rtx)
8986 {
8987 if (<CODE> == IOR)
8988 emit_move_insn (operands[3], constm1_rtx);
8989 else
8990 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8991 }
8992 else
8993 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8994
8995 DONE;
8996 })
8997
8998 (define_insn "*<code><mode>_1"
8999 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9000 (any_or:SWI248
9001 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9002 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9003 (clobber (reg:CC FLAGS_REG))]
9004 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9005 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9006 [(set_attr "type" "alu")
9007 (set_attr "mode" "<MODE>")])
9008
9009 (define_insn_and_split "*iordi_1_bts"
9010 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9011 (ior:DI
9012 (match_operand:DI 1 "nonimmediate_operand" "%0")
9013 (match_operand:DI 2 "const_int_operand" "n")))
9014 (clobber (reg:CC FLAGS_REG))]
9015 "TARGET_64BIT && TARGET_USE_BT
9016 && ix86_binary_operator_ok (IOR, DImode, operands)
9017 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9018 "#"
9019 "&& reload_completed"
9020 [(parallel [(set (zero_extract:DI (match_dup 0)
9021 (const_int 1)
9022 (match_dup 3))
9023 (const_int 1))
9024 (clobber (reg:CC FLAGS_REG))])]
9025 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9026 [(set_attr "type" "alu1")
9027 (set_attr "prefix_0f" "1")
9028 (set_attr "znver1_decode" "double")
9029 (set_attr "mode" "DI")])
9030
9031 (define_insn_and_split "*xordi_1_btc"
9032 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9033 (xor:DI
9034 (match_operand:DI 1 "nonimmediate_operand" "%0")
9035 (match_operand:DI 2 "const_int_operand" "n")))
9036 (clobber (reg:CC FLAGS_REG))]
9037 "TARGET_64BIT && TARGET_USE_BT
9038 && ix86_binary_operator_ok (XOR, DImode, operands)
9039 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9040 "#"
9041 "&& reload_completed"
9042 [(parallel [(set (zero_extract:DI (match_dup 0)
9043 (const_int 1)
9044 (match_dup 3))
9045 (not:DI (zero_extract:DI (match_dup 0)
9046 (const_int 1)
9047 (match_dup 3))))
9048 (clobber (reg:CC FLAGS_REG))])]
9049 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9050 [(set_attr "type" "alu1")
9051 (set_attr "prefix_0f" "1")
9052 (set_attr "znver1_decode" "double")
9053 (set_attr "mode" "DI")])
9054
9055 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9056 (define_insn "*<code>si_1_zext"
9057 [(set (match_operand:DI 0 "register_operand" "=r")
9058 (zero_extend:DI
9059 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9060 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9061 (clobber (reg:CC FLAGS_REG))]
9062 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9063 "<logic>{l}\t{%2, %k0|%k0, %2}"
9064 [(set_attr "type" "alu")
9065 (set_attr "mode" "SI")])
9066
9067 (define_insn "*<code>si_1_zext_imm"
9068 [(set (match_operand:DI 0 "register_operand" "=r")
9069 (any_or:DI
9070 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9071 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9072 (clobber (reg:CC FLAGS_REG))]
9073 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9074 "<logic>{l}\t{%2, %k0|%k0, %2}"
9075 [(set_attr "type" "alu")
9076 (set_attr "mode" "SI")])
9077
9078 (define_insn "*<code>qi_1"
9079 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9080 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9081 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9082 (clobber (reg:CC FLAGS_REG))]
9083 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9084 "@
9085 <logic>{b}\t{%2, %0|%0, %2}
9086 <logic>{b}\t{%2, %0|%0, %2}
9087 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9088 [(set_attr "type" "alu")
9089 (set_attr "mode" "QI,QI,SI")
9090 ;; Potential partial reg stall on alternative 2.
9091 (set (attr "preferred_for_speed")
9092 (cond [(eq_attr "alternative" "2")
9093 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9094 (symbol_ref "true")))])
9095
9096 (define_insn "*<code>qi_1_slp"
9097 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9098 (any_or:QI (match_dup 0)
9099 (match_operand:QI 1 "general_operand" "qmn,qn")))
9100 (clobber (reg:CC FLAGS_REG))]
9101 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9102 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9103 "<logic>{b}\t{%1, %0|%0, %1}"
9104 [(set_attr "type" "alu1")
9105 (set_attr "mode" "QI")])
9106
9107 (define_insn "*<code><mode>_2"
9108 [(set (reg FLAGS_REG)
9109 (compare (any_or:SWI
9110 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9111 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9112 (const_int 0)))
9113 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9114 (any_or:SWI (match_dup 1) (match_dup 2)))]
9115 "ix86_match_ccmode (insn, CCNOmode)
9116 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9117 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9118 [(set_attr "type" "alu")
9119 (set_attr "mode" "<MODE>")])
9120
9121 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9122 ;; ??? Special case for immediate operand is missing - it is tricky.
9123 (define_insn "*<code>si_2_zext"
9124 [(set (reg FLAGS_REG)
9125 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9126 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9127 (const_int 0)))
9128 (set (match_operand:DI 0 "register_operand" "=r")
9129 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9130 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9131 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9132 "<logic>{l}\t{%2, %k0|%k0, %2}"
9133 [(set_attr "type" "alu")
9134 (set_attr "mode" "SI")])
9135
9136 (define_insn "*<code>si_2_zext_imm"
9137 [(set (reg FLAGS_REG)
9138 (compare (any_or:SI
9139 (match_operand:SI 1 "nonimmediate_operand" "%0")
9140 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9141 (const_int 0)))
9142 (set (match_operand:DI 0 "register_operand" "=r")
9143 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9144 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9145 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9146 "<logic>{l}\t{%2, %k0|%k0, %2}"
9147 [(set_attr "type" "alu")
9148 (set_attr "mode" "SI")])
9149
9150 (define_insn "*<code>qi_2_slp"
9151 [(set (reg FLAGS_REG)
9152 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9153 (match_operand:QI 1 "general_operand" "qmn,qn"))
9154 (const_int 0)))
9155 (set (strict_low_part (match_dup 0))
9156 (any_or:QI (match_dup 0) (match_dup 1)))]
9157 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9158 && ix86_match_ccmode (insn, CCNOmode)
9159 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9160 "<logic>{b}\t{%1, %0|%0, %1}"
9161 [(set_attr "type" "alu1")
9162 (set_attr "mode" "QI")])
9163
9164 (define_insn "*<code><mode>_3"
9165 [(set (reg FLAGS_REG)
9166 (compare (any_or:SWI
9167 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9168 (match_operand:SWI 2 "<general_operand>" "<g>"))
9169 (const_int 0)))
9170 (clobber (match_scratch:SWI 0 "=<r>"))]
9171 "ix86_match_ccmode (insn, CCNOmode)
9172 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9173 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9174 [(set_attr "type" "alu")
9175 (set_attr "mode" "<MODE>")])
9176
9177 (define_insn "*<code>qi_ext_1"
9178 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9179 (const_int 8)
9180 (const_int 8))
9181 (subreg:SI
9182 (any_or:QI
9183 (subreg:QI
9184 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9185 (const_int 8)
9186 (const_int 8)) 0)
9187 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9188 (clobber (reg:CC FLAGS_REG))]
9189 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9190 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9191 && rtx_equal_p (operands[0], operands[1])"
9192 "<logic>{b}\t{%2, %h0|%h0, %2}"
9193 [(set_attr "isa" "*,nox64")
9194 (set_attr "type" "alu")
9195 (set_attr "mode" "QI")])
9196
9197 (define_insn "*<code>qi_ext_2"
9198 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9199 (const_int 8)
9200 (const_int 8))
9201 (subreg:SI
9202 (any_or:QI
9203 (subreg:QI
9204 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9205 (const_int 8)
9206 (const_int 8)) 0)
9207 (subreg:QI
9208 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9209 (const_int 8)
9210 (const_int 8)) 0)) 0))
9211 (clobber (reg:CC FLAGS_REG))]
9212 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9213 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9214 && (rtx_equal_p (operands[0], operands[1])
9215 || rtx_equal_p (operands[0], operands[2]))"
9216 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9217 [(set_attr "type" "alu")
9218 (set_attr "mode" "QI")])
9219
9220 ;; Convert wide OR instructions with immediate operand to shorter QImode
9221 ;; equivalents when possible.
9222 ;; Don't do the splitting with memory operands, since it introduces risk
9223 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9224 ;; for size, but that can (should?) be handled by generic code instead.
9225 (define_split
9226 [(set (match_operand:SWI248 0 "QIreg_operand")
9227 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9228 (match_operand:SWI248 2 "const_int_operand")))
9229 (clobber (reg:CC FLAGS_REG))]
9230 "reload_completed
9231 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9232 && !(INTVAL (operands[2]) & ~(255 << 8))"
9233 [(parallel
9234 [(set (zero_extract:SI (match_dup 0)
9235 (const_int 8)
9236 (const_int 8))
9237 (subreg:SI
9238 (any_or:QI
9239 (subreg:QI
9240 (zero_extract:SI (match_dup 1)
9241 (const_int 8)
9242 (const_int 8)) 0)
9243 (match_dup 2)) 0))
9244 (clobber (reg:CC FLAGS_REG))])]
9245 {
9246 operands[0] = gen_lowpart (SImode, operands[0]);
9247 operands[1] = gen_lowpart (SImode, operands[1]);
9248 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9249 })
9250
9251 ;; Since OR can be encoded with sign extended immediate, this is only
9252 ;; profitable when 7th bit is set.
9253 (define_split
9254 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9255 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9256 (match_operand:SWI248 2 "const_int_operand")))
9257 (clobber (reg:CC FLAGS_REG))]
9258 "reload_completed
9259 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9260 && !(INTVAL (operands[2]) & ~255)
9261 && (INTVAL (operands[2]) & 128)"
9262 [(parallel [(set (strict_low_part (match_dup 0))
9263 (any_or:QI (match_dup 1)
9264 (match_dup 2)))
9265 (clobber (reg:CC FLAGS_REG))])]
9266 {
9267 operands[0] = gen_lowpart (QImode, operands[0]);
9268 operands[1] = gen_lowpart (QImode, operands[1]);
9269 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9270 })
9271
9272 (define_expand "xorqi_ext_1_cc"
9273 [(parallel [
9274 (set (reg:CCNO FLAGS_REG)
9275 (compare:CCNO
9276 (xor:QI
9277 (subreg:QI
9278 (zero_extract:SI (match_operand 1 "ext_register_operand")
9279 (const_int 8)
9280 (const_int 8)) 0)
9281 (match_operand 2 "const_int_operand"))
9282 (const_int 0)))
9283 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9284 (const_int 8)
9285 (const_int 8))
9286 (subreg:SI
9287 (xor:QI
9288 (subreg:QI
9289 (zero_extract:SI (match_dup 1)
9290 (const_int 8)
9291 (const_int 8)) 0)
9292 (match_dup 2)) 0))])])
9293
9294 (define_insn "*xorqi_ext_1_cc"
9295 [(set (reg FLAGS_REG)
9296 (compare
9297 (xor:QI
9298 (subreg:QI
9299 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9300 (const_int 8)
9301 (const_int 8)) 0)
9302 (match_operand:QI 2 "general_operand" "QnBc,m"))
9303 (const_int 0)))
9304 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9305 (const_int 8)
9306 (const_int 8))
9307 (subreg:SI
9308 (xor:QI
9309 (subreg:QI
9310 (zero_extract:SI (match_dup 1)
9311 (const_int 8)
9312 (const_int 8)) 0)
9313 (match_dup 2)) 0))]
9314 "ix86_match_ccmode (insn, CCNOmode)
9315 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9316 && rtx_equal_p (operands[0], operands[1])"
9317 "xor{b}\t{%2, %h0|%h0, %2}"
9318 [(set_attr "isa" "*,nox64")
9319 (set_attr "type" "alu")
9320 (set_attr "mode" "QI")])
9321 \f
9322 ;; Negation instructions
9323
9324 (define_expand "neg<mode>2"
9325 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9326 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9327 ""
9328 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9329
9330 (define_insn_and_split "*neg<dwi>2_doubleword"
9331 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9332 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9333 (clobber (reg:CC FLAGS_REG))]
9334 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9335 "#"
9336 "reload_completed"
9337 [(parallel
9338 [(set (reg:CCZ FLAGS_REG)
9339 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9340 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9341 (parallel
9342 [(set (match_dup 2)
9343 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9344 (match_dup 3))
9345 (const_int 0)))
9346 (clobber (reg:CC FLAGS_REG))])
9347 (parallel
9348 [(set (match_dup 2)
9349 (neg:DWIH (match_dup 2)))
9350 (clobber (reg:CC FLAGS_REG))])]
9351 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9352
9353 (define_insn "*neg<mode>2_1"
9354 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9355 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9356 (clobber (reg:CC FLAGS_REG))]
9357 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9358 "neg{<imodesuffix>}\t%0"
9359 [(set_attr "type" "negnot")
9360 (set_attr "mode" "<MODE>")])
9361
9362 ;; Combine is quite creative about this pattern.
9363 (define_insn "*negsi2_1_zext"
9364 [(set (match_operand:DI 0 "register_operand" "=r")
9365 (lshiftrt:DI
9366 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9367 (const_int 32)))
9368 (const_int 32)))
9369 (clobber (reg:CC FLAGS_REG))]
9370 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9371 "neg{l}\t%k0"
9372 [(set_attr "type" "negnot")
9373 (set_attr "mode" "SI")])
9374
9375 ;; The problem with neg is that it does not perform (compare x 0),
9376 ;; it really performs (compare 0 x), which leaves us with the zero
9377 ;; flag being the only useful item.
9378
9379 (define_insn "*neg<mode>2_cmpz"
9380 [(set (reg:CCZ FLAGS_REG)
9381 (compare:CCZ
9382 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9383 (const_int 0)))
9384 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9385 (neg:SWI (match_dup 1)))]
9386 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9387 "neg{<imodesuffix>}\t%0"
9388 [(set_attr "type" "negnot")
9389 (set_attr "mode" "<MODE>")])
9390
9391 (define_insn "*negsi2_cmpz_zext"
9392 [(set (reg:CCZ FLAGS_REG)
9393 (compare:CCZ
9394 (lshiftrt:DI
9395 (neg:DI (ashift:DI
9396 (match_operand:DI 1 "register_operand" "0")
9397 (const_int 32)))
9398 (const_int 32))
9399 (const_int 0)))
9400 (set (match_operand:DI 0 "register_operand" "=r")
9401 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9402 (const_int 32)))
9403 (const_int 32)))]
9404 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9405 "neg{l}\t%k0"
9406 [(set_attr "type" "negnot")
9407 (set_attr "mode" "SI")])
9408
9409 ;; Negate with jump on overflow.
9410 (define_expand "negv<mode>3"
9411 [(parallel [(set (reg:CCO FLAGS_REG)
9412 (ne:CCO (match_operand:SWI 1 "register_operand")
9413 (match_dup 3)))
9414 (set (match_operand:SWI 0 "register_operand")
9415 (neg:SWI (match_dup 1)))])
9416 (set (pc) (if_then_else
9417 (eq (reg:CCO FLAGS_REG) (const_int 0))
9418 (label_ref (match_operand 2))
9419 (pc)))]
9420 ""
9421 {
9422 operands[3]
9423 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9424 <MODE>mode);
9425 })
9426
9427 (define_insn "*negv<mode>3"
9428 [(set (reg:CCO FLAGS_REG)
9429 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9430 (match_operand:SWI 2 "const_int_operand")))
9431 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9432 (neg:SWI (match_dup 1)))]
9433 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9434 && mode_signbit_p (<MODE>mode, operands[2])"
9435 "neg{<imodesuffix>}\t%0"
9436 [(set_attr "type" "negnot")
9437 (set_attr "mode" "<MODE>")])
9438
9439 (define_expand "<code>tf2"
9440 [(set (match_operand:TF 0 "register_operand")
9441 (absneg:TF (match_operand:TF 1 "register_operand")))]
9442 "TARGET_SSE"
9443 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9444
9445 (define_insn "*<code>tf2_1"
9446 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
9447 (absneg:TF
9448 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
9449 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))
9450 (clobber (reg:CC FLAGS_REG))]
9451 "TARGET_SSE"
9452 "#"
9453 [(set_attr "isa" "noavx,noavx,avx,avx")])
9454
9455 (define_expand "<code><mode>2"
9456 [(set (match_operand:X87MODEF 0 "register_operand")
9457 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9458 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9459 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9460
9461 ;; Changing of sign for FP values is doable using integer unit too.
9462 (define_insn "*<code><mode>2_i387_1"
9463 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9464 (absneg:X87MODEF
9465 (match_operand:X87MODEF 1 "register_operand" "0,0")))
9466 (clobber (reg:CC FLAGS_REG))]
9467 "TARGET_80387"
9468 "#")
9469
9470 (define_split
9471 [(set (match_operand:X87MODEF 0 "fp_register_operand")
9472 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
9473 (clobber (reg:CC FLAGS_REG))]
9474 "TARGET_80387 && reload_completed"
9475 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
9476
9477 (define_split
9478 [(set (match_operand:X87MODEF 0 "general_reg_operand")
9479 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
9480 (clobber (reg:CC FLAGS_REG))]
9481 "TARGET_80387 && reload_completed"
9482 [(const_int 0)]
9483 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9484
9485 (define_insn "*<code><mode>2_1"
9486 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
9487 (absneg:MODEF
9488 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
9489 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
9490 (clobber (reg:CC FLAGS_REG))]
9491 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9492 "#"
9493 [(set_attr "isa" "noavx,noavx,avx,*,*")
9494 (set (attr "enabled")
9495 (if_then_else
9496 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9497 (if_then_else
9498 (eq_attr "alternative" "3,4")
9499 (symbol_ref "TARGET_MIX_SSE_I387")
9500 (const_string "*"))
9501 (if_then_else
9502 (eq_attr "alternative" "3,4")
9503 (symbol_ref "true")
9504 (symbol_ref "false"))))])
9505
9506 (define_split
9507 [(set (match_operand:SSEMODEF 0 "sse_reg_operand")
9508 (absneg:SSEMODEF
9509 (match_operand:SSEMODEF 1 "vector_operand")))
9510 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
9511 (clobber (reg:CC FLAGS_REG))]
9512 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9513 || (TARGET_SSE && (<MODE>mode == TFmode)))
9514 && reload_completed"
9515 [(set (match_dup 0) (match_dup 3))]
9516 {
9517 machine_mode mode = <MODE>mode;
9518 machine_mode vmode = <ssevecmodef>mode;
9519 enum rtx_code absneg_op = <CODE> == ABS ? AND : XOR;
9520
9521 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9522 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9523
9524 if (TARGET_AVX)
9525 {
9526 if (MEM_P (operands[1]))
9527 std::swap (operands[1], operands[2]);
9528 }
9529 else
9530 {
9531 if (operands_match_p (operands[0], operands[2]))
9532 std::swap (operands[1], operands[2]);
9533 }
9534
9535 operands[3]
9536 = gen_rtx_fmt_ee (absneg_op, vmode, operands[1], operands[2]);
9537 })
9538
9539 (define_split
9540 [(set (match_operand:MODEF 0 "fp_register_operand")
9541 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
9542 (use (match_operand 2))
9543 (clobber (reg:CC FLAGS_REG))]
9544 "TARGET_80387 && reload_completed"
9545 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
9546
9547 (define_split
9548 [(set (match_operand:MODEF 0 "general_reg_operand")
9549 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
9550 (use (match_operand 2))
9551 (clobber (reg:CC FLAGS_REG))]
9552 "TARGET_80387 && reload_completed"
9553 [(const_int 0)]
9554 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9555
9556 ;; Conditionalize these after reload. If they match before reload, we
9557 ;; lose the clobber and ability to use integer instructions.
9558
9559 (define_insn "*<code><mode>2_i387"
9560 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9561 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9562 "TARGET_80387 && reload_completed"
9563 "<absneg_mnemonic>"
9564 [(set_attr "type" "fsgn")
9565 (set_attr "mode" "<MODE>")])
9566
9567 ;; Copysign instructions
9568
9569 (define_expand "copysign<mode>3"
9570 [(match_operand:SSEMODEF 0 "register_operand")
9571 (match_operand:SSEMODEF 1 "nonmemory_operand")
9572 (match_operand:SSEMODEF 2 "register_operand")]
9573 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9574 || (TARGET_SSE && (<MODE>mode == TFmode))"
9575 "ix86_expand_copysign (operands); DONE;")
9576
9577 (define_insn_and_split "copysign<mode>3_const"
9578 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv")
9579 (unspec:SSEMODEF
9580 [(match_operand:<ssevecmodef> 1 "nonimm_or_0_operand" "YvmC")
9581 (match_operand:SSEMODEF 2 "register_operand" "0")
9582 (match_operand:<ssevecmodef> 3 "nonimmediate_operand" "Yvm")]
9583 UNSPEC_COPYSIGN))]
9584 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9585 || (TARGET_SSE && (<MODE>mode == TFmode))"
9586 "#"
9587 "&& reload_completed"
9588 [(const_int 0)]
9589 "ix86_split_copysign_const (operands); DONE;")
9590
9591 (define_insn "copysign<mode>3_var"
9592 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9593 (unspec:SSEMODEF
9594 [(match_operand:SSEMODEF 2 "register_operand" "Yv,0,0,Yv,Yv")
9595 (match_operand:SSEMODEF 3 "register_operand" "1,1,Yv,1,Yv")
9596 (match_operand:<ssevecmodef> 4
9597 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9598 (match_operand:<ssevecmodef> 5
9599 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9600 UNSPEC_COPYSIGN))
9601 (clobber (match_scratch:<ssevecmodef> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9602 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9603 || (TARGET_SSE && (<MODE>mode == TFmode))"
9604 "#")
9605
9606 (define_split
9607 [(set (match_operand:SSEMODEF 0 "register_operand")
9608 (unspec:SSEMODEF
9609 [(match_operand:SSEMODEF 2 "register_operand")
9610 (match_operand:SSEMODEF 3 "register_operand")
9611 (match_operand:<ssevecmodef> 4)
9612 (match_operand:<ssevecmodef> 5)]
9613 UNSPEC_COPYSIGN))
9614 (clobber (match_scratch:<ssevecmodef> 1))]
9615 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9616 || (TARGET_SSE && (<MODE>mode == TFmode)))
9617 && reload_completed"
9618 [(const_int 0)]
9619 "ix86_split_copysign_var (operands); DONE;")
9620
9621 (define_expand "xorsign<mode>3"
9622 [(match_operand:MODEF 0 "register_operand")
9623 (match_operand:MODEF 1 "register_operand")
9624 (match_operand:MODEF 2 "register_operand")]
9625 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9626 "ix86_expand_xorsign (operands); DONE;")
9627
9628 (define_insn_and_split "xorsign<mode>3_1"
9629 [(set (match_operand:MODEF 0 "register_operand" "=Yv")
9630 (unspec:MODEF
9631 [(match_operand:MODEF 1 "register_operand" "Yv")
9632 (match_operand:MODEF 2 "register_operand" "0")
9633 (match_operand:<ssevecmode> 3 "nonimmediate_operand" "Yvm")]
9634 UNSPEC_XORSIGN))]
9635 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9636 "#"
9637 "&& reload_completed"
9638 [(const_int 0)]
9639 "ix86_split_xorsign (operands); DONE;")
9640 \f
9641 ;; One complement instructions
9642
9643 (define_expand "one_cmpl<mode>2"
9644 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9645 (not:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")))]
9646 ""
9647 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9648
9649 (define_insn_and_split "*one_cmpldi2_doubleword"
9650 [(set (match_operand:DI 0 "nonimmediate_operand")
9651 (not:DI (match_operand:DI 1 "nonimmediate_operand")))]
9652 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9653 && ix86_unary_operator_ok (NOT, DImode, operands)
9654 && can_create_pseudo_p ()"
9655 "#"
9656 "&& 1"
9657 [(set (match_dup 0)
9658 (not:SI (match_dup 1)))
9659 (set (match_dup 2)
9660 (not:SI (match_dup 3)))]
9661 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9662
9663 (define_insn "*one_cmpl<mode>2_1"
9664 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9665 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9666 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9667 "not{<imodesuffix>}\t%0"
9668 [(set_attr "type" "negnot")
9669 (set_attr "mode" "<MODE>")])
9670
9671 ;; ??? Currently never generated - xor is used instead.
9672 (define_insn "*one_cmplsi2_1_zext"
9673 [(set (match_operand:DI 0 "register_operand" "=r")
9674 (zero_extend:DI
9675 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9676 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9677 "not{l}\t%k0"
9678 [(set_attr "type" "negnot")
9679 (set_attr "mode" "SI")])
9680
9681 (define_insn "*one_cmplqi2_1"
9682 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9683 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9684 "ix86_unary_operator_ok (NOT, QImode, operands)"
9685 "@
9686 not{b}\t%0
9687 not{l}\t%k0"
9688 [(set_attr "type" "negnot")
9689 (set_attr "mode" "QI,SI")
9690 ;; Potential partial reg stall on alternative 1.
9691 (set (attr "preferred_for_speed")
9692 (cond [(eq_attr "alternative" "1")
9693 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9694 (symbol_ref "true")))])
9695
9696 (define_insn "*one_cmpl<mode>2_2"
9697 [(set (reg FLAGS_REG)
9698 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9699 (const_int 0)))
9700 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9701 (not:SWI (match_dup 1)))]
9702 "ix86_match_ccmode (insn, CCNOmode)
9703 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9704 "#"
9705 [(set_attr "type" "alu1")
9706 (set_attr "mode" "<MODE>")])
9707
9708 (define_split
9709 [(set (match_operand 0 "flags_reg_operand")
9710 (match_operator 2 "compare_operator"
9711 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9712 (const_int 0)]))
9713 (set (match_operand:SWI 1 "nonimmediate_operand")
9714 (not:SWI (match_dup 3)))]
9715 "ix86_match_ccmode (insn, CCNOmode)"
9716 [(parallel [(set (match_dup 0)
9717 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9718 (const_int 0)]))
9719 (set (match_dup 1)
9720 (xor:SWI (match_dup 3) (const_int -1)))])])
9721
9722 ;; ??? Currently never generated - xor is used instead.
9723 (define_insn "*one_cmplsi2_2_zext"
9724 [(set (reg FLAGS_REG)
9725 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9726 (const_int 0)))
9727 (set (match_operand:DI 0 "register_operand" "=r")
9728 (zero_extend:DI (not:SI (match_dup 1))))]
9729 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9730 && ix86_unary_operator_ok (NOT, SImode, operands)"
9731 "#"
9732 [(set_attr "type" "alu1")
9733 (set_attr "mode" "SI")])
9734
9735 (define_split
9736 [(set (match_operand 0 "flags_reg_operand")
9737 (match_operator 2 "compare_operator"
9738 [(not:SI (match_operand:SI 3 "register_operand"))
9739 (const_int 0)]))
9740 (set (match_operand:DI 1 "register_operand")
9741 (zero_extend:DI (not:SI (match_dup 3))))]
9742 "ix86_match_ccmode (insn, CCNOmode)"
9743 [(parallel [(set (match_dup 0)
9744 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9745 (const_int 0)]))
9746 (set (match_dup 1)
9747 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9748 \f
9749 ;; Shift instructions
9750
9751 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9752 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9753 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9754 ;; from the assembler input.
9755 ;;
9756 ;; This instruction shifts the target reg/mem as usual, but instead of
9757 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9758 ;; is a left shift double, bits are taken from the high order bits of
9759 ;; reg, else if the insn is a shift right double, bits are taken from the
9760 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9761 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9762 ;;
9763 ;; Since sh[lr]d does not change the `reg' operand, that is done
9764 ;; separately, making all shifts emit pairs of shift double and normal
9765 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9766 ;; support a 63 bit shift, each shift where the count is in a reg expands
9767 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9768 ;;
9769 ;; If the shift count is a constant, we need never emit more than one
9770 ;; shift pair, instead using moves and sign extension for counts greater
9771 ;; than 31.
9772
9773 (define_expand "ashl<mode>3"
9774 [(set (match_operand:SDWIM 0 "<shift_operand>")
9775 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9776 (match_operand:QI 2 "nonmemory_operand")))]
9777 ""
9778 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9779
9780 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
9781 [(set (match_operand:<DWI> 0 "register_operand")
9782 (ashift:<DWI>
9783 (match_operand:<DWI> 1 "register_operand")
9784 (subreg:QI
9785 (and:SI
9786 (match_operand:SI 2 "register_operand" "c")
9787 (match_operand:SI 3 "const_int_operand")) 0)))
9788 (clobber (reg:CC FLAGS_REG))]
9789 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
9790 && can_create_pseudo_p ()"
9791 "#"
9792 "&& 1"
9793 [(parallel
9794 [(set (match_dup 6)
9795 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
9796 (lshiftrt:DWIH (match_dup 5)
9797 (minus:QI (match_dup 8) (match_dup 2)))))
9798 (clobber (reg:CC FLAGS_REG))])
9799 (parallel
9800 [(set (match_dup 4)
9801 (ashift:DWIH (match_dup 5) (match_dup 2)))
9802 (clobber (reg:CC FLAGS_REG))])]
9803 {
9804 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
9805
9806 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9807
9808 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9809 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9810 {
9811 rtx tem = gen_reg_rtx (SImode);
9812 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
9813 operands[2] = tem;
9814 }
9815
9816 operands[2] = gen_lowpart (QImode, operands[2]);
9817
9818 if (!rtx_equal_p (operands[6], operands[7]))
9819 emit_move_insn (operands[6], operands[7]);
9820 })
9821
9822 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
9823 [(set (match_operand:<DWI> 0 "register_operand")
9824 (ashift:<DWI>
9825 (match_operand:<DWI> 1 "register_operand")
9826 (and:QI
9827 (match_operand:QI 2 "register_operand" "c")
9828 (match_operand:QI 3 "const_int_operand"))))
9829 (clobber (reg:CC FLAGS_REG))]
9830 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
9831 && can_create_pseudo_p ()"
9832 "#"
9833 "&& 1"
9834 [(parallel
9835 [(set (match_dup 6)
9836 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
9837 (lshiftrt:DWIH (match_dup 5)
9838 (minus:QI (match_dup 8) (match_dup 2)))))
9839 (clobber (reg:CC FLAGS_REG))])
9840 (parallel
9841 [(set (match_dup 4)
9842 (ashift:DWIH (match_dup 5) (match_dup 2)))
9843 (clobber (reg:CC FLAGS_REG))])]
9844 {
9845 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
9846
9847 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9848
9849 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9850 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9851 {
9852 rtx tem = gen_reg_rtx (QImode);
9853 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
9854 operands[2] = tem;
9855 }
9856
9857 if (!rtx_equal_p (operands[6], operands[7]))
9858 emit_move_insn (operands[6], operands[7]);
9859 })
9860
9861 (define_insn "*ashl<mode>3_doubleword"
9862 [(set (match_operand:DWI 0 "register_operand" "=&r")
9863 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
9864 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9865 (clobber (reg:CC FLAGS_REG))]
9866 ""
9867 "#"
9868 [(set_attr "type" "multi")])
9869
9870 (define_split
9871 [(set (match_operand:DWI 0 "register_operand")
9872 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9873 (match_operand:QI 2 "nonmemory_operand")))
9874 (clobber (reg:CC FLAGS_REG))]
9875 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9876 [(const_int 0)]
9877 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9878
9879 ;; By default we don't ask for a scratch register, because when DWImode
9880 ;; values are manipulated, registers are already at a premium. But if
9881 ;; we have one handy, we won't turn it away.
9882
9883 (define_peephole2
9884 [(match_scratch:DWIH 3 "r")
9885 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9886 (ashift:<DWI>
9887 (match_operand:<DWI> 1 "nonmemory_operand")
9888 (match_operand:QI 2 "nonmemory_operand")))
9889 (clobber (reg:CC FLAGS_REG))])
9890 (match_dup 3)]
9891 "TARGET_CMOVE"
9892 [(const_int 0)]
9893 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9894
9895 (define_insn "x86_64_shld"
9896 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9897 (ior:DI (ashift:DI (match_dup 0)
9898 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9899 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9900 (minus:QI (const_int 64) (match_dup 2)))))
9901 (clobber (reg:CC FLAGS_REG))]
9902 "TARGET_64BIT"
9903 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9904 [(set_attr "type" "ishift")
9905 (set_attr "prefix_0f" "1")
9906 (set_attr "mode" "DI")
9907 (set_attr "athlon_decode" "vector")
9908 (set_attr "amdfam10_decode" "vector")
9909 (set_attr "bdver1_decode" "vector")])
9910
9911 (define_insn "x86_shld"
9912 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9913 (ior:SI (ashift:SI (match_dup 0)
9914 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9915 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9916 (minus:QI (const_int 32) (match_dup 2)))))
9917 (clobber (reg:CC FLAGS_REG))]
9918 ""
9919 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9920 [(set_attr "type" "ishift")
9921 (set_attr "prefix_0f" "1")
9922 (set_attr "mode" "SI")
9923 (set_attr "pent_pair" "np")
9924 (set_attr "athlon_decode" "vector")
9925 (set_attr "amdfam10_decode" "vector")
9926 (set_attr "bdver1_decode" "vector")])
9927
9928 (define_expand "x86_shift<mode>_adj_1"
9929 [(set (reg:CCZ FLAGS_REG)
9930 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9931 (match_dup 4))
9932 (const_int 0)))
9933 (set (match_operand:SWI48 0 "register_operand")
9934 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9935 (match_operand:SWI48 1 "register_operand")
9936 (match_dup 0)))
9937 (set (match_dup 1)
9938 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9939 (match_operand:SWI48 3 "register_operand")
9940 (match_dup 1)))]
9941 "TARGET_CMOVE"
9942 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9943
9944 (define_expand "x86_shift<mode>_adj_2"
9945 [(use (match_operand:SWI48 0 "register_operand"))
9946 (use (match_operand:SWI48 1 "register_operand"))
9947 (use (match_operand:QI 2 "register_operand"))]
9948 ""
9949 {
9950 rtx_code_label *label = gen_label_rtx ();
9951 rtx tmp;
9952
9953 emit_insn (gen_testqi_ccz_1 (operands[2],
9954 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9955
9956 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9957 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9958 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9959 gen_rtx_LABEL_REF (VOIDmode, label),
9960 pc_rtx);
9961 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9962 JUMP_LABEL (tmp) = label;
9963
9964 emit_move_insn (operands[0], operands[1]);
9965 ix86_expand_clear (operands[1]);
9966
9967 emit_label (label);
9968 LABEL_NUSES (label) = 1;
9969
9970 DONE;
9971 })
9972
9973 ;; Avoid useless masking of count operand.
9974 (define_insn_and_split "*ashl<mode>3_mask"
9975 [(set (match_operand:SWI48 0 "nonimmediate_operand")
9976 (ashift:SWI48
9977 (match_operand:SWI48 1 "nonimmediate_operand")
9978 (subreg:QI
9979 (and:SI
9980 (match_operand:SI 2 "register_operand" "c,r")
9981 (match_operand:SI 3 "const_int_operand")) 0)))
9982 (clobber (reg:CC FLAGS_REG))]
9983 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9984 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9985 == GET_MODE_BITSIZE (<MODE>mode)-1
9986 && can_create_pseudo_p ()"
9987 "#"
9988 "&& 1"
9989 [(parallel
9990 [(set (match_dup 0)
9991 (ashift:SWI48 (match_dup 1)
9992 (match_dup 2)))
9993 (clobber (reg:CC FLAGS_REG))])]
9994 "operands[2] = gen_lowpart (QImode, operands[2]);"
9995 [(set_attr "isa" "*,bmi2")])
9996
9997 (define_insn_and_split "*ashl<mode>3_mask_1"
9998 [(set (match_operand:SWI48 0 "nonimmediate_operand")
9999 (ashift:SWI48
10000 (match_operand:SWI48 1 "nonimmediate_operand")
10001 (and:QI
10002 (match_operand:QI 2 "register_operand" "c,r")
10003 (match_operand:QI 3 "const_int_operand"))))
10004 (clobber (reg:CC FLAGS_REG))]
10005 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10006 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10007 == GET_MODE_BITSIZE (<MODE>mode)-1
10008 && can_create_pseudo_p ()"
10009 "#"
10010 "&& 1"
10011 [(parallel
10012 [(set (match_dup 0)
10013 (ashift:SWI48 (match_dup 1)
10014 (match_dup 2)))
10015 (clobber (reg:CC FLAGS_REG))])]
10016 ""
10017 [(set_attr "isa" "*,bmi2")])
10018
10019 (define_insn "*bmi2_ashl<mode>3_1"
10020 [(set (match_operand:SWI48 0 "register_operand" "=r")
10021 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10022 (match_operand:SWI48 2 "register_operand" "r")))]
10023 "TARGET_BMI2"
10024 "shlx\t{%2, %1, %0|%0, %1, %2}"
10025 [(set_attr "type" "ishiftx")
10026 (set_attr "mode" "<MODE>")])
10027
10028 (define_insn "*ashl<mode>3_1"
10029 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10030 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10031 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10032 (clobber (reg:CC FLAGS_REG))]
10033 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10034 {
10035 switch (get_attr_type (insn))
10036 {
10037 case TYPE_LEA:
10038 case TYPE_ISHIFTX:
10039 return "#";
10040
10041 case TYPE_ALU:
10042 gcc_assert (operands[2] == const1_rtx);
10043 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10044 return "add{<imodesuffix>}\t%0, %0";
10045
10046 default:
10047 if (operands[2] == const1_rtx
10048 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10049 return "sal{<imodesuffix>}\t%0";
10050 else
10051 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10052 }
10053 }
10054 [(set_attr "isa" "*,*,bmi2")
10055 (set (attr "type")
10056 (cond [(eq_attr "alternative" "1")
10057 (const_string "lea")
10058 (eq_attr "alternative" "2")
10059 (const_string "ishiftx")
10060 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10061 (match_operand 0 "register_operand"))
10062 (match_operand 2 "const1_operand"))
10063 (const_string "alu")
10064 ]
10065 (const_string "ishift")))
10066 (set (attr "length_immediate")
10067 (if_then_else
10068 (ior (eq_attr "type" "alu")
10069 (and (eq_attr "type" "ishift")
10070 (and (match_operand 2 "const1_operand")
10071 (ior (match_test "TARGET_SHIFT1")
10072 (match_test "optimize_function_for_size_p (cfun)")))))
10073 (const_string "0")
10074 (const_string "*")))
10075 (set_attr "mode" "<MODE>")])
10076
10077 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10078 (define_split
10079 [(set (match_operand:SWI48 0 "register_operand")
10080 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10081 (match_operand:QI 2 "register_operand")))
10082 (clobber (reg:CC FLAGS_REG))]
10083 "TARGET_BMI2 && reload_completed"
10084 [(set (match_dup 0)
10085 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10086 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10087
10088 (define_insn "*bmi2_ashlsi3_1_zext"
10089 [(set (match_operand:DI 0 "register_operand" "=r")
10090 (zero_extend:DI
10091 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10092 (match_operand:SI 2 "register_operand" "r"))))]
10093 "TARGET_64BIT && TARGET_BMI2"
10094 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10095 [(set_attr "type" "ishiftx")
10096 (set_attr "mode" "SI")])
10097
10098 (define_insn "*ashlsi3_1_zext"
10099 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10100 (zero_extend:DI
10101 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10102 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10103 (clobber (reg:CC FLAGS_REG))]
10104 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10105 {
10106 switch (get_attr_type (insn))
10107 {
10108 case TYPE_LEA:
10109 case TYPE_ISHIFTX:
10110 return "#";
10111
10112 case TYPE_ALU:
10113 gcc_assert (operands[2] == const1_rtx);
10114 return "add{l}\t%k0, %k0";
10115
10116 default:
10117 if (operands[2] == const1_rtx
10118 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10119 return "sal{l}\t%k0";
10120 else
10121 return "sal{l}\t{%2, %k0|%k0, %2}";
10122 }
10123 }
10124 [(set_attr "isa" "*,*,bmi2")
10125 (set (attr "type")
10126 (cond [(eq_attr "alternative" "1")
10127 (const_string "lea")
10128 (eq_attr "alternative" "2")
10129 (const_string "ishiftx")
10130 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10131 (match_operand 2 "const1_operand"))
10132 (const_string "alu")
10133 ]
10134 (const_string "ishift")))
10135 (set (attr "length_immediate")
10136 (if_then_else
10137 (ior (eq_attr "type" "alu")
10138 (and (eq_attr "type" "ishift")
10139 (and (match_operand 2 "const1_operand")
10140 (ior (match_test "TARGET_SHIFT1")
10141 (match_test "optimize_function_for_size_p (cfun)")))))
10142 (const_string "0")
10143 (const_string "*")))
10144 (set_attr "mode" "SI")])
10145
10146 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10147 (define_split
10148 [(set (match_operand:DI 0 "register_operand")
10149 (zero_extend:DI
10150 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10151 (match_operand:QI 2 "register_operand"))))
10152 (clobber (reg:CC FLAGS_REG))]
10153 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10154 [(set (match_dup 0)
10155 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10156 "operands[2] = gen_lowpart (SImode, operands[2]);")
10157
10158 (define_insn "*ashlhi3_1"
10159 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10160 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10161 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10162 (clobber (reg:CC FLAGS_REG))]
10163 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10164 {
10165 switch (get_attr_type (insn))
10166 {
10167 case TYPE_LEA:
10168 return "#";
10169
10170 case TYPE_ALU:
10171 gcc_assert (operands[2] == const1_rtx);
10172 return "add{w}\t%0, %0";
10173
10174 default:
10175 if (operands[2] == const1_rtx
10176 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10177 return "sal{w}\t%0";
10178 else
10179 return "sal{w}\t{%2, %0|%0, %2}";
10180 }
10181 }
10182 [(set (attr "type")
10183 (cond [(eq_attr "alternative" "1")
10184 (const_string "lea")
10185 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10186 (match_operand 0 "register_operand"))
10187 (match_operand 2 "const1_operand"))
10188 (const_string "alu")
10189 ]
10190 (const_string "ishift")))
10191 (set (attr "length_immediate")
10192 (if_then_else
10193 (ior (eq_attr "type" "alu")
10194 (and (eq_attr "type" "ishift")
10195 (and (match_operand 2 "const1_operand")
10196 (ior (match_test "TARGET_SHIFT1")
10197 (match_test "optimize_function_for_size_p (cfun)")))))
10198 (const_string "0")
10199 (const_string "*")))
10200 (set_attr "mode" "HI,SI")])
10201
10202 (define_insn "*ashlqi3_1"
10203 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10204 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10205 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10206 (clobber (reg:CC FLAGS_REG))]
10207 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10208 {
10209 switch (get_attr_type (insn))
10210 {
10211 case TYPE_LEA:
10212 return "#";
10213
10214 case TYPE_ALU:
10215 gcc_assert (operands[2] == const1_rtx);
10216 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10217 return "add{l}\t%k0, %k0";
10218 else
10219 return "add{b}\t%0, %0";
10220
10221 default:
10222 if (operands[2] == const1_rtx
10223 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10224 {
10225 if (get_attr_mode (insn) == MODE_SI)
10226 return "sal{l}\t%k0";
10227 else
10228 return "sal{b}\t%0";
10229 }
10230 else
10231 {
10232 if (get_attr_mode (insn) == MODE_SI)
10233 return "sal{l}\t{%2, %k0|%k0, %2}";
10234 else
10235 return "sal{b}\t{%2, %0|%0, %2}";
10236 }
10237 }
10238 }
10239 [(set (attr "type")
10240 (cond [(eq_attr "alternative" "2")
10241 (const_string "lea")
10242 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10243 (match_operand 0 "register_operand"))
10244 (match_operand 2 "const1_operand"))
10245 (const_string "alu")
10246 ]
10247 (const_string "ishift")))
10248 (set (attr "length_immediate")
10249 (if_then_else
10250 (ior (eq_attr "type" "alu")
10251 (and (eq_attr "type" "ishift")
10252 (and (match_operand 2 "const1_operand")
10253 (ior (match_test "TARGET_SHIFT1")
10254 (match_test "optimize_function_for_size_p (cfun)")))))
10255 (const_string "0")
10256 (const_string "*")))
10257 (set_attr "mode" "QI,SI,SI")
10258 ;; Potential partial reg stall on alternative 1.
10259 (set (attr "preferred_for_speed")
10260 (cond [(eq_attr "alternative" "1")
10261 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10262 (symbol_ref "true")))])
10263
10264 (define_insn "*ashlqi3_1_slp"
10265 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10266 (ashift:QI (match_dup 0)
10267 (match_operand:QI 1 "nonmemory_operand" "cI")))
10268 (clobber (reg:CC FLAGS_REG))]
10269 "(optimize_function_for_size_p (cfun)
10270 || !TARGET_PARTIAL_FLAG_REG_STALL
10271 || (operands[1] == const1_rtx
10272 && (TARGET_SHIFT1
10273 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10274 {
10275 switch (get_attr_type (insn))
10276 {
10277 case TYPE_ALU1:
10278 gcc_assert (operands[1] == const1_rtx);
10279 return "add{b}\t%0, %0";
10280
10281 default:
10282 if (operands[1] == const1_rtx
10283 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10284 return "sal{b}\t%0";
10285 else
10286 return "sal{b}\t{%1, %0|%0, %1}";
10287 }
10288 }
10289 [(set (attr "type")
10290 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10291 (match_operand 0 "register_operand"))
10292 (match_operand 1 "const1_operand"))
10293 (const_string "alu1")
10294 ]
10295 (const_string "ishift1")))
10296 (set (attr "length_immediate")
10297 (if_then_else
10298 (ior (eq_attr "type" "alu1")
10299 (and (eq_attr "type" "ishift1")
10300 (and (match_operand 1 "const1_operand")
10301 (ior (match_test "TARGET_SHIFT1")
10302 (match_test "optimize_function_for_size_p (cfun)")))))
10303 (const_string "0")
10304 (const_string "*")))
10305 (set_attr "mode" "QI")])
10306
10307 ;; Convert ashift to the lea pattern to avoid flags dependency.
10308 (define_split
10309 [(set (match_operand:SWI 0 "register_operand")
10310 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10311 (match_operand 2 "const_0_to_3_operand")))
10312 (clobber (reg:CC FLAGS_REG))]
10313 "reload_completed
10314 && REGNO (operands[0]) != REGNO (operands[1])"
10315 [(set (match_dup 0)
10316 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10317 {
10318 if (<MODE>mode != <LEAMODE>mode)
10319 {
10320 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10321 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10322 }
10323 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10324 })
10325
10326 ;; Convert ashift to the lea pattern to avoid flags dependency.
10327 (define_split
10328 [(set (match_operand:DI 0 "register_operand")
10329 (zero_extend:DI
10330 (ashift:SI (match_operand:SI 1 "index_register_operand")
10331 (match_operand 2 "const_0_to_3_operand"))))
10332 (clobber (reg:CC FLAGS_REG))]
10333 "TARGET_64BIT && reload_completed
10334 && REGNO (operands[0]) != REGNO (operands[1])"
10335 [(set (match_dup 0)
10336 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10337 {
10338 operands[1] = gen_lowpart (SImode, operands[1]);
10339 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10340 })
10341
10342 ;; This pattern can't accept a variable shift count, since shifts by
10343 ;; zero don't affect the flags. We assume that shifts by constant
10344 ;; zero are optimized away.
10345 (define_insn "*ashl<mode>3_cmp"
10346 [(set (reg FLAGS_REG)
10347 (compare
10348 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10349 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10350 (const_int 0)))
10351 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10352 (ashift:SWI (match_dup 1) (match_dup 2)))]
10353 "(optimize_function_for_size_p (cfun)
10354 || !TARGET_PARTIAL_FLAG_REG_STALL
10355 || (operands[2] == const1_rtx
10356 && (TARGET_SHIFT1
10357 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10358 && ix86_match_ccmode (insn, CCGOCmode)
10359 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10360 {
10361 switch (get_attr_type (insn))
10362 {
10363 case TYPE_ALU:
10364 gcc_assert (operands[2] == const1_rtx);
10365 return "add{<imodesuffix>}\t%0, %0";
10366
10367 default:
10368 if (operands[2] == const1_rtx
10369 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10370 return "sal{<imodesuffix>}\t%0";
10371 else
10372 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10373 }
10374 }
10375 [(set (attr "type")
10376 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10377 (match_operand 0 "register_operand"))
10378 (match_operand 2 "const1_operand"))
10379 (const_string "alu")
10380 ]
10381 (const_string "ishift")))
10382 (set (attr "length_immediate")
10383 (if_then_else
10384 (ior (eq_attr "type" "alu")
10385 (and (eq_attr "type" "ishift")
10386 (and (match_operand 2 "const1_operand")
10387 (ior (match_test "TARGET_SHIFT1")
10388 (match_test "optimize_function_for_size_p (cfun)")))))
10389 (const_string "0")
10390 (const_string "*")))
10391 (set_attr "mode" "<MODE>")])
10392
10393 (define_insn "*ashlsi3_cmp_zext"
10394 [(set (reg FLAGS_REG)
10395 (compare
10396 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10397 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10398 (const_int 0)))
10399 (set (match_operand:DI 0 "register_operand" "=r")
10400 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10401 "TARGET_64BIT
10402 && (optimize_function_for_size_p (cfun)
10403 || !TARGET_PARTIAL_FLAG_REG_STALL
10404 || (operands[2] == const1_rtx
10405 && (TARGET_SHIFT1
10406 || TARGET_DOUBLE_WITH_ADD)))
10407 && ix86_match_ccmode (insn, CCGOCmode)
10408 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10409 {
10410 switch (get_attr_type (insn))
10411 {
10412 case TYPE_ALU:
10413 gcc_assert (operands[2] == const1_rtx);
10414 return "add{l}\t%k0, %k0";
10415
10416 default:
10417 if (operands[2] == const1_rtx
10418 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10419 return "sal{l}\t%k0";
10420 else
10421 return "sal{l}\t{%2, %k0|%k0, %2}";
10422 }
10423 }
10424 [(set (attr "type")
10425 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10426 (match_operand 2 "const1_operand"))
10427 (const_string "alu")
10428 ]
10429 (const_string "ishift")))
10430 (set (attr "length_immediate")
10431 (if_then_else
10432 (ior (eq_attr "type" "alu")
10433 (and (eq_attr "type" "ishift")
10434 (and (match_operand 2 "const1_operand")
10435 (ior (match_test "TARGET_SHIFT1")
10436 (match_test "optimize_function_for_size_p (cfun)")))))
10437 (const_string "0")
10438 (const_string "*")))
10439 (set_attr "mode" "SI")])
10440
10441 (define_insn "*ashl<mode>3_cconly"
10442 [(set (reg FLAGS_REG)
10443 (compare
10444 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10445 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10446 (const_int 0)))
10447 (clobber (match_scratch:SWI 0 "=<r>"))]
10448 "(optimize_function_for_size_p (cfun)
10449 || !TARGET_PARTIAL_FLAG_REG_STALL
10450 || (operands[2] == const1_rtx
10451 && (TARGET_SHIFT1
10452 || TARGET_DOUBLE_WITH_ADD)))
10453 && ix86_match_ccmode (insn, CCGOCmode)"
10454 {
10455 switch (get_attr_type (insn))
10456 {
10457 case TYPE_ALU:
10458 gcc_assert (operands[2] == const1_rtx);
10459 return "add{<imodesuffix>}\t%0, %0";
10460
10461 default:
10462 if (operands[2] == const1_rtx
10463 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10464 return "sal{<imodesuffix>}\t%0";
10465 else
10466 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10467 }
10468 }
10469 [(set (attr "type")
10470 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10471 (match_operand 0 "register_operand"))
10472 (match_operand 2 "const1_operand"))
10473 (const_string "alu")
10474 ]
10475 (const_string "ishift")))
10476 (set (attr "length_immediate")
10477 (if_then_else
10478 (ior (eq_attr "type" "alu")
10479 (and (eq_attr "type" "ishift")
10480 (and (match_operand 2 "const1_operand")
10481 (ior (match_test "TARGET_SHIFT1")
10482 (match_test "optimize_function_for_size_p (cfun)")))))
10483 (const_string "0")
10484 (const_string "*")))
10485 (set_attr "mode" "<MODE>")])
10486
10487 ;; See comment above `ashl<mode>3' about how this works.
10488
10489 (define_expand "<shift_insn><mode>3"
10490 [(set (match_operand:SDWIM 0 "<shift_operand>")
10491 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10492 (match_operand:QI 2 "nonmemory_operand")))]
10493 ""
10494 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10495
10496 ;; Avoid useless masking of count operand.
10497 (define_insn_and_split "*<shift_insn><mode>3_mask"
10498 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10499 (any_shiftrt:SWI48
10500 (match_operand:SWI48 1 "nonimmediate_operand")
10501 (subreg:QI
10502 (and:SI
10503 (match_operand:SI 2 "register_operand" "c,r")
10504 (match_operand:SI 3 "const_int_operand")) 0)))
10505 (clobber (reg:CC FLAGS_REG))]
10506 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10507 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10508 == GET_MODE_BITSIZE (<MODE>mode)-1
10509 && can_create_pseudo_p ()"
10510 "#"
10511 "&& 1"
10512 [(parallel
10513 [(set (match_dup 0)
10514 (any_shiftrt:SWI48 (match_dup 1)
10515 (match_dup 2)))
10516 (clobber (reg:CC FLAGS_REG))])]
10517 "operands[2] = gen_lowpart (QImode, operands[2]);"
10518 [(set_attr "isa" "*,bmi2")])
10519
10520 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10521 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10522 (any_shiftrt:SWI48
10523 (match_operand:SWI48 1 "nonimmediate_operand")
10524 (and:QI
10525 (match_operand:QI 2 "register_operand" "c,r")
10526 (match_operand:QI 3 "const_int_operand"))))
10527 (clobber (reg:CC FLAGS_REG))]
10528 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10529 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10530 == GET_MODE_BITSIZE (<MODE>mode)-1
10531 && can_create_pseudo_p ()"
10532 "#"
10533 "&& 1"
10534 [(parallel
10535 [(set (match_dup 0)
10536 (any_shiftrt:SWI48 (match_dup 1)
10537 (match_dup 2)))
10538 (clobber (reg:CC FLAGS_REG))])]
10539 ""
10540 [(set_attr "isa" "*,bmi2")])
10541
10542 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
10543 [(set (match_operand:<DWI> 0 "register_operand")
10544 (any_shiftrt:<DWI>
10545 (match_operand:<DWI> 1 "register_operand")
10546 (subreg:QI
10547 (and:SI
10548 (match_operand:SI 2 "register_operand" "c")
10549 (match_operand:SI 3 "const_int_operand")) 0)))
10550 (clobber (reg:CC FLAGS_REG))]
10551 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10552 && can_create_pseudo_p ()"
10553 "#"
10554 "&& 1"
10555 [(parallel
10556 [(set (match_dup 4)
10557 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10558 (ashift:DWIH (match_dup 7)
10559 (minus:QI (match_dup 8) (match_dup 2)))))
10560 (clobber (reg:CC FLAGS_REG))])
10561 (parallel
10562 [(set (match_dup 6)
10563 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10564 (clobber (reg:CC FLAGS_REG))])]
10565 {
10566 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10567
10568 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10569
10570 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10571 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10572 {
10573 rtx tem = gen_reg_rtx (SImode);
10574 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10575 operands[2] = tem;
10576 }
10577
10578 operands[2] = gen_lowpart (QImode, operands[2]);
10579
10580 if (!rtx_equal_p (operands[4], operands[5]))
10581 emit_move_insn (operands[4], operands[5]);
10582 })
10583
10584 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
10585 [(set (match_operand:<DWI> 0 "register_operand")
10586 (any_shiftrt:<DWI>
10587 (match_operand:<DWI> 1 "register_operand")
10588 (and:QI
10589 (match_operand:QI 2 "register_operand" "c")
10590 (match_operand:QI 3 "const_int_operand"))))
10591 (clobber (reg:CC FLAGS_REG))]
10592 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10593 && can_create_pseudo_p ()"
10594 "#"
10595 "&& 1"
10596 [(parallel
10597 [(set (match_dup 4)
10598 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10599 (ashift:DWIH (match_dup 7)
10600 (minus:QI (match_dup 8) (match_dup 2)))))
10601 (clobber (reg:CC FLAGS_REG))])
10602 (parallel
10603 [(set (match_dup 6)
10604 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10605 (clobber (reg:CC FLAGS_REG))])]
10606 {
10607 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10608
10609 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10610
10611 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10612 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10613 {
10614 rtx tem = gen_reg_rtx (QImode);
10615 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10616 operands[2] = tem;
10617 }
10618
10619 if (!rtx_equal_p (operands[4], operands[5]))
10620 emit_move_insn (operands[4], operands[5]);
10621 })
10622
10623 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10624 [(set (match_operand:DWI 0 "register_operand" "=&r")
10625 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10626 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10627 (clobber (reg:CC FLAGS_REG))]
10628 ""
10629 "#"
10630 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10631 [(const_int 0)]
10632 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10633 [(set_attr "type" "multi")])
10634
10635 ;; By default we don't ask for a scratch register, because when DWImode
10636 ;; values are manipulated, registers are already at a premium. But if
10637 ;; we have one handy, we won't turn it away.
10638
10639 (define_peephole2
10640 [(match_scratch:DWIH 3 "r")
10641 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10642 (any_shiftrt:<DWI>
10643 (match_operand:<DWI> 1 "register_operand")
10644 (match_operand:QI 2 "nonmemory_operand")))
10645 (clobber (reg:CC FLAGS_REG))])
10646 (match_dup 3)]
10647 "TARGET_CMOVE"
10648 [(const_int 0)]
10649 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10650
10651 (define_insn "x86_64_shrd"
10652 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10653 (ior:DI (lshiftrt:DI (match_dup 0)
10654 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10655 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10656 (minus:QI (const_int 64) (match_dup 2)))))
10657 (clobber (reg:CC FLAGS_REG))]
10658 "TARGET_64BIT"
10659 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10660 [(set_attr "type" "ishift")
10661 (set_attr "prefix_0f" "1")
10662 (set_attr "mode" "DI")
10663 (set_attr "athlon_decode" "vector")
10664 (set_attr "amdfam10_decode" "vector")
10665 (set_attr "bdver1_decode" "vector")])
10666
10667 (define_insn "x86_shrd"
10668 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10669 (ior:SI (lshiftrt:SI (match_dup 0)
10670 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10671 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10672 (minus:QI (const_int 32) (match_dup 2)))))
10673 (clobber (reg:CC FLAGS_REG))]
10674 ""
10675 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10676 [(set_attr "type" "ishift")
10677 (set_attr "prefix_0f" "1")
10678 (set_attr "mode" "SI")
10679 (set_attr "pent_pair" "np")
10680 (set_attr "athlon_decode" "vector")
10681 (set_attr "amdfam10_decode" "vector")
10682 (set_attr "bdver1_decode" "vector")])
10683
10684 ;; Base name for insn mnemonic.
10685 (define_mode_attr cvt_mnemonic
10686 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
10687
10688 (define_insn "ashr<mode>3_cvt"
10689 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
10690 (ashiftrt:SWI48
10691 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
10692 (match_operand:QI 2 "const_int_operand")))
10693 (clobber (reg:CC FLAGS_REG))]
10694 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
10695 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10696 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
10697 "@
10698 <cvt_mnemonic>
10699 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
10700 [(set_attr "type" "imovx,ishift")
10701 (set_attr "prefix_0f" "0,*")
10702 (set_attr "length_immediate" "0,*")
10703 (set_attr "modrm" "0,1")
10704 (set_attr "mode" "<MODE>")])
10705
10706 (define_insn "*ashrsi3_cvt_zext"
10707 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10708 (zero_extend:DI
10709 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10710 (match_operand:QI 2 "const_int_operand"))))
10711 (clobber (reg:CC FLAGS_REG))]
10712 "TARGET_64BIT && INTVAL (operands[2]) == 31
10713 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10714 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10715 "@
10716 {cltd|cdq}
10717 sar{l}\t{%2, %k0|%k0, %2}"
10718 [(set_attr "type" "imovx,ishift")
10719 (set_attr "prefix_0f" "0,*")
10720 (set_attr "length_immediate" "0,*")
10721 (set_attr "modrm" "0,1")
10722 (set_attr "mode" "SI")])
10723
10724 (define_expand "x86_shift<mode>_adj_3"
10725 [(use (match_operand:SWI48 0 "register_operand"))
10726 (use (match_operand:SWI48 1 "register_operand"))
10727 (use (match_operand:QI 2 "register_operand"))]
10728 ""
10729 {
10730 rtx_code_label *label = gen_label_rtx ();
10731 rtx tmp;
10732
10733 emit_insn (gen_testqi_ccz_1 (operands[2],
10734 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10735
10736 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10737 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10738 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10739 gen_rtx_LABEL_REF (VOIDmode, label),
10740 pc_rtx);
10741 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10742 JUMP_LABEL (tmp) = label;
10743
10744 emit_move_insn (operands[0], operands[1]);
10745 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10746 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10747 emit_label (label);
10748 LABEL_NUSES (label) = 1;
10749
10750 DONE;
10751 })
10752
10753 (define_insn "*bmi2_<shift_insn><mode>3_1"
10754 [(set (match_operand:SWI48 0 "register_operand" "=r")
10755 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10756 (match_operand:SWI48 2 "register_operand" "r")))]
10757 "TARGET_BMI2"
10758 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10759 [(set_attr "type" "ishiftx")
10760 (set_attr "mode" "<MODE>")])
10761
10762 (define_insn "*<shift_insn><mode>3_1"
10763 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10764 (any_shiftrt:SWI48
10765 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10766 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10767 (clobber (reg:CC FLAGS_REG))]
10768 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10769 {
10770 switch (get_attr_type (insn))
10771 {
10772 case TYPE_ISHIFTX:
10773 return "#";
10774
10775 default:
10776 if (operands[2] == const1_rtx
10777 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10778 return "<shift>{<imodesuffix>}\t%0";
10779 else
10780 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10781 }
10782 }
10783 [(set_attr "isa" "*,bmi2")
10784 (set_attr "type" "ishift,ishiftx")
10785 (set (attr "length_immediate")
10786 (if_then_else
10787 (and (match_operand 2 "const1_operand")
10788 (ior (match_test "TARGET_SHIFT1")
10789 (match_test "optimize_function_for_size_p (cfun)")))
10790 (const_string "0")
10791 (const_string "*")))
10792 (set_attr "mode" "<MODE>")])
10793
10794 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10795 (define_split
10796 [(set (match_operand:SWI48 0 "register_operand")
10797 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10798 (match_operand:QI 2 "register_operand")))
10799 (clobber (reg:CC FLAGS_REG))]
10800 "TARGET_BMI2 && reload_completed"
10801 [(set (match_dup 0)
10802 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10803 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10804
10805 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10806 [(set (match_operand:DI 0 "register_operand" "=r")
10807 (zero_extend:DI
10808 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10809 (match_operand:SI 2 "register_operand" "r"))))]
10810 "TARGET_64BIT && TARGET_BMI2"
10811 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10812 [(set_attr "type" "ishiftx")
10813 (set_attr "mode" "SI")])
10814
10815 (define_insn "*<shift_insn>si3_1_zext"
10816 [(set (match_operand:DI 0 "register_operand" "=r,r")
10817 (zero_extend:DI
10818 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10819 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10820 (clobber (reg:CC FLAGS_REG))]
10821 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10822 {
10823 switch (get_attr_type (insn))
10824 {
10825 case TYPE_ISHIFTX:
10826 return "#";
10827
10828 default:
10829 if (operands[2] == const1_rtx
10830 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10831 return "<shift>{l}\t%k0";
10832 else
10833 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10834 }
10835 }
10836 [(set_attr "isa" "*,bmi2")
10837 (set_attr "type" "ishift,ishiftx")
10838 (set (attr "length_immediate")
10839 (if_then_else
10840 (and (match_operand 2 "const1_operand")
10841 (ior (match_test "TARGET_SHIFT1")
10842 (match_test "optimize_function_for_size_p (cfun)")))
10843 (const_string "0")
10844 (const_string "*")))
10845 (set_attr "mode" "SI")])
10846
10847 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10848 (define_split
10849 [(set (match_operand:DI 0 "register_operand")
10850 (zero_extend:DI
10851 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10852 (match_operand:QI 2 "register_operand"))))
10853 (clobber (reg:CC FLAGS_REG))]
10854 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10855 [(set (match_dup 0)
10856 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10857 "operands[2] = gen_lowpart (SImode, operands[2]);")
10858
10859 (define_insn "*<shift_insn><mode>3_1"
10860 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10861 (any_shiftrt:SWI12
10862 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10863 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10864 (clobber (reg:CC FLAGS_REG))]
10865 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10866 {
10867 if (operands[2] == const1_rtx
10868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10869 return "<shift>{<imodesuffix>}\t%0";
10870 else
10871 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10872 }
10873 [(set_attr "type" "ishift")
10874 (set (attr "length_immediate")
10875 (if_then_else
10876 (and (match_operand 2 "const1_operand")
10877 (ior (match_test "TARGET_SHIFT1")
10878 (match_test "optimize_function_for_size_p (cfun)")))
10879 (const_string "0")
10880 (const_string "*")))
10881 (set_attr "mode" "<MODE>")])
10882
10883 (define_insn "*<shift_insn>qi3_1_slp"
10884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10885 (any_shiftrt:QI (match_dup 0)
10886 (match_operand:QI 1 "nonmemory_operand" "cI")))
10887 (clobber (reg:CC FLAGS_REG))]
10888 "(optimize_function_for_size_p (cfun)
10889 || !TARGET_PARTIAL_REG_STALL
10890 || (operands[1] == const1_rtx
10891 && TARGET_SHIFT1))"
10892 {
10893 if (operands[1] == const1_rtx
10894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10895 return "<shift>{b}\t%0";
10896 else
10897 return "<shift>{b}\t{%1, %0|%0, %1}";
10898 }
10899 [(set_attr "type" "ishift1")
10900 (set (attr "length_immediate")
10901 (if_then_else
10902 (and (match_operand 1 "const1_operand")
10903 (ior (match_test "TARGET_SHIFT1")
10904 (match_test "optimize_function_for_size_p (cfun)")))
10905 (const_string "0")
10906 (const_string "*")))
10907 (set_attr "mode" "QI")])
10908
10909 ;; This pattern can't accept a variable shift count, since shifts by
10910 ;; zero don't affect the flags. We assume that shifts by constant
10911 ;; zero are optimized away.
10912 (define_insn "*<shift_insn><mode>3_cmp"
10913 [(set (reg FLAGS_REG)
10914 (compare
10915 (any_shiftrt:SWI
10916 (match_operand:SWI 1 "nonimmediate_operand" "0")
10917 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10918 (const_int 0)))
10919 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10920 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10921 "(optimize_function_for_size_p (cfun)
10922 || !TARGET_PARTIAL_FLAG_REG_STALL
10923 || (operands[2] == const1_rtx
10924 && TARGET_SHIFT1))
10925 && ix86_match_ccmode (insn, CCGOCmode)
10926 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10927 {
10928 if (operands[2] == const1_rtx
10929 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10930 return "<shift>{<imodesuffix>}\t%0";
10931 else
10932 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10933 }
10934 [(set_attr "type" "ishift")
10935 (set (attr "length_immediate")
10936 (if_then_else
10937 (and (match_operand 2 "const1_operand")
10938 (ior (match_test "TARGET_SHIFT1")
10939 (match_test "optimize_function_for_size_p (cfun)")))
10940 (const_string "0")
10941 (const_string "*")))
10942 (set_attr "mode" "<MODE>")])
10943
10944 (define_insn "*<shift_insn>si3_cmp_zext"
10945 [(set (reg FLAGS_REG)
10946 (compare
10947 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10948 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10949 (const_int 0)))
10950 (set (match_operand:DI 0 "register_operand" "=r")
10951 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10952 "TARGET_64BIT
10953 && (optimize_function_for_size_p (cfun)
10954 || !TARGET_PARTIAL_FLAG_REG_STALL
10955 || (operands[2] == const1_rtx
10956 && TARGET_SHIFT1))
10957 && ix86_match_ccmode (insn, CCGOCmode)
10958 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10959 {
10960 if (operands[2] == const1_rtx
10961 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10962 return "<shift>{l}\t%k0";
10963 else
10964 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10965 }
10966 [(set_attr "type" "ishift")
10967 (set (attr "length_immediate")
10968 (if_then_else
10969 (and (match_operand 2 "const1_operand")
10970 (ior (match_test "TARGET_SHIFT1")
10971 (match_test "optimize_function_for_size_p (cfun)")))
10972 (const_string "0")
10973 (const_string "*")))
10974 (set_attr "mode" "SI")])
10975
10976 (define_insn "*<shift_insn><mode>3_cconly"
10977 [(set (reg FLAGS_REG)
10978 (compare
10979 (any_shiftrt:SWI
10980 (match_operand:SWI 1 "register_operand" "0")
10981 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10982 (const_int 0)))
10983 (clobber (match_scratch:SWI 0 "=<r>"))]
10984 "(optimize_function_for_size_p (cfun)
10985 || !TARGET_PARTIAL_FLAG_REG_STALL
10986 || (operands[2] == const1_rtx
10987 && TARGET_SHIFT1))
10988 && ix86_match_ccmode (insn, CCGOCmode)"
10989 {
10990 if (operands[2] == const1_rtx
10991 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10992 return "<shift>{<imodesuffix>}\t%0";
10993 else
10994 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10995 }
10996 [(set_attr "type" "ishift")
10997 (set (attr "length_immediate")
10998 (if_then_else
10999 (and (match_operand 2 "const1_operand")
11000 (ior (match_test "TARGET_SHIFT1")
11001 (match_test "optimize_function_for_size_p (cfun)")))
11002 (const_string "0")
11003 (const_string "*")))
11004 (set_attr "mode" "<MODE>")])
11005 \f
11006 ;; Rotate instructions
11007
11008 (define_expand "<rotate_insn>ti3"
11009 [(set (match_operand:TI 0 "register_operand")
11010 (any_rotate:TI (match_operand:TI 1 "register_operand")
11011 (match_operand:QI 2 "nonmemory_operand")))]
11012 "TARGET_64BIT"
11013 {
11014 if (const_1_to_63_operand (operands[2], VOIDmode))
11015 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11016 (operands[0], operands[1], operands[2]));
11017 else
11018 FAIL;
11019
11020 DONE;
11021 })
11022
11023 (define_expand "<rotate_insn>di3"
11024 [(set (match_operand:DI 0 "shiftdi_operand")
11025 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11026 (match_operand:QI 2 "nonmemory_operand")))]
11027 ""
11028 {
11029 if (TARGET_64BIT)
11030 ix86_expand_binary_operator (<CODE>, DImode, operands);
11031 else if (const_1_to_31_operand (operands[2], VOIDmode))
11032 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11033 (operands[0], operands[1], operands[2]));
11034 else
11035 FAIL;
11036
11037 DONE;
11038 })
11039
11040 (define_expand "<rotate_insn><mode>3"
11041 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11042 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11043 (match_operand:QI 2 "nonmemory_operand")))]
11044 ""
11045 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11046
11047 ;; Avoid useless masking of count operand.
11048 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11049 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11050 (any_rotate:SWI48
11051 (match_operand:SWI48 1 "nonimmediate_operand")
11052 (subreg:QI
11053 (and:SI
11054 (match_operand:SI 2 "register_operand" "c")
11055 (match_operand:SI 3 "const_int_operand")) 0)))
11056 (clobber (reg:CC FLAGS_REG))]
11057 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11058 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11059 == GET_MODE_BITSIZE (<MODE>mode)-1
11060 && can_create_pseudo_p ()"
11061 "#"
11062 "&& 1"
11063 [(parallel
11064 [(set (match_dup 0)
11065 (any_rotate:SWI48 (match_dup 1)
11066 (match_dup 2)))
11067 (clobber (reg:CC FLAGS_REG))])]
11068 "operands[2] = gen_lowpart (QImode, operands[2]);")
11069
11070 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11071 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11072 (any_rotate:SWI48
11073 (match_operand:SWI48 1 "nonimmediate_operand")
11074 (and:QI
11075 (match_operand:QI 2 "register_operand" "c")
11076 (match_operand:QI 3 "const_int_operand"))))
11077 (clobber (reg:CC FLAGS_REG))]
11078 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11079 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11080 == GET_MODE_BITSIZE (<MODE>mode)-1
11081 && can_create_pseudo_p ()"
11082 "#"
11083 "&& 1"
11084 [(parallel
11085 [(set (match_dup 0)
11086 (any_rotate:SWI48 (match_dup 1)
11087 (match_dup 2)))
11088 (clobber (reg:CC FLAGS_REG))])])
11089
11090 ;; Implement rotation using two double-precision
11091 ;; shift instructions and a scratch register.
11092
11093 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11094 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11095 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11096 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11097 (clobber (reg:CC FLAGS_REG))
11098 (clobber (match_scratch:DWIH 3 "=&r"))]
11099 ""
11100 "#"
11101 "reload_completed"
11102 [(set (match_dup 3) (match_dup 4))
11103 (parallel
11104 [(set (match_dup 4)
11105 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11106 (lshiftrt:DWIH (match_dup 5)
11107 (minus:QI (match_dup 6) (match_dup 2)))))
11108 (clobber (reg:CC FLAGS_REG))])
11109 (parallel
11110 [(set (match_dup 5)
11111 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11112 (lshiftrt:DWIH (match_dup 3)
11113 (minus:QI (match_dup 6) (match_dup 2)))))
11114 (clobber (reg:CC FLAGS_REG))])]
11115 {
11116 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11117
11118 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11119 })
11120
11121 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11122 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11123 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11124 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11125 (clobber (reg:CC FLAGS_REG))
11126 (clobber (match_scratch:DWIH 3 "=&r"))]
11127 ""
11128 "#"
11129 "reload_completed"
11130 [(set (match_dup 3) (match_dup 4))
11131 (parallel
11132 [(set (match_dup 4)
11133 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11134 (ashift:DWIH (match_dup 5)
11135 (minus:QI (match_dup 6) (match_dup 2)))))
11136 (clobber (reg:CC FLAGS_REG))])
11137 (parallel
11138 [(set (match_dup 5)
11139 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11140 (ashift:DWIH (match_dup 3)
11141 (minus:QI (match_dup 6) (match_dup 2)))))
11142 (clobber (reg:CC FLAGS_REG))])]
11143 {
11144 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11145
11146 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11147 })
11148
11149 (define_mode_attr rorx_immediate_operand
11150 [(SI "const_0_to_31_operand")
11151 (DI "const_0_to_63_operand")])
11152
11153 (define_insn "*bmi2_rorx<mode>3_1"
11154 [(set (match_operand:SWI48 0 "register_operand" "=r")
11155 (rotatert:SWI48
11156 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11157 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11158 "TARGET_BMI2"
11159 "rorx\t{%2, %1, %0|%0, %1, %2}"
11160 [(set_attr "type" "rotatex")
11161 (set_attr "mode" "<MODE>")])
11162
11163 (define_insn "*<rotate_insn><mode>3_1"
11164 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11165 (any_rotate:SWI48
11166 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11167 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11168 (clobber (reg:CC FLAGS_REG))]
11169 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11170 {
11171 switch (get_attr_type (insn))
11172 {
11173 case TYPE_ROTATEX:
11174 return "#";
11175
11176 default:
11177 if (operands[2] == const1_rtx
11178 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11179 return "<rotate>{<imodesuffix>}\t%0";
11180 else
11181 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11182 }
11183 }
11184 [(set_attr "isa" "*,bmi2")
11185 (set_attr "type" "rotate,rotatex")
11186 (set (attr "length_immediate")
11187 (if_then_else
11188 (and (eq_attr "type" "rotate")
11189 (and (match_operand 2 "const1_operand")
11190 (ior (match_test "TARGET_SHIFT1")
11191 (match_test "optimize_function_for_size_p (cfun)"))))
11192 (const_string "0")
11193 (const_string "*")))
11194 (set_attr "mode" "<MODE>")])
11195
11196 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11197 (define_split
11198 [(set (match_operand:SWI48 0 "register_operand")
11199 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11200 (match_operand:QI 2 "const_int_operand")))
11201 (clobber (reg:CC FLAGS_REG))]
11202 "TARGET_BMI2 && reload_completed"
11203 [(set (match_dup 0)
11204 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11205 {
11206 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11207
11208 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11209 })
11210
11211 (define_split
11212 [(set (match_operand:SWI48 0 "register_operand")
11213 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11214 (match_operand:QI 2 "const_int_operand")))
11215 (clobber (reg:CC FLAGS_REG))]
11216 "TARGET_BMI2 && reload_completed"
11217 [(set (match_dup 0)
11218 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11219
11220 (define_insn "*bmi2_rorxsi3_1_zext"
11221 [(set (match_operand:DI 0 "register_operand" "=r")
11222 (zero_extend:DI
11223 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11224 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11225 "TARGET_64BIT && TARGET_BMI2"
11226 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11227 [(set_attr "type" "rotatex")
11228 (set_attr "mode" "SI")])
11229
11230 (define_insn "*<rotate_insn>si3_1_zext"
11231 [(set (match_operand:DI 0 "register_operand" "=r,r")
11232 (zero_extend:DI
11233 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11234 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11235 (clobber (reg:CC FLAGS_REG))]
11236 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11237 {
11238 switch (get_attr_type (insn))
11239 {
11240 case TYPE_ROTATEX:
11241 return "#";
11242
11243 default:
11244 if (operands[2] == const1_rtx
11245 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11246 return "<rotate>{l}\t%k0";
11247 else
11248 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11249 }
11250 }
11251 [(set_attr "isa" "*,bmi2")
11252 (set_attr "type" "rotate,rotatex")
11253 (set (attr "length_immediate")
11254 (if_then_else
11255 (and (eq_attr "type" "rotate")
11256 (and (match_operand 2 "const1_operand")
11257 (ior (match_test "TARGET_SHIFT1")
11258 (match_test "optimize_function_for_size_p (cfun)"))))
11259 (const_string "0")
11260 (const_string "*")))
11261 (set_attr "mode" "SI")])
11262
11263 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11264 (define_split
11265 [(set (match_operand:DI 0 "register_operand")
11266 (zero_extend:DI
11267 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11268 (match_operand:QI 2 "const_int_operand"))))
11269 (clobber (reg:CC FLAGS_REG))]
11270 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11271 [(set (match_dup 0)
11272 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11273 {
11274 int bitsize = GET_MODE_BITSIZE (SImode);
11275
11276 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11277 })
11278
11279 (define_split
11280 [(set (match_operand:DI 0 "register_operand")
11281 (zero_extend:DI
11282 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11283 (match_operand:QI 2 "const_int_operand"))))
11284 (clobber (reg:CC FLAGS_REG))]
11285 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11286 [(set (match_dup 0)
11287 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11288
11289 (define_insn "*<rotate_insn><mode>3_1"
11290 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11291 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11292 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11293 (clobber (reg:CC FLAGS_REG))]
11294 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11295 {
11296 if (operands[2] == const1_rtx
11297 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11298 return "<rotate>{<imodesuffix>}\t%0";
11299 else
11300 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11301 }
11302 [(set_attr "type" "rotate")
11303 (set (attr "length_immediate")
11304 (if_then_else
11305 (and (match_operand 2 "const1_operand")
11306 (ior (match_test "TARGET_SHIFT1")
11307 (match_test "optimize_function_for_size_p (cfun)")))
11308 (const_string "0")
11309 (const_string "*")))
11310 (set_attr "mode" "<MODE>")])
11311
11312 (define_insn "*<rotate_insn>qi3_1_slp"
11313 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11314 (any_rotate:QI (match_dup 0)
11315 (match_operand:QI 1 "nonmemory_operand" "cI")))
11316 (clobber (reg:CC FLAGS_REG))]
11317 "(optimize_function_for_size_p (cfun)
11318 || !TARGET_PARTIAL_REG_STALL
11319 || (operands[1] == const1_rtx
11320 && TARGET_SHIFT1))"
11321 {
11322 if (operands[1] == const1_rtx
11323 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11324 return "<rotate>{b}\t%0";
11325 else
11326 return "<rotate>{b}\t{%1, %0|%0, %1}";
11327 }
11328 [(set_attr "type" "rotate1")
11329 (set (attr "length_immediate")
11330 (if_then_else
11331 (and (match_operand 1 "const1_operand")
11332 (ior (match_test "TARGET_SHIFT1")
11333 (match_test "optimize_function_for_size_p (cfun)")))
11334 (const_string "0")
11335 (const_string "*")))
11336 (set_attr "mode" "QI")])
11337
11338 (define_split
11339 [(set (match_operand:HI 0 "QIreg_operand")
11340 (any_rotate:HI (match_dup 0) (const_int 8)))
11341 (clobber (reg:CC FLAGS_REG))]
11342 "reload_completed
11343 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11344 [(parallel [(set (strict_low_part (match_dup 0))
11345 (bswap:HI (match_dup 0)))
11346 (clobber (reg:CC FLAGS_REG))])])
11347 \f
11348 ;; Bit set / bit test instructions
11349
11350 ;; %%% bts, btr, btc
11351
11352 ;; These instructions are *slow* when applied to memory.
11353
11354 (define_code_attr btsc [(ior "bts") (xor "btc")])
11355
11356 (define_insn "*<btsc><mode>"
11357 [(set (match_operand:SWI48 0 "register_operand" "=r")
11358 (any_or:SWI48
11359 (ashift:SWI48 (const_int 1)
11360 (match_operand:QI 2 "register_operand" "r"))
11361 (match_operand:SWI48 1 "register_operand" "0")))
11362 (clobber (reg:CC FLAGS_REG))]
11363 "TARGET_USE_BT"
11364 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11365 [(set_attr "type" "alu1")
11366 (set_attr "prefix_0f" "1")
11367 (set_attr "znver1_decode" "double")
11368 (set_attr "mode" "<MODE>")])
11369
11370 ;; Avoid useless masking of count operand.
11371 (define_insn_and_split "*<btsc><mode>_mask"
11372 [(set (match_operand:SWI48 0 "register_operand")
11373 (any_or:SWI48
11374 (ashift:SWI48
11375 (const_int 1)
11376 (subreg:QI
11377 (and:SI
11378 (match_operand:SI 1 "register_operand")
11379 (match_operand:SI 2 "const_int_operand")) 0))
11380 (match_operand:SWI48 3 "register_operand")))
11381 (clobber (reg:CC FLAGS_REG))]
11382 "TARGET_USE_BT
11383 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11384 == GET_MODE_BITSIZE (<MODE>mode)-1
11385 && can_create_pseudo_p ()"
11386 "#"
11387 "&& 1"
11388 [(parallel
11389 [(set (match_dup 0)
11390 (any_or:SWI48
11391 (ashift:SWI48 (const_int 1)
11392 (match_dup 1))
11393 (match_dup 3)))
11394 (clobber (reg:CC FLAGS_REG))])]
11395 "operands[1] = gen_lowpart (QImode, operands[1]);")
11396
11397 (define_insn_and_split "*<btsc><mode>_mask_1"
11398 [(set (match_operand:SWI48 0 "register_operand")
11399 (any_or:SWI48
11400 (ashift:SWI48
11401 (const_int 1)
11402 (and:QI
11403 (match_operand:QI 1 "register_operand")
11404 (match_operand:QI 2 "const_int_operand")))
11405 (match_operand:SWI48 3 "register_operand")))
11406 (clobber (reg:CC FLAGS_REG))]
11407 "TARGET_USE_BT
11408 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11409 == GET_MODE_BITSIZE (<MODE>mode)-1
11410 && can_create_pseudo_p ()"
11411 "#"
11412 "&& 1"
11413 [(parallel
11414 [(set (match_dup 0)
11415 (any_or:SWI48
11416 (ashift:SWI48 (const_int 1)
11417 (match_dup 1))
11418 (match_dup 3)))
11419 (clobber (reg:CC FLAGS_REG))])])
11420
11421 (define_insn "*btr<mode>"
11422 [(set (match_operand:SWI48 0 "register_operand" "=r")
11423 (and:SWI48
11424 (rotate:SWI48 (const_int -2)
11425 (match_operand:QI 2 "register_operand" "r"))
11426 (match_operand:SWI48 1 "register_operand" "0")))
11427 (clobber (reg:CC FLAGS_REG))]
11428 "TARGET_USE_BT"
11429 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11430 [(set_attr "type" "alu1")
11431 (set_attr "prefix_0f" "1")
11432 (set_attr "znver1_decode" "double")
11433 (set_attr "mode" "<MODE>")])
11434
11435 ;; Avoid useless masking of count operand.
11436 (define_insn_and_split "*btr<mode>_mask"
11437 [(set (match_operand:SWI48 0 "register_operand")
11438 (and:SWI48
11439 (rotate:SWI48
11440 (const_int -2)
11441 (subreg:QI
11442 (and:SI
11443 (match_operand:SI 1 "register_operand")
11444 (match_operand:SI 2 "const_int_operand")) 0))
11445 (match_operand:SWI48 3 "register_operand")))
11446 (clobber (reg:CC FLAGS_REG))]
11447 "TARGET_USE_BT
11448 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11449 == GET_MODE_BITSIZE (<MODE>mode)-1
11450 && can_create_pseudo_p ()"
11451 "#"
11452 "&& 1"
11453 [(parallel
11454 [(set (match_dup 0)
11455 (and:SWI48
11456 (rotate:SWI48 (const_int -2)
11457 (match_dup 1))
11458 (match_dup 3)))
11459 (clobber (reg:CC FLAGS_REG))])]
11460 "operands[1] = gen_lowpart (QImode, operands[1]);")
11461
11462 (define_insn_and_split "*btr<mode>_mask_1"
11463 [(set (match_operand:SWI48 0 "register_operand")
11464 (and:SWI48
11465 (rotate:SWI48
11466 (const_int -2)
11467 (and:QI
11468 (match_operand:QI 1 "register_operand")
11469 (match_operand:QI 2 "const_int_operand")))
11470 (match_operand:SWI48 3 "register_operand")))
11471 (clobber (reg:CC FLAGS_REG))]
11472 "TARGET_USE_BT
11473 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11474 == GET_MODE_BITSIZE (<MODE>mode)-1
11475 && can_create_pseudo_p ()"
11476 "#"
11477 "&& 1"
11478 [(parallel
11479 [(set (match_dup 0)
11480 (and:SWI48
11481 (rotate:SWI48 (const_int -2)
11482 (match_dup 1))
11483 (match_dup 3)))
11484 (clobber (reg:CC FLAGS_REG))])])
11485
11486 ;; These instructions are never faster than the corresponding
11487 ;; and/ior/xor operations when using immediate operand, so with
11488 ;; 32-bit there's no point. But in 64-bit, we can't hold the
11489 ;; relevant immediates within the instruction itself, so operating
11490 ;; on bits in the high 32-bits of a register becomes easier.
11491 ;;
11492 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11493 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11494 ;; negdf respectively, so they can never be disabled entirely.
11495
11496 (define_insn "*btsq_imm"
11497 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11498 (const_int 1)
11499 (match_operand 1 "const_0_to_63_operand" "J"))
11500 (const_int 1))
11501 (clobber (reg:CC FLAGS_REG))]
11502 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11503 "bts{q}\t{%1, %0|%0, %1}"
11504 [(set_attr "type" "alu1")
11505 (set_attr "prefix_0f" "1")
11506 (set_attr "znver1_decode" "double")
11507 (set_attr "mode" "DI")])
11508
11509 (define_insn "*btrq_imm"
11510 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11511 (const_int 1)
11512 (match_operand 1 "const_0_to_63_operand" "J"))
11513 (const_int 0))
11514 (clobber (reg:CC FLAGS_REG))]
11515 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11516 "btr{q}\t{%1, %0|%0, %1}"
11517 [(set_attr "type" "alu1")
11518 (set_attr "prefix_0f" "1")
11519 (set_attr "znver1_decode" "double")
11520 (set_attr "mode" "DI")])
11521
11522 (define_insn "*btcq_imm"
11523 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11524 (const_int 1)
11525 (match_operand 1 "const_0_to_63_operand" "J"))
11526 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11527 (clobber (reg:CC FLAGS_REG))]
11528 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11529 "btc{q}\t{%1, %0|%0, %1}"
11530 [(set_attr "type" "alu1")
11531 (set_attr "prefix_0f" "1")
11532 (set_attr "znver1_decode" "double")
11533 (set_attr "mode" "DI")])
11534
11535 ;; Allow Nocona to avoid these instructions if a register is available.
11536
11537 (define_peephole2
11538 [(match_scratch:DI 2 "r")
11539 (parallel [(set (zero_extract:DI
11540 (match_operand:DI 0 "nonimmediate_operand")
11541 (const_int 1)
11542 (match_operand 1 "const_0_to_63_operand"))
11543 (const_int 1))
11544 (clobber (reg:CC FLAGS_REG))])]
11545 "TARGET_64BIT && !TARGET_USE_BT"
11546 [(parallel [(set (match_dup 0)
11547 (ior:DI (match_dup 0) (match_dup 3)))
11548 (clobber (reg:CC FLAGS_REG))])]
11549 {
11550 int i = INTVAL (operands[1]);
11551
11552 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11553
11554 if (!x86_64_immediate_operand (operands[3], DImode))
11555 {
11556 emit_move_insn (operands[2], operands[3]);
11557 operands[3] = operands[2];
11558 }
11559 })
11560
11561 (define_peephole2
11562 [(match_scratch:DI 2 "r")
11563 (parallel [(set (zero_extract:DI
11564 (match_operand:DI 0 "nonimmediate_operand")
11565 (const_int 1)
11566 (match_operand 1 "const_0_to_63_operand"))
11567 (const_int 0))
11568 (clobber (reg:CC FLAGS_REG))])]
11569 "TARGET_64BIT && !TARGET_USE_BT"
11570 [(parallel [(set (match_dup 0)
11571 (and:DI (match_dup 0) (match_dup 3)))
11572 (clobber (reg:CC FLAGS_REG))])]
11573 {
11574 int i = INTVAL (operands[1]);
11575
11576 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11577
11578 if (!x86_64_immediate_operand (operands[3], DImode))
11579 {
11580 emit_move_insn (operands[2], operands[3]);
11581 operands[3] = operands[2];
11582 }
11583 })
11584
11585 (define_peephole2
11586 [(match_scratch:DI 2 "r")
11587 (parallel [(set (zero_extract:DI
11588 (match_operand:DI 0 "nonimmediate_operand")
11589 (const_int 1)
11590 (match_operand 1 "const_0_to_63_operand"))
11591 (not:DI (zero_extract:DI
11592 (match_dup 0) (const_int 1) (match_dup 1))))
11593 (clobber (reg:CC FLAGS_REG))])]
11594 "TARGET_64BIT && !TARGET_USE_BT"
11595 [(parallel [(set (match_dup 0)
11596 (xor:DI (match_dup 0) (match_dup 3)))
11597 (clobber (reg:CC FLAGS_REG))])]
11598 {
11599 int i = INTVAL (operands[1]);
11600
11601 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11602
11603 if (!x86_64_immediate_operand (operands[3], DImode))
11604 {
11605 emit_move_insn (operands[2], operands[3]);
11606 operands[3] = operands[2];
11607 }
11608 })
11609
11610 ;; %%% bt
11611
11612 (define_insn "*bt<mode>"
11613 [(set (reg:CCC FLAGS_REG)
11614 (compare:CCC
11615 (zero_extract:SWI48
11616 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11617 (const_int 1)
11618 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11619 (const_int 0)))]
11620 ""
11621 {
11622 switch (get_attr_mode (insn))
11623 {
11624 case MODE_SI:
11625 return "bt{l}\t{%1, %k0|%k0, %1}";
11626
11627 case MODE_DI:
11628 return "bt{q}\t{%q1, %0|%0, %q1}";
11629
11630 default:
11631 gcc_unreachable ();
11632 }
11633 }
11634 [(set_attr "type" "alu1")
11635 (set_attr "prefix_0f" "1")
11636 (set (attr "mode")
11637 (if_then_else
11638 (and (match_test "CONST_INT_P (operands[1])")
11639 (match_test "INTVAL (operands[1]) < 32"))
11640 (const_string "SI")
11641 (const_string "<MODE>")))])
11642
11643 (define_insn_and_split "*jcc_bt<mode>"
11644 [(set (pc)
11645 (if_then_else (match_operator 0 "bt_comparison_operator"
11646 [(zero_extract:SWI48
11647 (match_operand:SWI48 1 "nonimmediate_operand")
11648 (const_int 1)
11649 (match_operand:SI 2 "nonmemory_operand"))
11650 (const_int 0)])
11651 (label_ref (match_operand 3))
11652 (pc)))
11653 (clobber (reg:CC FLAGS_REG))]
11654 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11655 && (CONST_INT_P (operands[2])
11656 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11657 && INTVAL (operands[2])
11658 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11659 : !memory_operand (operands[1], <MODE>mode))
11660 && can_create_pseudo_p ()"
11661 "#"
11662 "&& 1"
11663 [(set (reg:CCC FLAGS_REG)
11664 (compare:CCC
11665 (zero_extract:SWI48
11666 (match_dup 1)
11667 (const_int 1)
11668 (match_dup 2))
11669 (const_int 0)))
11670 (set (pc)
11671 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11672 (label_ref (match_dup 3))
11673 (pc)))]
11674 {
11675 operands[0] = shallow_copy_rtx (operands[0]);
11676 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11677 })
11678
11679 (define_insn_and_split "*jcc_bt<mode>_1"
11680 [(set (pc)
11681 (if_then_else (match_operator 0 "bt_comparison_operator"
11682 [(zero_extract:SWI48
11683 (match_operand:SWI48 1 "register_operand")
11684 (const_int 1)
11685 (zero_extend:SI
11686 (match_operand:QI 2 "register_operand")))
11687 (const_int 0)])
11688 (label_ref (match_operand 3))
11689 (pc)))
11690 (clobber (reg:CC FLAGS_REG))]
11691 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11692 && can_create_pseudo_p ()"
11693 "#"
11694 "&& 1"
11695 [(set (reg:CCC FLAGS_REG)
11696 (compare:CCC
11697 (zero_extract:SWI48
11698 (match_dup 1)
11699 (const_int 1)
11700 (match_dup 2))
11701 (const_int 0)))
11702 (set (pc)
11703 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11704 (label_ref (match_dup 3))
11705 (pc)))]
11706 {
11707 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11708 operands[0] = shallow_copy_rtx (operands[0]);
11709 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11710 })
11711
11712 ;; Avoid useless masking of bit offset operand.
11713 (define_insn_and_split "*jcc_bt<mode>_mask"
11714 [(set (pc)
11715 (if_then_else (match_operator 0 "bt_comparison_operator"
11716 [(zero_extract:SWI48
11717 (match_operand:SWI48 1 "register_operand")
11718 (const_int 1)
11719 (and:SI
11720 (match_operand:SI 2 "register_operand")
11721 (match_operand 3 "const_int_operand")))])
11722 (label_ref (match_operand 4))
11723 (pc)))
11724 (clobber (reg:CC FLAGS_REG))]
11725 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11726 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11727 == GET_MODE_BITSIZE (<MODE>mode)-1
11728 && can_create_pseudo_p ()"
11729 "#"
11730 "&& 1"
11731 [(set (reg:CCC FLAGS_REG)
11732 (compare:CCC
11733 (zero_extract:SWI48
11734 (match_dup 1)
11735 (const_int 1)
11736 (match_dup 2))
11737 (const_int 0)))
11738 (set (pc)
11739 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11740 (label_ref (match_dup 4))
11741 (pc)))]
11742 {
11743 operands[0] = shallow_copy_rtx (operands[0]);
11744 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11745 })
11746 \f
11747 ;; Store-flag instructions.
11748
11749 ;; For all sCOND expanders, also expand the compare or test insn that
11750 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11751
11752 (define_insn_and_split "*setcc_di_1"
11753 [(set (match_operand:DI 0 "register_operand" "=q")
11754 (match_operator:DI 1 "ix86_comparison_operator"
11755 [(reg FLAGS_REG) (const_int 0)]))]
11756 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11757 "#"
11758 "&& reload_completed"
11759 [(set (match_dup 2) (match_dup 1))
11760 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11761 {
11762 operands[1] = shallow_copy_rtx (operands[1]);
11763 PUT_MODE (operands[1], QImode);
11764 operands[2] = gen_lowpart (QImode, operands[0]);
11765 })
11766
11767 (define_insn_and_split "*setcc_si_1_and"
11768 [(set (match_operand:SI 0 "register_operand" "=q")
11769 (match_operator:SI 1 "ix86_comparison_operator"
11770 [(reg FLAGS_REG) (const_int 0)]))
11771 (clobber (reg:CC FLAGS_REG))]
11772 "!TARGET_PARTIAL_REG_STALL
11773 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11774 "#"
11775 "&& reload_completed"
11776 [(set (match_dup 2) (match_dup 1))
11777 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11778 (clobber (reg:CC FLAGS_REG))])]
11779 {
11780 operands[1] = shallow_copy_rtx (operands[1]);
11781 PUT_MODE (operands[1], QImode);
11782 operands[2] = gen_lowpart (QImode, operands[0]);
11783 })
11784
11785 (define_insn_and_split "*setcc_si_1_movzbl"
11786 [(set (match_operand:SI 0 "register_operand" "=q")
11787 (match_operator:SI 1 "ix86_comparison_operator"
11788 [(reg FLAGS_REG) (const_int 0)]))]
11789 "!TARGET_PARTIAL_REG_STALL
11790 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11791 "#"
11792 "&& reload_completed"
11793 [(set (match_dup 2) (match_dup 1))
11794 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11795 {
11796 operands[1] = shallow_copy_rtx (operands[1]);
11797 PUT_MODE (operands[1], QImode);
11798 operands[2] = gen_lowpart (QImode, operands[0]);
11799 })
11800
11801 (define_insn "*setcc_qi"
11802 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11803 (match_operator:QI 1 "ix86_comparison_operator"
11804 [(reg FLAGS_REG) (const_int 0)]))]
11805 ""
11806 "set%C1\t%0"
11807 [(set_attr "type" "setcc")
11808 (set_attr "mode" "QI")])
11809
11810 (define_insn "*setcc_qi_slp"
11811 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11812 (match_operator:QI 1 "ix86_comparison_operator"
11813 [(reg FLAGS_REG) (const_int 0)]))]
11814 ""
11815 "set%C1\t%0"
11816 [(set_attr "type" "setcc")
11817 (set_attr "mode" "QI")])
11818
11819 ;; In general it is not safe to assume too much about CCmode registers,
11820 ;; so simplify-rtx stops when it sees a second one. Under certain
11821 ;; conditions this is safe on x86, so help combine not create
11822 ;;
11823 ;; seta %al
11824 ;; testb %al, %al
11825 ;; sete %al
11826
11827 (define_split
11828 [(set (match_operand:QI 0 "nonimmediate_operand")
11829 (ne:QI (match_operator 1 "ix86_comparison_operator"
11830 [(reg FLAGS_REG) (const_int 0)])
11831 (const_int 0)))]
11832 ""
11833 [(set (match_dup 0) (match_dup 1))]
11834 {
11835 operands[1] = shallow_copy_rtx (operands[1]);
11836 PUT_MODE (operands[1], QImode);
11837 })
11838
11839 (define_split
11840 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11841 (ne:QI (match_operator 1 "ix86_comparison_operator"
11842 [(reg FLAGS_REG) (const_int 0)])
11843 (const_int 0)))]
11844 ""
11845 [(set (match_dup 0) (match_dup 1))]
11846 {
11847 operands[1] = shallow_copy_rtx (operands[1]);
11848 PUT_MODE (operands[1], QImode);
11849 })
11850
11851 (define_split
11852 [(set (match_operand:QI 0 "nonimmediate_operand")
11853 (eq:QI (match_operator 1 "ix86_comparison_operator"
11854 [(reg FLAGS_REG) (const_int 0)])
11855 (const_int 0)))]
11856 ""
11857 [(set (match_dup 0) (match_dup 1))]
11858 {
11859 operands[1] = shallow_copy_rtx (operands[1]);
11860 PUT_MODE (operands[1], QImode);
11861 PUT_CODE (operands[1],
11862 ix86_reverse_condition (GET_CODE (operands[1]),
11863 GET_MODE (XEXP (operands[1], 0))));
11864
11865 /* Make sure that (a) the CCmode we have for the flags is strong
11866 enough for the reversed compare or (b) we have a valid FP compare. */
11867 if (! ix86_comparison_operator (operands[1], VOIDmode))
11868 FAIL;
11869 })
11870
11871 (define_split
11872 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11873 (eq:QI (match_operator 1 "ix86_comparison_operator"
11874 [(reg FLAGS_REG) (const_int 0)])
11875 (const_int 0)))]
11876 ""
11877 [(set (match_dup 0) (match_dup 1))]
11878 {
11879 operands[1] = shallow_copy_rtx (operands[1]);
11880 PUT_MODE (operands[1], QImode);
11881 PUT_CODE (operands[1],
11882 ix86_reverse_condition (GET_CODE (operands[1]),
11883 GET_MODE (XEXP (operands[1], 0))));
11884
11885 /* Make sure that (a) the CCmode we have for the flags is strong
11886 enough for the reversed compare or (b) we have a valid FP compare. */
11887 if (! ix86_comparison_operator (operands[1], VOIDmode))
11888 FAIL;
11889 })
11890
11891 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11892 ;; subsequent logical operations are used to imitate conditional moves.
11893 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11894 ;; it directly.
11895
11896 (define_insn "setcc_<mode>_sse"
11897 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11898 (match_operator:MODEF 3 "sse_comparison_operator"
11899 [(match_operand:MODEF 1 "register_operand" "0,x")
11900 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11901 "SSE_FLOAT_MODE_P (<MODE>mode)"
11902 "@
11903 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11904 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11905 [(set_attr "isa" "noavx,avx")
11906 (set_attr "type" "ssecmp")
11907 (set_attr "length_immediate" "1")
11908 (set_attr "prefix" "orig,vex")
11909 (set_attr "mode" "<MODE>")])
11910 \f
11911 ;; Basic conditional jump instructions.
11912 ;; We ignore the overflow flag for signed branch instructions.
11913
11914 (define_insn "*jcc"
11915 [(set (pc)
11916 (if_then_else (match_operator 1 "ix86_comparison_operator"
11917 [(reg FLAGS_REG) (const_int 0)])
11918 (label_ref (match_operand 0))
11919 (pc)))]
11920 ""
11921 "%!%+j%C1\t%l0"
11922 [(set_attr "type" "ibr")
11923 (set_attr "modrm" "0")
11924 (set (attr "length")
11925 (if_then_else
11926 (and (ge (minus (match_dup 0) (pc))
11927 (const_int -126))
11928 (lt (minus (match_dup 0) (pc))
11929 (const_int 128)))
11930 (const_int 2)
11931 (const_int 6)))])
11932
11933 ;; In general it is not safe to assume too much about CCmode registers,
11934 ;; so simplify-rtx stops when it sees a second one. Under certain
11935 ;; conditions this is safe on x86, so help combine not create
11936 ;;
11937 ;; seta %al
11938 ;; testb %al, %al
11939 ;; je Lfoo
11940
11941 (define_split
11942 [(set (pc)
11943 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11944 [(reg FLAGS_REG) (const_int 0)])
11945 (const_int 0))
11946 (label_ref (match_operand 1))
11947 (pc)))]
11948 ""
11949 [(set (pc)
11950 (if_then_else (match_dup 0)
11951 (label_ref (match_dup 1))
11952 (pc)))]
11953 {
11954 operands[0] = shallow_copy_rtx (operands[0]);
11955 PUT_MODE (operands[0], VOIDmode);
11956 })
11957
11958 (define_split
11959 [(set (pc)
11960 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11961 [(reg FLAGS_REG) (const_int 0)])
11962 (const_int 0))
11963 (label_ref (match_operand 1))
11964 (pc)))]
11965 ""
11966 [(set (pc)
11967 (if_then_else (match_dup 0)
11968 (label_ref (match_dup 1))
11969 (pc)))]
11970 {
11971 operands[0] = shallow_copy_rtx (operands[0]);
11972 PUT_MODE (operands[0], VOIDmode);
11973 PUT_CODE (operands[0],
11974 ix86_reverse_condition (GET_CODE (operands[0]),
11975 GET_MODE (XEXP (operands[0], 0))));
11976
11977 /* Make sure that (a) the CCmode we have for the flags is strong
11978 enough for the reversed compare or (b) we have a valid FP compare. */
11979 if (! ix86_comparison_operator (operands[0], VOIDmode))
11980 FAIL;
11981 })
11982 \f
11983 ;; Unconditional and other jump instructions
11984
11985 (define_insn "jump"
11986 [(set (pc)
11987 (label_ref (match_operand 0)))]
11988 ""
11989 "%!jmp\t%l0"
11990 [(set_attr "type" "ibr")
11991 (set_attr "modrm" "0")
11992 (set (attr "length")
11993 (if_then_else
11994 (and (ge (minus (match_dup 0) (pc))
11995 (const_int -126))
11996 (lt (minus (match_dup 0) (pc))
11997 (const_int 128)))
11998 (const_int 2)
11999 (const_int 5)))])
12000
12001 (define_expand "indirect_jump"
12002 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12003 ""
12004 {
12005 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12006 operands[0] = convert_memory_address (word_mode, operands[0]);
12007 cfun->machine->has_local_indirect_jump = true;
12008 })
12009
12010 (define_insn "*indirect_jump"
12011 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12012 ""
12013 "* return ix86_output_indirect_jmp (operands[0]);"
12014 [(set (attr "type")
12015 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12016 != indirect_branch_keep)")
12017 (const_string "multi")
12018 (const_string "ibr")))
12019 (set_attr "length_immediate" "0")])
12020
12021 (define_expand "tablejump"
12022 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12023 (use (label_ref (match_operand 1)))])]
12024 ""
12025 {
12026 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12027 relative. Convert the relative address to an absolute address. */
12028 if (flag_pic)
12029 {
12030 rtx op0, op1;
12031 enum rtx_code code;
12032
12033 /* We can't use @GOTOFF for text labels on VxWorks;
12034 see gotoff_operand. */
12035 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12036 {
12037 code = PLUS;
12038 op0 = operands[0];
12039 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12040 }
12041 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12042 {
12043 code = PLUS;
12044 op0 = operands[0];
12045 op1 = pic_offset_table_rtx;
12046 }
12047 else
12048 {
12049 code = MINUS;
12050 op0 = pic_offset_table_rtx;
12051 op1 = operands[0];
12052 }
12053
12054 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12055 OPTAB_DIRECT);
12056 }
12057
12058 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12059 operands[0] = convert_memory_address (word_mode, operands[0]);
12060 cfun->machine->has_local_indirect_jump = true;
12061 })
12062
12063 (define_insn "*tablejump_1"
12064 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12065 (use (label_ref (match_operand 1)))]
12066 ""
12067 "* return ix86_output_indirect_jmp (operands[0]);"
12068 [(set (attr "type")
12069 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12070 != indirect_branch_keep)")
12071 (const_string "multi")
12072 (const_string "ibr")))
12073 (set_attr "length_immediate" "0")])
12074 \f
12075 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12076
12077 (define_peephole2
12078 [(set (reg FLAGS_REG) (match_operand 0))
12079 (set (match_operand:QI 1 "register_operand")
12080 (match_operator:QI 2 "ix86_comparison_operator"
12081 [(reg FLAGS_REG) (const_int 0)]))
12082 (set (match_operand 3 "any_QIreg_operand")
12083 (zero_extend (match_dup 1)))]
12084 "(peep2_reg_dead_p (3, operands[1])
12085 || operands_match_p (operands[1], operands[3]))
12086 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12087 && peep2_regno_dead_p (0, FLAGS_REG)"
12088 [(set (match_dup 4) (match_dup 0))
12089 (set (strict_low_part (match_dup 5))
12090 (match_dup 2))]
12091 {
12092 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12093 operands[5] = gen_lowpart (QImode, operands[3]);
12094 ix86_expand_clear (operands[3]);
12095 })
12096
12097 (define_peephole2
12098 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12099 (match_operand 4)])
12100 (set (match_operand:QI 1 "register_operand")
12101 (match_operator:QI 2 "ix86_comparison_operator"
12102 [(reg FLAGS_REG) (const_int 0)]))
12103 (set (match_operand 3 "any_QIreg_operand")
12104 (zero_extend (match_dup 1)))]
12105 "(peep2_reg_dead_p (3, operands[1])
12106 || operands_match_p (operands[1], operands[3]))
12107 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12108 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12109 && ! reg_set_p (operands[3], operands[4])
12110 && peep2_regno_dead_p (0, FLAGS_REG)"
12111 [(parallel [(set (match_dup 5) (match_dup 0))
12112 (match_dup 4)])
12113 (set (strict_low_part (match_dup 6))
12114 (match_dup 2))]
12115 {
12116 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12117 operands[6] = gen_lowpart (QImode, operands[3]);
12118 ix86_expand_clear (operands[3]);
12119 })
12120
12121 (define_peephole2
12122 [(set (reg FLAGS_REG) (match_operand 0))
12123 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12124 (match_operand 5)])
12125 (set (match_operand:QI 2 "register_operand")
12126 (match_operator:QI 3 "ix86_comparison_operator"
12127 [(reg FLAGS_REG) (const_int 0)]))
12128 (set (match_operand 4 "any_QIreg_operand")
12129 (zero_extend (match_dup 2)))]
12130 "(peep2_reg_dead_p (4, operands[2])
12131 || operands_match_p (operands[2], operands[4]))
12132 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12133 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12134 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12135 && ! reg_set_p (operands[4], operands[5])
12136 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12137 && peep2_regno_dead_p (0, FLAGS_REG)"
12138 [(set (match_dup 6) (match_dup 0))
12139 (parallel [(set (match_dup 7) (match_dup 1))
12140 (match_dup 5)])
12141 (set (strict_low_part (match_dup 8))
12142 (match_dup 3))]
12143 {
12144 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12145 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12146 operands[8] = gen_lowpart (QImode, operands[4]);
12147 ix86_expand_clear (operands[4]);
12148 })
12149
12150 ;; Similar, but match zero extend with andsi3.
12151
12152 (define_peephole2
12153 [(set (reg FLAGS_REG) (match_operand 0))
12154 (set (match_operand:QI 1 "register_operand")
12155 (match_operator:QI 2 "ix86_comparison_operator"
12156 [(reg FLAGS_REG) (const_int 0)]))
12157 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12158 (and:SI (match_dup 3) (const_int 255)))
12159 (clobber (reg:CC FLAGS_REG))])]
12160 "REGNO (operands[1]) == REGNO (operands[3])
12161 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12162 && peep2_regno_dead_p (0, FLAGS_REG)"
12163 [(set (match_dup 4) (match_dup 0))
12164 (set (strict_low_part (match_dup 5))
12165 (match_dup 2))]
12166 {
12167 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12168 operands[5] = gen_lowpart (QImode, operands[3]);
12169 ix86_expand_clear (operands[3]);
12170 })
12171
12172 (define_peephole2
12173 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12174 (match_operand 4)])
12175 (set (match_operand:QI 1 "register_operand")
12176 (match_operator:QI 2 "ix86_comparison_operator"
12177 [(reg FLAGS_REG) (const_int 0)]))
12178 (parallel [(set (match_operand 3 "any_QIreg_operand")
12179 (zero_extend (match_dup 1)))
12180 (clobber (reg:CC FLAGS_REG))])]
12181 "(peep2_reg_dead_p (3, operands[1])
12182 || operands_match_p (operands[1], operands[3]))
12183 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12184 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12185 && ! reg_set_p (operands[3], operands[4])
12186 && peep2_regno_dead_p (0, FLAGS_REG)"
12187 [(parallel [(set (match_dup 5) (match_dup 0))
12188 (match_dup 4)])
12189 (set (strict_low_part (match_dup 6))
12190 (match_dup 2))]
12191 {
12192 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12193 operands[6] = gen_lowpart (QImode, operands[3]);
12194 ix86_expand_clear (operands[3]);
12195 })
12196
12197 (define_peephole2
12198 [(set (reg FLAGS_REG) (match_operand 0))
12199 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12200 (match_operand 5)])
12201 (set (match_operand:QI 2 "register_operand")
12202 (match_operator:QI 3 "ix86_comparison_operator"
12203 [(reg FLAGS_REG) (const_int 0)]))
12204 (parallel [(set (match_operand 4 "any_QIreg_operand")
12205 (zero_extend (match_dup 2)))
12206 (clobber (reg:CC FLAGS_REG))])]
12207 "(peep2_reg_dead_p (4, operands[2])
12208 || operands_match_p (operands[2], operands[4]))
12209 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12210 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12211 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12212 && ! reg_set_p (operands[4], operands[5])
12213 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12214 && peep2_regno_dead_p (0, FLAGS_REG)"
12215 [(set (match_dup 6) (match_dup 0))
12216 (parallel [(set (match_dup 7) (match_dup 1))
12217 (match_dup 5)])
12218 (set (strict_low_part (match_dup 8))
12219 (match_dup 3))]
12220 {
12221 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12222 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12223 operands[8] = gen_lowpart (QImode, operands[4]);
12224 ix86_expand_clear (operands[4]);
12225 })
12226 \f
12227 ;; Call instructions.
12228
12229 ;; The predicates normally associated with named expanders are not properly
12230 ;; checked for calls. This is a bug in the generic code, but it isn't that
12231 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12232
12233 ;; P6 processors will jump to the address after the decrement when %esp
12234 ;; is used as a call operand, so they will execute return address as a code.
12235 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12236
12237 ;; Register constraint for call instruction.
12238 (define_mode_attr c [(SI "l") (DI "r")])
12239
12240 ;; Call subroutine returning no value.
12241
12242 (define_expand "call"
12243 [(call (match_operand:QI 0)
12244 (match_operand 1))
12245 (use (match_operand 2))]
12246 ""
12247 {
12248 ix86_expand_call (NULL, operands[0], operands[1],
12249 operands[2], NULL, false);
12250 DONE;
12251 })
12252
12253 (define_expand "sibcall"
12254 [(call (match_operand:QI 0)
12255 (match_operand 1))
12256 (use (match_operand 2))]
12257 ""
12258 {
12259 ix86_expand_call (NULL, operands[0], operands[1],
12260 operands[2], NULL, true);
12261 DONE;
12262 })
12263
12264 (define_insn "*call"
12265 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12266 (match_operand 1))]
12267 "!SIBLING_CALL_P (insn)"
12268 "* return ix86_output_call_insn (insn, operands[0]);"
12269 [(set_attr "type" "call")])
12270
12271 ;; This covers both call and sibcall since only GOT slot is allowed.
12272 (define_insn "*call_got_x32"
12273 [(call (mem:QI (zero_extend:DI
12274 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12275 (match_operand 1))]
12276 "TARGET_X32"
12277 {
12278 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12279 return ix86_output_call_insn (insn, fnaddr);
12280 }
12281 [(set_attr "type" "call")])
12282
12283 ;; Since sibcall never returns, we can only use call-clobbered register
12284 ;; as GOT base.
12285 (define_insn "*sibcall_GOT_32"
12286 [(call (mem:QI
12287 (mem:SI (plus:SI
12288 (match_operand:SI 0 "register_no_elim_operand" "U")
12289 (match_operand:SI 1 "GOT32_symbol_operand"))))
12290 (match_operand 2))]
12291 "!TARGET_MACHO
12292 && !TARGET_64BIT
12293 && !TARGET_INDIRECT_BRANCH_REGISTER
12294 && SIBLING_CALL_P (insn)"
12295 {
12296 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12297 fnaddr = gen_const_mem (SImode, fnaddr);
12298 return ix86_output_call_insn (insn, fnaddr);
12299 }
12300 [(set_attr "type" "call")])
12301
12302 (define_insn "*sibcall"
12303 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12304 (match_operand 1))]
12305 "SIBLING_CALL_P (insn)"
12306 "* return ix86_output_call_insn (insn, operands[0]);"
12307 [(set_attr "type" "call")])
12308
12309 (define_insn "*sibcall_memory"
12310 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12311 (match_operand 1))
12312 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12313 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12314 "* return ix86_output_call_insn (insn, operands[0]);"
12315 [(set_attr "type" "call")])
12316
12317 (define_peephole2
12318 [(set (match_operand:W 0 "register_operand")
12319 (match_operand:W 1 "memory_operand"))
12320 (call (mem:QI (match_dup 0))
12321 (match_operand 3))]
12322 "!TARGET_X32
12323 && !TARGET_INDIRECT_BRANCH_REGISTER
12324 && SIBLING_CALL_P (peep2_next_insn (1))
12325 && !reg_mentioned_p (operands[0],
12326 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12327 [(parallel [(call (mem:QI (match_dup 1))
12328 (match_dup 3))
12329 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12330
12331 (define_peephole2
12332 [(set (match_operand:W 0 "register_operand")
12333 (match_operand:W 1 "memory_operand"))
12334 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12335 (call (mem:QI (match_dup 0))
12336 (match_operand 3))]
12337 "!TARGET_X32
12338 && !TARGET_INDIRECT_BRANCH_REGISTER
12339 && SIBLING_CALL_P (peep2_next_insn (2))
12340 && !reg_mentioned_p (operands[0],
12341 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12342 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12343 (parallel [(call (mem:QI (match_dup 1))
12344 (match_dup 3))
12345 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12346
12347 (define_expand "call_pop"
12348 [(parallel [(call (match_operand:QI 0)
12349 (match_operand:SI 1))
12350 (set (reg:SI SP_REG)
12351 (plus:SI (reg:SI SP_REG)
12352 (match_operand:SI 3)))])]
12353 "!TARGET_64BIT"
12354 {
12355 ix86_expand_call (NULL, operands[0], operands[1],
12356 operands[2], operands[3], false);
12357 DONE;
12358 })
12359
12360 (define_insn "*call_pop"
12361 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12362 (match_operand 1))
12363 (set (reg:SI SP_REG)
12364 (plus:SI (reg:SI SP_REG)
12365 (match_operand:SI 2 "immediate_operand" "i")))]
12366 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12367 "* return ix86_output_call_insn (insn, operands[0]);"
12368 [(set_attr "type" "call")])
12369
12370 (define_insn "*sibcall_pop"
12371 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12372 (match_operand 1))
12373 (set (reg:SI SP_REG)
12374 (plus:SI (reg:SI SP_REG)
12375 (match_operand:SI 2 "immediate_operand" "i")))]
12376 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12377 "* return ix86_output_call_insn (insn, operands[0]);"
12378 [(set_attr "type" "call")])
12379
12380 (define_insn "*sibcall_pop_memory"
12381 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12382 (match_operand 1))
12383 (set (reg:SI SP_REG)
12384 (plus:SI (reg:SI SP_REG)
12385 (match_operand:SI 2 "immediate_operand" "i")))
12386 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12387 "!TARGET_64BIT"
12388 "* return ix86_output_call_insn (insn, operands[0]);"
12389 [(set_attr "type" "call")])
12390
12391 (define_peephole2
12392 [(set (match_operand:SI 0 "register_operand")
12393 (match_operand:SI 1 "memory_operand"))
12394 (parallel [(call (mem:QI (match_dup 0))
12395 (match_operand 3))
12396 (set (reg:SI SP_REG)
12397 (plus:SI (reg:SI SP_REG)
12398 (match_operand:SI 4 "immediate_operand")))])]
12399 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12400 && !reg_mentioned_p (operands[0],
12401 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12402 [(parallel [(call (mem:QI (match_dup 1))
12403 (match_dup 3))
12404 (set (reg:SI SP_REG)
12405 (plus:SI (reg:SI SP_REG)
12406 (match_dup 4)))
12407 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12408
12409 (define_peephole2
12410 [(set (match_operand:SI 0 "register_operand")
12411 (match_operand:SI 1 "memory_operand"))
12412 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12413 (parallel [(call (mem:QI (match_dup 0))
12414 (match_operand 3))
12415 (set (reg:SI SP_REG)
12416 (plus:SI (reg:SI SP_REG)
12417 (match_operand:SI 4 "immediate_operand")))])]
12418 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12419 && !reg_mentioned_p (operands[0],
12420 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12421 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12422 (parallel [(call (mem:QI (match_dup 1))
12423 (match_dup 3))
12424 (set (reg:SI SP_REG)
12425 (plus:SI (reg:SI SP_REG)
12426 (match_dup 4)))
12427 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12428
12429 ;; Combining simple memory jump instruction
12430
12431 (define_peephole2
12432 [(set (match_operand:W 0 "register_operand")
12433 (match_operand:W 1 "memory_operand"))
12434 (set (pc) (match_dup 0))]
12435 "!TARGET_X32
12436 && !TARGET_INDIRECT_BRANCH_REGISTER
12437 && peep2_reg_dead_p (2, operands[0])"
12438 [(set (pc) (match_dup 1))])
12439
12440 ;; Call subroutine, returning value in operand 0
12441
12442 (define_expand "call_value"
12443 [(set (match_operand 0)
12444 (call (match_operand:QI 1)
12445 (match_operand 2)))
12446 (use (match_operand 3))]
12447 ""
12448 {
12449 ix86_expand_call (operands[0], operands[1], operands[2],
12450 operands[3], NULL, false);
12451 DONE;
12452 })
12453
12454 (define_expand "sibcall_value"
12455 [(set (match_operand 0)
12456 (call (match_operand:QI 1)
12457 (match_operand 2)))
12458 (use (match_operand 3))]
12459 ""
12460 {
12461 ix86_expand_call (operands[0], operands[1], operands[2],
12462 operands[3], NULL, true);
12463 DONE;
12464 })
12465
12466 (define_insn "*call_value"
12467 [(set (match_operand 0)
12468 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12469 (match_operand 2)))]
12470 "!SIBLING_CALL_P (insn)"
12471 "* return ix86_output_call_insn (insn, operands[1]);"
12472 [(set_attr "type" "callv")])
12473
12474 ;; This covers both call and sibcall since only GOT slot is allowed.
12475 (define_insn "*call_value_got_x32"
12476 [(set (match_operand 0)
12477 (call (mem:QI
12478 (zero_extend:DI
12479 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12480 (match_operand 2)))]
12481 "TARGET_X32"
12482 {
12483 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12484 return ix86_output_call_insn (insn, fnaddr);
12485 }
12486 [(set_attr "type" "callv")])
12487
12488 ;; Since sibcall never returns, we can only use call-clobbered register
12489 ;; as GOT base.
12490 (define_insn "*sibcall_value_GOT_32"
12491 [(set (match_operand 0)
12492 (call (mem:QI
12493 (mem:SI (plus:SI
12494 (match_operand:SI 1 "register_no_elim_operand" "U")
12495 (match_operand:SI 2 "GOT32_symbol_operand"))))
12496 (match_operand 3)))]
12497 "!TARGET_MACHO
12498 && !TARGET_64BIT
12499 && !TARGET_INDIRECT_BRANCH_REGISTER
12500 && SIBLING_CALL_P (insn)"
12501 {
12502 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12503 fnaddr = gen_const_mem (SImode, fnaddr);
12504 return ix86_output_call_insn (insn, fnaddr);
12505 }
12506 [(set_attr "type" "callv")])
12507
12508 (define_insn "*sibcall_value"
12509 [(set (match_operand 0)
12510 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12511 (match_operand 2)))]
12512 "SIBLING_CALL_P (insn)"
12513 "* return ix86_output_call_insn (insn, operands[1]);"
12514 [(set_attr "type" "callv")])
12515
12516 (define_insn "*sibcall_value_memory"
12517 [(set (match_operand 0)
12518 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12519 (match_operand 2)))
12520 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12521 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12522 "* return ix86_output_call_insn (insn, operands[1]);"
12523 [(set_attr "type" "callv")])
12524
12525 (define_peephole2
12526 [(set (match_operand:W 0 "register_operand")
12527 (match_operand:W 1 "memory_operand"))
12528 (set (match_operand 2)
12529 (call (mem:QI (match_dup 0))
12530 (match_operand 3)))]
12531 "!TARGET_X32
12532 && !TARGET_INDIRECT_BRANCH_REGISTER
12533 && SIBLING_CALL_P (peep2_next_insn (1))
12534 && !reg_mentioned_p (operands[0],
12535 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12536 [(parallel [(set (match_dup 2)
12537 (call (mem:QI (match_dup 1))
12538 (match_dup 3)))
12539 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12540
12541 (define_peephole2
12542 [(set (match_operand:W 0 "register_operand")
12543 (match_operand:W 1 "memory_operand"))
12544 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12545 (set (match_operand 2)
12546 (call (mem:QI (match_dup 0))
12547 (match_operand 3)))]
12548 "!TARGET_X32
12549 && !TARGET_INDIRECT_BRANCH_REGISTER
12550 && SIBLING_CALL_P (peep2_next_insn (2))
12551 && !reg_mentioned_p (operands[0],
12552 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12553 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12554 (parallel [(set (match_dup 2)
12555 (call (mem:QI (match_dup 1))
12556 (match_dup 3)))
12557 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12558
12559 (define_expand "call_value_pop"
12560 [(parallel [(set (match_operand 0)
12561 (call (match_operand:QI 1)
12562 (match_operand:SI 2)))
12563 (set (reg:SI SP_REG)
12564 (plus:SI (reg:SI SP_REG)
12565 (match_operand:SI 4)))])]
12566 "!TARGET_64BIT"
12567 {
12568 ix86_expand_call (operands[0], operands[1], operands[2],
12569 operands[3], operands[4], false);
12570 DONE;
12571 })
12572
12573 (define_insn "*call_value_pop"
12574 [(set (match_operand 0)
12575 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12576 (match_operand 2)))
12577 (set (reg:SI SP_REG)
12578 (plus:SI (reg:SI SP_REG)
12579 (match_operand:SI 3 "immediate_operand" "i")))]
12580 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12581 "* return ix86_output_call_insn (insn, operands[1]);"
12582 [(set_attr "type" "callv")])
12583
12584 (define_insn "*sibcall_value_pop"
12585 [(set (match_operand 0)
12586 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12587 (match_operand 2)))
12588 (set (reg:SI SP_REG)
12589 (plus:SI (reg:SI SP_REG)
12590 (match_operand:SI 3 "immediate_operand" "i")))]
12591 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12592 "* return ix86_output_call_insn (insn, operands[1]);"
12593 [(set_attr "type" "callv")])
12594
12595 (define_insn "*sibcall_value_pop_memory"
12596 [(set (match_operand 0)
12597 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12598 (match_operand 2)))
12599 (set (reg:SI SP_REG)
12600 (plus:SI (reg:SI SP_REG)
12601 (match_operand:SI 3 "immediate_operand" "i")))
12602 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12603 "!TARGET_64BIT"
12604 "* return ix86_output_call_insn (insn, operands[1]);"
12605 [(set_attr "type" "callv")])
12606
12607 (define_peephole2
12608 [(set (match_operand:SI 0 "register_operand")
12609 (match_operand:SI 1 "memory_operand"))
12610 (parallel [(set (match_operand 2)
12611 (call (mem:QI (match_dup 0))
12612 (match_operand 3)))
12613 (set (reg:SI SP_REG)
12614 (plus:SI (reg:SI SP_REG)
12615 (match_operand:SI 4 "immediate_operand")))])]
12616 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12617 && !reg_mentioned_p (operands[0],
12618 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12619 [(parallel [(set (match_dup 2)
12620 (call (mem:QI (match_dup 1))
12621 (match_dup 3)))
12622 (set (reg:SI SP_REG)
12623 (plus:SI (reg:SI SP_REG)
12624 (match_dup 4)))
12625 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12626
12627 (define_peephole2
12628 [(set (match_operand:SI 0 "register_operand")
12629 (match_operand:SI 1 "memory_operand"))
12630 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12631 (parallel [(set (match_operand 2)
12632 (call (mem:QI (match_dup 0))
12633 (match_operand 3)))
12634 (set (reg:SI SP_REG)
12635 (plus:SI (reg:SI SP_REG)
12636 (match_operand:SI 4 "immediate_operand")))])]
12637 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12638 && !reg_mentioned_p (operands[0],
12639 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12640 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12641 (parallel [(set (match_dup 2)
12642 (call (mem:QI (match_dup 1))
12643 (match_dup 3)))
12644 (set (reg:SI SP_REG)
12645 (plus:SI (reg:SI SP_REG)
12646 (match_dup 4)))
12647 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12648
12649 ;; Call subroutine returning any type.
12650
12651 (define_expand "untyped_call"
12652 [(parallel [(call (match_operand 0)
12653 (const_int 0))
12654 (match_operand 1)
12655 (match_operand 2)])]
12656 ""
12657 {
12658 int i;
12659
12660 /* In order to give reg-stack an easier job in validating two
12661 coprocessor registers as containing a possible return value,
12662 simply pretend the untyped call returns a complex long double
12663 value.
12664
12665 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12666 and should have the default ABI. */
12667
12668 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12669 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12670 operands[0], const0_rtx,
12671 GEN_INT ((TARGET_64BIT
12672 ? (ix86_abi == SYSV_ABI
12673 ? X86_64_SSE_REGPARM_MAX
12674 : X86_64_MS_SSE_REGPARM_MAX)
12675 : X86_32_SSE_REGPARM_MAX)
12676 - 1),
12677 NULL, false);
12678
12679 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12680 {
12681 rtx set = XVECEXP (operands[2], 0, i);
12682 emit_move_insn (SET_DEST (set), SET_SRC (set));
12683 }
12684
12685 /* The optimizer does not know that the call sets the function value
12686 registers we stored in the result block. We avoid problems by
12687 claiming that all hard registers are used and clobbered at this
12688 point. */
12689 emit_insn (gen_blockage ());
12690
12691 DONE;
12692 })
12693 \f
12694 ;; Prologue and epilogue instructions
12695
12696 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12697 ;; all of memory. This blocks insns from being moved across this point.
12698
12699 (define_insn "blockage"
12700 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12701 ""
12702 ""
12703 [(set_attr "length" "0")])
12704
12705 ;; Do not schedule instructions accessing memory across this point.
12706
12707 (define_expand "memory_blockage"
12708 [(set (match_dup 0)
12709 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12710 ""
12711 {
12712 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12713 MEM_VOLATILE_P (operands[0]) = 1;
12714 })
12715
12716 (define_insn "*memory_blockage"
12717 [(set (match_operand:BLK 0)
12718 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12719 ""
12720 ""
12721 [(set_attr "length" "0")])
12722
12723 ;; As USE insns aren't meaningful after reload, this is used instead
12724 ;; to prevent deleting instructions setting registers for PIC code
12725 (define_insn "prologue_use"
12726 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12727 ""
12728 ""
12729 [(set_attr "length" "0")])
12730
12731 ;; Insn emitted into the body of a function to return from a function.
12732 ;; This is only done if the function's epilogue is known to be simple.
12733 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12734
12735 (define_expand "return"
12736 [(simple_return)]
12737 "ix86_can_use_return_insn_p ()"
12738 {
12739 if (crtl->args.pops_args)
12740 {
12741 rtx popc = GEN_INT (crtl->args.pops_args);
12742 emit_jump_insn (gen_simple_return_pop_internal (popc));
12743 DONE;
12744 }
12745 })
12746
12747 ;; We need to disable this for TARGET_SEH, as otherwise
12748 ;; shrink-wrapped prologue gets enabled too. This might exceed
12749 ;; the maximum size of prologue in unwind information.
12750 ;; Also disallow shrink-wrapping if using stack slot to pass the
12751 ;; static chain pointer - the first instruction has to be pushl %esi
12752 ;; and it can't be moved around, as we use alternate entry points
12753 ;; in that case.
12754
12755 (define_expand "simple_return"
12756 [(simple_return)]
12757 "!TARGET_SEH && !ix86_static_chain_on_stack"
12758 {
12759 if (crtl->args.pops_args)
12760 {
12761 rtx popc = GEN_INT (crtl->args.pops_args);
12762 emit_jump_insn (gen_simple_return_pop_internal (popc));
12763 DONE;
12764 }
12765 })
12766
12767 (define_insn "simple_return_internal"
12768 [(simple_return)]
12769 "reload_completed"
12770 "* return ix86_output_function_return (false);"
12771 [(set_attr "length" "1")
12772 (set_attr "atom_unit" "jeu")
12773 (set_attr "length_immediate" "0")
12774 (set_attr "modrm" "0")])
12775
12776 (define_insn "interrupt_return"
12777 [(simple_return)
12778 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12779 "reload_completed"
12780 {
12781 return TARGET_64BIT ? "iretq" : "iret";
12782 })
12783
12784 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12785 ;; instruction Athlon and K8 have.
12786
12787 (define_insn "simple_return_internal_long"
12788 [(simple_return)
12789 (unspec [(const_int 0)] UNSPEC_REP)]
12790 "reload_completed"
12791 "* return ix86_output_function_return (true);"
12792 [(set_attr "length" "2")
12793 (set_attr "atom_unit" "jeu")
12794 (set_attr "length_immediate" "0")
12795 (set_attr "prefix_rep" "1")
12796 (set_attr "modrm" "0")])
12797
12798 (define_insn_and_split "simple_return_pop_internal"
12799 [(simple_return)
12800 (use (match_operand:SI 0 "const_int_operand"))]
12801 "reload_completed"
12802 "%!ret\t%0"
12803 "&& cfun->machine->function_return_type != indirect_branch_keep"
12804 [(const_int 0)]
12805 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
12806 [(set_attr "length" "3")
12807 (set_attr "atom_unit" "jeu")
12808 (set_attr "length_immediate" "2")
12809 (set_attr "modrm" "0")])
12810
12811 (define_expand "simple_return_indirect_internal"
12812 [(parallel
12813 [(simple_return)
12814 (use (match_operand 0 "register_operand"))])])
12815
12816 (define_insn "*simple_return_indirect_internal<mode>"
12817 [(simple_return)
12818 (use (match_operand:W 0 "register_operand" "r"))]
12819 "reload_completed"
12820 "* return ix86_output_indirect_function_return (operands[0]);"
12821 [(set (attr "type")
12822 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12823 != indirect_branch_keep)")
12824 (const_string "multi")
12825 (const_string "ibr")))
12826 (set_attr "length_immediate" "0")])
12827
12828 (define_insn "nop"
12829 [(const_int 0)]
12830 ""
12831 "nop"
12832 [(set_attr "length" "1")
12833 (set_attr "length_immediate" "0")
12834 (set_attr "modrm" "0")])
12835
12836 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12837 (define_insn "nops"
12838 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12839 UNSPECV_NOPS)]
12840 "reload_completed"
12841 {
12842 int num = INTVAL (operands[0]);
12843
12844 gcc_assert (IN_RANGE (num, 1, 8));
12845
12846 while (num--)
12847 fputs ("\tnop\n", asm_out_file);
12848
12849 return "";
12850 }
12851 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12852 (set_attr "length_immediate" "0")
12853 (set_attr "modrm" "0")])
12854
12855 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12856 ;; branch prediction penalty for the third jump in a 16-byte
12857 ;; block on K8.
12858
12859 (define_insn "pad"
12860 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12861 ""
12862 {
12863 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12864 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12865 #else
12866 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12867 The align insn is used to avoid 3 jump instructions in the row to improve
12868 branch prediction and the benefits hardly outweigh the cost of extra 8
12869 nops on the average inserted by full alignment pseudo operation. */
12870 #endif
12871 return "";
12872 }
12873 [(set_attr "length" "16")])
12874
12875 (define_expand "prologue"
12876 [(const_int 0)]
12877 ""
12878 "ix86_expand_prologue (); DONE;")
12879
12880 (define_expand "set_got"
12881 [(parallel
12882 [(set (match_operand:SI 0 "register_operand")
12883 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12884 (clobber (reg:CC FLAGS_REG))])]
12885 "!TARGET_64BIT"
12886 {
12887 if (flag_pic && !TARGET_VXWORKS_RTP)
12888 ix86_pc_thunk_call_expanded = true;
12889 })
12890
12891 (define_insn "*set_got"
12892 [(set (match_operand:SI 0 "register_operand" "=r")
12893 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12894 (clobber (reg:CC FLAGS_REG))]
12895 "!TARGET_64BIT"
12896 "* return output_set_got (operands[0], NULL_RTX);"
12897 [(set_attr "type" "multi")
12898 (set_attr "length" "12")])
12899
12900 (define_expand "set_got_labelled"
12901 [(parallel
12902 [(set (match_operand:SI 0 "register_operand")
12903 (unspec:SI [(label_ref (match_operand 1))]
12904 UNSPEC_SET_GOT))
12905 (clobber (reg:CC FLAGS_REG))])]
12906 "!TARGET_64BIT"
12907 {
12908 if (flag_pic && !TARGET_VXWORKS_RTP)
12909 ix86_pc_thunk_call_expanded = true;
12910 })
12911
12912 (define_insn "*set_got_labelled"
12913 [(set (match_operand:SI 0 "register_operand" "=r")
12914 (unspec:SI [(label_ref (match_operand 1))]
12915 UNSPEC_SET_GOT))
12916 (clobber (reg:CC FLAGS_REG))]
12917 "!TARGET_64BIT"
12918 "* return output_set_got (operands[0], operands[1]);"
12919 [(set_attr "type" "multi")
12920 (set_attr "length" "12")])
12921
12922 (define_insn "set_got_rex64"
12923 [(set (match_operand:DI 0 "register_operand" "=r")
12924 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12925 "TARGET_64BIT"
12926 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12927 [(set_attr "type" "lea")
12928 (set_attr "length_address" "4")
12929 (set_attr "mode" "DI")])
12930
12931 (define_insn "set_rip_rex64"
12932 [(set (match_operand:DI 0 "register_operand" "=r")
12933 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12934 "TARGET_64BIT"
12935 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12936 [(set_attr "type" "lea")
12937 (set_attr "length_address" "4")
12938 (set_attr "mode" "DI")])
12939
12940 (define_insn "set_got_offset_rex64"
12941 [(set (match_operand:DI 0 "register_operand" "=r")
12942 (unspec:DI
12943 [(label_ref (match_operand 1))]
12944 UNSPEC_SET_GOT_OFFSET))]
12945 "TARGET_LP64"
12946 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12947 [(set_attr "type" "imov")
12948 (set_attr "length_immediate" "0")
12949 (set_attr "length_address" "8")
12950 (set_attr "mode" "DI")])
12951
12952 (define_expand "epilogue"
12953 [(const_int 0)]
12954 ""
12955 "ix86_expand_epilogue (1); DONE;")
12956
12957 (define_expand "sibcall_epilogue"
12958 [(const_int 0)]
12959 ""
12960 "ix86_expand_epilogue (0); DONE;")
12961
12962 (define_expand "eh_return"
12963 [(use (match_operand 0 "register_operand"))]
12964 ""
12965 {
12966 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12967
12968 /* Tricky bit: we write the address of the handler to which we will
12969 be returning into someone else's stack frame, one word below the
12970 stack address we wish to restore. */
12971 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12972 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12973 /* Return address is always in word_mode. */
12974 tmp = gen_rtx_MEM (word_mode, tmp);
12975 if (GET_MODE (ra) != word_mode)
12976 ra = convert_to_mode (word_mode, ra, 1);
12977 emit_move_insn (tmp, ra);
12978
12979 emit_jump_insn (gen_eh_return_internal ());
12980 emit_barrier ();
12981 DONE;
12982 })
12983
12984 (define_insn_and_split "eh_return_internal"
12985 [(eh_return)]
12986 ""
12987 "#"
12988 "epilogue_completed"
12989 [(const_int 0)]
12990 "ix86_expand_epilogue (2); DONE;")
12991
12992 (define_expand "@leave_<mode>"
12993 [(parallel
12994 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
12995 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
12996 (clobber (mem:BLK (scratch)))])]
12997 ""
12998 "operands[0] = GEN_INT (<MODE_SIZE>);")
12999
13000 (define_insn "*leave"
13001 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13002 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13003 (clobber (mem:BLK (scratch)))]
13004 "!TARGET_64BIT"
13005 "leave"
13006 [(set_attr "type" "leave")])
13007
13008 (define_insn "*leave_rex64"
13009 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13010 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13011 (clobber (mem:BLK (scratch)))]
13012 "TARGET_64BIT"
13013 "leave"
13014 [(set_attr "type" "leave")])
13015 \f
13016 ;; Handle -fsplit-stack.
13017
13018 (define_expand "split_stack_prologue"
13019 [(const_int 0)]
13020 ""
13021 {
13022 ix86_expand_split_stack_prologue ();
13023 DONE;
13024 })
13025
13026 ;; In order to support the call/return predictor, we use a return
13027 ;; instruction which the middle-end doesn't see.
13028 (define_insn "split_stack_return"
13029 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13030 UNSPECV_SPLIT_STACK_RETURN)]
13031 ""
13032 {
13033 if (operands[0] == const0_rtx)
13034 return "ret";
13035 else
13036 return "ret\t%0";
13037 }
13038 [(set_attr "atom_unit" "jeu")
13039 (set_attr "modrm" "0")
13040 (set (attr "length")
13041 (if_then_else (match_operand:SI 0 "const0_operand")
13042 (const_int 1)
13043 (const_int 3)))
13044 (set (attr "length_immediate")
13045 (if_then_else (match_operand:SI 0 "const0_operand")
13046 (const_int 0)
13047 (const_int 2)))])
13048
13049 ;; If there are operand 0 bytes available on the stack, jump to
13050 ;; operand 1.
13051
13052 (define_expand "split_stack_space_check"
13053 [(set (pc) (if_then_else
13054 (ltu (minus (reg SP_REG)
13055 (match_operand 0 "register_operand"))
13056 (match_dup 2))
13057 (label_ref (match_operand 1))
13058 (pc)))]
13059 ""
13060 {
13061 rtx reg = gen_reg_rtx (Pmode);
13062
13063 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13064
13065 operands[2] = ix86_split_stack_guard ();
13066 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13067
13068 DONE;
13069 })
13070 \f
13071 ;; Bit manipulation instructions.
13072
13073 (define_expand "ffs<mode>2"
13074 [(set (match_dup 2) (const_int -1))
13075 (parallel [(set (match_dup 3) (match_dup 4))
13076 (set (match_operand:SWI48 0 "register_operand")
13077 (ctz:SWI48
13078 (match_operand:SWI48 1 "nonimmediate_operand")))])
13079 (set (match_dup 0) (if_then_else:SWI48
13080 (eq (match_dup 3) (const_int 0))
13081 (match_dup 2)
13082 (match_dup 0)))
13083 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13084 (clobber (reg:CC FLAGS_REG))])]
13085 ""
13086 {
13087 machine_mode flags_mode;
13088
13089 if (<MODE>mode == SImode && !TARGET_CMOVE)
13090 {
13091 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13092 DONE;
13093 }
13094
13095 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13096
13097 operands[2] = gen_reg_rtx (<MODE>mode);
13098 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13099 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13100 })
13101
13102 (define_insn_and_split "ffssi2_no_cmove"
13103 [(set (match_operand:SI 0 "register_operand" "=r")
13104 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13105 (clobber (match_scratch:SI 2 "=&q"))
13106 (clobber (reg:CC FLAGS_REG))]
13107 "!TARGET_CMOVE"
13108 "#"
13109 "&& reload_completed"
13110 [(parallel [(set (match_dup 4) (match_dup 5))
13111 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13112 (set (strict_low_part (match_dup 3))
13113 (eq:QI (match_dup 4) (const_int 0)))
13114 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13115 (clobber (reg:CC FLAGS_REG))])
13116 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13117 (clobber (reg:CC FLAGS_REG))])
13118 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13119 (clobber (reg:CC FLAGS_REG))])]
13120 {
13121 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13122
13123 operands[3] = gen_lowpart (QImode, operands[2]);
13124 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13125 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13126
13127 ix86_expand_clear (operands[2]);
13128 })
13129
13130 (define_insn_and_split "*tzcnt<mode>_1"
13131 [(set (reg:CCC FLAGS_REG)
13132 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13133 (const_int 0)))
13134 (set (match_operand:SWI48 0 "register_operand" "=r")
13135 (ctz:SWI48 (match_dup 1)))]
13136 "TARGET_BMI"
13137 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13138 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13139 && optimize_function_for_speed_p (cfun)
13140 && !reg_mentioned_p (operands[0], operands[1])"
13141 [(parallel
13142 [(set (reg:CCC FLAGS_REG)
13143 (compare:CCC (match_dup 1) (const_int 0)))
13144 (set (match_dup 0)
13145 (ctz:SWI48 (match_dup 1)))
13146 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13147 "ix86_expand_clear (operands[0]);"
13148 [(set_attr "type" "alu1")
13149 (set_attr "prefix_0f" "1")
13150 (set_attr "prefix_rep" "1")
13151 (set_attr "btver2_decode" "double")
13152 (set_attr "mode" "<MODE>")])
13153
13154 ; False dependency happens when destination is only updated by tzcnt,
13155 ; lzcnt or popcnt. There is no false dependency when destination is
13156 ; also used in source.
13157 (define_insn "*tzcnt<mode>_1_falsedep"
13158 [(set (reg:CCC FLAGS_REG)
13159 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13160 (const_int 0)))
13161 (set (match_operand:SWI48 0 "register_operand" "=r")
13162 (ctz:SWI48 (match_dup 1)))
13163 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13164 UNSPEC_INSN_FALSE_DEP)]
13165 "TARGET_BMI"
13166 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13167 [(set_attr "type" "alu1")
13168 (set_attr "prefix_0f" "1")
13169 (set_attr "prefix_rep" "1")
13170 (set_attr "btver2_decode" "double")
13171 (set_attr "mode" "<MODE>")])
13172
13173 (define_insn "*bsf<mode>_1"
13174 [(set (reg:CCZ FLAGS_REG)
13175 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13176 (const_int 0)))
13177 (set (match_operand:SWI48 0 "register_operand" "=r")
13178 (ctz:SWI48 (match_dup 1)))]
13179 ""
13180 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13181 [(set_attr "type" "alu1")
13182 (set_attr "prefix_0f" "1")
13183 (set_attr "btver2_decode" "double")
13184 (set_attr "znver1_decode" "vector")
13185 (set_attr "mode" "<MODE>")])
13186
13187 (define_insn_and_split "ctz<mode>2"
13188 [(set (match_operand:SWI48 0 "register_operand" "=r")
13189 (ctz:SWI48
13190 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13191 (clobber (reg:CC FLAGS_REG))]
13192 ""
13193 {
13194 if (TARGET_BMI)
13195 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13196 else if (optimize_function_for_size_p (cfun))
13197 ;
13198 else if (TARGET_GENERIC)
13199 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13200 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13201
13202 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13203 }
13204 "(TARGET_BMI || TARGET_GENERIC)
13205 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13206 && optimize_function_for_speed_p (cfun)
13207 && !reg_mentioned_p (operands[0], operands[1])"
13208 [(parallel
13209 [(set (match_dup 0)
13210 (ctz:SWI48 (match_dup 1)))
13211 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13212 (clobber (reg:CC FLAGS_REG))])]
13213 "ix86_expand_clear (operands[0]);"
13214 [(set_attr "type" "alu1")
13215 (set_attr "prefix_0f" "1")
13216 (set (attr "prefix_rep")
13217 (if_then_else
13218 (ior (match_test "TARGET_BMI")
13219 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13220 (match_test "TARGET_GENERIC")))
13221 (const_string "1")
13222 (const_string "0")))
13223 (set_attr "mode" "<MODE>")])
13224
13225 ; False dependency happens when destination is only updated by tzcnt,
13226 ; lzcnt or popcnt. There is no false dependency when destination is
13227 ; also used in source.
13228 (define_insn "*ctz<mode>2_falsedep"
13229 [(set (match_operand:SWI48 0 "register_operand" "=r")
13230 (ctz:SWI48
13231 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13232 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13233 UNSPEC_INSN_FALSE_DEP)
13234 (clobber (reg:CC FLAGS_REG))]
13235 ""
13236 {
13237 if (TARGET_BMI)
13238 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13239 else if (TARGET_GENERIC)
13240 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13241 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13242 else
13243 gcc_unreachable ();
13244 }
13245 [(set_attr "type" "alu1")
13246 (set_attr "prefix_0f" "1")
13247 (set_attr "prefix_rep" "1")
13248 (set_attr "mode" "<MODE>")])
13249
13250 (define_insn "bsr_rex64"
13251 [(set (match_operand:DI 0 "register_operand" "=r")
13252 (minus:DI (const_int 63)
13253 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13254 (clobber (reg:CC FLAGS_REG))]
13255 "TARGET_64BIT"
13256 "bsr{q}\t{%1, %0|%0, %1}"
13257 [(set_attr "type" "alu1")
13258 (set_attr "prefix_0f" "1")
13259 (set_attr "znver1_decode" "vector")
13260 (set_attr "mode" "DI")])
13261
13262 (define_insn "bsr"
13263 [(set (match_operand:SI 0 "register_operand" "=r")
13264 (minus:SI (const_int 31)
13265 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13266 (clobber (reg:CC FLAGS_REG))]
13267 ""
13268 "bsr{l}\t{%1, %0|%0, %1}"
13269 [(set_attr "type" "alu1")
13270 (set_attr "prefix_0f" "1")
13271 (set_attr "znver1_decode" "vector")
13272 (set_attr "mode" "SI")])
13273
13274 (define_insn "*bsrhi"
13275 [(set (match_operand:HI 0 "register_operand" "=r")
13276 (minus:HI (const_int 15)
13277 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13278 (clobber (reg:CC FLAGS_REG))]
13279 ""
13280 "bsr{w}\t{%1, %0|%0, %1}"
13281 [(set_attr "type" "alu1")
13282 (set_attr "prefix_0f" "1")
13283 (set_attr "znver1_decode" "vector")
13284 (set_attr "mode" "HI")])
13285
13286 (define_expand "clz<mode>2"
13287 [(parallel
13288 [(set (match_operand:SWI48 0 "register_operand")
13289 (minus:SWI48
13290 (match_dup 2)
13291 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13292 (clobber (reg:CC FLAGS_REG))])
13293 (parallel
13294 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13295 (clobber (reg:CC FLAGS_REG))])]
13296 ""
13297 {
13298 if (TARGET_LZCNT)
13299 {
13300 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13301 DONE;
13302 }
13303 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13304 })
13305
13306 (define_insn_and_split "clz<mode>2_lzcnt"
13307 [(set (match_operand:SWI48 0 "register_operand" "=r")
13308 (clz:SWI48
13309 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13310 (clobber (reg:CC FLAGS_REG))]
13311 "TARGET_LZCNT"
13312 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13313 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13314 && optimize_function_for_speed_p (cfun)
13315 && !reg_mentioned_p (operands[0], operands[1])"
13316 [(parallel
13317 [(set (match_dup 0)
13318 (clz:SWI48 (match_dup 1)))
13319 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13320 (clobber (reg:CC FLAGS_REG))])]
13321 "ix86_expand_clear (operands[0]);"
13322 [(set_attr "prefix_rep" "1")
13323 (set_attr "type" "bitmanip")
13324 (set_attr "mode" "<MODE>")])
13325
13326 ; False dependency happens when destination is only updated by tzcnt,
13327 ; lzcnt or popcnt. There is no false dependency when destination is
13328 ; also used in source.
13329 (define_insn "*clz<mode>2_lzcnt_falsedep"
13330 [(set (match_operand:SWI48 0 "register_operand" "=r")
13331 (clz:SWI48
13332 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13333 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13334 UNSPEC_INSN_FALSE_DEP)
13335 (clobber (reg:CC FLAGS_REG))]
13336 "TARGET_LZCNT"
13337 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13338 [(set_attr "prefix_rep" "1")
13339 (set_attr "type" "bitmanip")
13340 (set_attr "mode" "<MODE>")])
13341
13342 (define_int_iterator LT_ZCNT
13343 [(UNSPEC_TZCNT "TARGET_BMI")
13344 (UNSPEC_LZCNT "TARGET_LZCNT")])
13345
13346 (define_int_attr lt_zcnt
13347 [(UNSPEC_TZCNT "tzcnt")
13348 (UNSPEC_LZCNT "lzcnt")])
13349
13350 (define_int_attr lt_zcnt_type
13351 [(UNSPEC_TZCNT "alu1")
13352 (UNSPEC_LZCNT "bitmanip")])
13353
13354 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13355 ;; provides operand size as output when source operand is zero.
13356
13357 (define_insn_and_split "<lt_zcnt>_<mode>"
13358 [(set (match_operand:SWI48 0 "register_operand" "=r")
13359 (unspec:SWI48
13360 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13361 (clobber (reg:CC FLAGS_REG))]
13362 ""
13363 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13364 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13365 && optimize_function_for_speed_p (cfun)
13366 && !reg_mentioned_p (operands[0], operands[1])"
13367 [(parallel
13368 [(set (match_dup 0)
13369 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13370 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13371 (clobber (reg:CC FLAGS_REG))])]
13372 "ix86_expand_clear (operands[0]);"
13373 [(set_attr "type" "<lt_zcnt_type>")
13374 (set_attr "prefix_0f" "1")
13375 (set_attr "prefix_rep" "1")
13376 (set_attr "mode" "<MODE>")])
13377
13378 ; False dependency happens when destination is only updated by tzcnt,
13379 ; lzcnt or popcnt. There is no false dependency when destination is
13380 ; also used in source.
13381 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13382 [(set (match_operand:SWI48 0 "register_operand" "=r")
13383 (unspec:SWI48
13384 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13385 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13386 UNSPEC_INSN_FALSE_DEP)
13387 (clobber (reg:CC FLAGS_REG))]
13388 ""
13389 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13390 [(set_attr "type" "<lt_zcnt_type>")
13391 (set_attr "prefix_0f" "1")
13392 (set_attr "prefix_rep" "1")
13393 (set_attr "mode" "<MODE>")])
13394
13395 (define_insn "<lt_zcnt>_hi"
13396 [(set (match_operand:HI 0 "register_operand" "=r")
13397 (unspec:HI
13398 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13399 (clobber (reg:CC FLAGS_REG))]
13400 ""
13401 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13402 [(set_attr "type" "<lt_zcnt_type>")
13403 (set_attr "prefix_0f" "1")
13404 (set_attr "prefix_rep" "1")
13405 (set_attr "mode" "HI")])
13406
13407 ;; BMI instructions.
13408
13409 (define_insn "bmi_bextr_<mode>"
13410 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13411 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13412 (match_operand:SWI48 2 "register_operand" "r,r")]
13413 UNSPEC_BEXTR))
13414 (clobber (reg:CC FLAGS_REG))]
13415 "TARGET_BMI"
13416 "bextr\t{%2, %1, %0|%0, %1, %2}"
13417 [(set_attr "type" "bitmanip")
13418 (set_attr "btver2_decode" "direct, double")
13419 (set_attr "mode" "<MODE>")])
13420
13421 (define_insn "*bmi_bextr_<mode>_ccz"
13422 [(set (reg:CCZ FLAGS_REG)
13423 (compare:CCZ
13424 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13425 (match_operand:SWI48 2 "register_operand" "r,r")]
13426 UNSPEC_BEXTR)
13427 (const_int 0)))
13428 (clobber (match_scratch:SWI48 0 "=r,r"))]
13429 "TARGET_BMI"
13430 "bextr\t{%2, %1, %0|%0, %1, %2}"
13431 [(set_attr "type" "bitmanip")
13432 (set_attr "btver2_decode" "direct, double")
13433 (set_attr "mode" "<MODE>")])
13434
13435 (define_insn "*bmi_blsi_<mode>"
13436 [(set (match_operand:SWI48 0 "register_operand" "=r")
13437 (and:SWI48
13438 (neg:SWI48
13439 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13440 (match_dup 1)))
13441 (clobber (reg:CC FLAGS_REG))]
13442 "TARGET_BMI"
13443 "blsi\t{%1, %0|%0, %1}"
13444 [(set_attr "type" "bitmanip")
13445 (set_attr "btver2_decode" "double")
13446 (set_attr "mode" "<MODE>")])
13447
13448 (define_insn "*bmi_blsmsk_<mode>"
13449 [(set (match_operand:SWI48 0 "register_operand" "=r")
13450 (xor:SWI48
13451 (plus:SWI48
13452 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13453 (const_int -1))
13454 (match_dup 1)))
13455 (clobber (reg:CC FLAGS_REG))]
13456 "TARGET_BMI"
13457 "blsmsk\t{%1, %0|%0, %1}"
13458 [(set_attr "type" "bitmanip")
13459 (set_attr "btver2_decode" "double")
13460 (set_attr "mode" "<MODE>")])
13461
13462 (define_insn "*bmi_blsr_<mode>"
13463 [(set (match_operand:SWI48 0 "register_operand" "=r")
13464 (and:SWI48
13465 (plus:SWI48
13466 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13467 (const_int -1))
13468 (match_dup 1)))
13469 (clobber (reg:CC FLAGS_REG))]
13470 "TARGET_BMI"
13471 "blsr\t{%1, %0|%0, %1}"
13472 [(set_attr "type" "bitmanip")
13473 (set_attr "btver2_decode" "double")
13474 (set_attr "mode" "<MODE>")])
13475
13476 (define_insn "*bmi_blsr_<mode>_cmp"
13477 [(set (reg:CCZ FLAGS_REG)
13478 (compare:CCZ
13479 (and:SWI48
13480 (plus:SWI48
13481 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13482 (const_int -1))
13483 (match_dup 1))
13484 (const_int 0)))
13485 (set (match_operand:SWI48 0 "register_operand" "=r")
13486 (and:SWI48
13487 (plus:SWI48
13488 (match_dup 1)
13489 (const_int -1))
13490 (match_dup 1)))]
13491 "TARGET_BMI"
13492 "blsr\t{%1, %0|%0, %1}"
13493 [(set_attr "type" "bitmanip")
13494 (set_attr "btver2_decode" "double")
13495 (set_attr "mode" "<MODE>")])
13496
13497 (define_insn "*bmi_blsr_<mode>_ccz"
13498 [(set (reg:CCZ FLAGS_REG)
13499 (compare:CCZ
13500 (and:SWI48
13501 (plus:SWI48
13502 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13503 (const_int -1))
13504 (match_dup 1))
13505 (const_int 0)))
13506 (clobber (match_scratch:SWI48 0 "=r"))]
13507 "TARGET_BMI"
13508 "blsr\t{%1, %0|%0, %1}"
13509 [(set_attr "type" "bitmanip")
13510 (set_attr "btver2_decode" "double")
13511 (set_attr "mode" "<MODE>")])
13512
13513 ;; BMI2 instructions.
13514 (define_expand "bmi2_bzhi_<mode>3"
13515 [(parallel
13516 [(set (match_operand:SWI48 0 "register_operand")
13517 (if_then_else:SWI48
13518 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
13519 (const_int 255))
13520 (const_int 0))
13521 (zero_extract:SWI48
13522 (match_operand:SWI48 1 "nonimmediate_operand")
13523 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
13524 (match_dup 3))
13525 (const_int 0))
13526 (const_int 0)))
13527 (clobber (reg:CC FLAGS_REG))])]
13528 "TARGET_BMI2"
13529 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13530
13531 (define_insn "*bmi2_bzhi_<mode>3"
13532 [(set (match_operand:SWI48 0 "register_operand" "=r")
13533 (if_then_else:SWI48
13534 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13535 (const_int 255))
13536 (const_int 0))
13537 (zero_extract:SWI48
13538 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13539 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
13540 (match_operand:SWI48 3 "const_int_operand" "n"))
13541 (const_int 0))
13542 (const_int 0)))
13543 (clobber (reg:CC FLAGS_REG))]
13544 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13545 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13546 [(set_attr "type" "bitmanip")
13547 (set_attr "prefix" "vex")
13548 (set_attr "mode" "<MODE>")])
13549
13550 (define_insn "*bmi2_bzhi_<mode>3_1"
13551 [(set (match_operand:SWI48 0 "register_operand" "=r")
13552 (if_then_else:SWI48
13553 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
13554 (zero_extract:SWI48
13555 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13556 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
13557 (match_operand:SWI48 3 "const_int_operand" "n"))
13558 (const_int 0))
13559 (const_int 0)))
13560 (clobber (reg:CC FLAGS_REG))]
13561 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13562 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13563 [(set_attr "type" "bitmanip")
13564 (set_attr "prefix" "vex")
13565 (set_attr "mode" "<MODE>")])
13566
13567 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13568 [(set (reg:CCZ FLAGS_REG)
13569 (compare:CCZ
13570 (if_then_else:SWI48
13571 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
13572 (zero_extract:SWI48
13573 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13574 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
13575 (match_operand:SWI48 3 "const_int_operand" "n"))
13576 (const_int 0))
13577 (const_int 0))
13578 (const_int 0)))
13579 (clobber (match_scratch:SWI48 0 "=r"))]
13580 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13581 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13582 [(set_attr "type" "bitmanip")
13583 (set_attr "prefix" "vex")
13584 (set_attr "mode" "<MODE>")])
13585
13586 (define_insn "bmi2_pdep_<mode>3"
13587 [(set (match_operand:SWI48 0 "register_operand" "=r")
13588 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13589 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13590 UNSPEC_PDEP))]
13591 "TARGET_BMI2"
13592 "pdep\t{%2, %1, %0|%0, %1, %2}"
13593 [(set_attr "type" "bitmanip")
13594 (set_attr "prefix" "vex")
13595 (set_attr "mode" "<MODE>")])
13596
13597 (define_insn "bmi2_pext_<mode>3"
13598 [(set (match_operand:SWI48 0 "register_operand" "=r")
13599 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13600 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13601 UNSPEC_PEXT))]
13602 "TARGET_BMI2"
13603 "pext\t{%2, %1, %0|%0, %1, %2}"
13604 [(set_attr "type" "bitmanip")
13605 (set_attr "prefix" "vex")
13606 (set_attr "mode" "<MODE>")])
13607
13608 ;; TBM instructions.
13609 (define_expand "tbm_bextri_<mode>"
13610 [(parallel
13611 [(set (match_operand:SWI48 0 "register_operand")
13612 (zero_extract:SWI48
13613 (match_operand:SWI48 1 "nonimmediate_operand")
13614 (match_operand 2 "const_0_to_255_operand" "N")
13615 (match_operand 3 "const_0_to_255_operand" "N")))
13616 (clobber (reg:CC FLAGS_REG))])]
13617 "TARGET_TBM"
13618 {
13619 if (operands[2] == const0_rtx
13620 || INTVAL (operands[3]) >= <MODE_SIZE> * BITS_PER_UNIT)
13621 {
13622 emit_move_insn (operands[0], const0_rtx);
13623 DONE;
13624 }
13625 if (INTVAL (operands[2]) + INTVAL (operands[3])
13626 > <MODE_SIZE> * BITS_PER_UNIT)
13627 operands[2] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - INTVAL (operands[3]));
13628 })
13629
13630 (define_insn "*tbm_bextri_<mode>"
13631 [(set (match_operand:SWI48 0 "register_operand" "=r")
13632 (zero_extract:SWI48
13633 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13634 (match_operand 2 "const_0_to_255_operand" "N")
13635 (match_operand 3 "const_0_to_255_operand" "N")))
13636 (clobber (reg:CC FLAGS_REG))]
13637 "TARGET_TBM"
13638 {
13639 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13640 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13641 }
13642 [(set_attr "type" "bitmanip")
13643 (set_attr "mode" "<MODE>")])
13644
13645 (define_insn "*tbm_blcfill_<mode>"
13646 [(set (match_operand:SWI48 0 "register_operand" "=r")
13647 (and:SWI48
13648 (plus:SWI48
13649 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13650 (const_int 1))
13651 (match_dup 1)))
13652 (clobber (reg:CC FLAGS_REG))]
13653 "TARGET_TBM"
13654 "blcfill\t{%1, %0|%0, %1}"
13655 [(set_attr "type" "bitmanip")
13656 (set_attr "mode" "<MODE>")])
13657
13658 (define_insn "*tbm_blci_<mode>"
13659 [(set (match_operand:SWI48 0 "register_operand" "=r")
13660 (ior:SWI48
13661 (not:SWI48
13662 (plus:SWI48
13663 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13664 (const_int 1)))
13665 (match_dup 1)))
13666 (clobber (reg:CC FLAGS_REG))]
13667 "TARGET_TBM"
13668 "blci\t{%1, %0|%0, %1}"
13669 [(set_attr "type" "bitmanip")
13670 (set_attr "mode" "<MODE>")])
13671
13672 (define_insn "*tbm_blcic_<mode>"
13673 [(set (match_operand:SWI48 0 "register_operand" "=r")
13674 (and:SWI48
13675 (plus:SWI48
13676 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13677 (const_int 1))
13678 (not:SWI48
13679 (match_dup 1))))
13680 (clobber (reg:CC FLAGS_REG))]
13681 "TARGET_TBM"
13682 "blcic\t{%1, %0|%0, %1}"
13683 [(set_attr "type" "bitmanip")
13684 (set_attr "mode" "<MODE>")])
13685
13686 (define_insn "*tbm_blcmsk_<mode>"
13687 [(set (match_operand:SWI48 0 "register_operand" "=r")
13688 (xor:SWI48
13689 (plus:SWI48
13690 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13691 (const_int 1))
13692 (match_dup 1)))
13693 (clobber (reg:CC FLAGS_REG))]
13694 "TARGET_TBM"
13695 "blcmsk\t{%1, %0|%0, %1}"
13696 [(set_attr "type" "bitmanip")
13697 (set_attr "mode" "<MODE>")])
13698
13699 (define_insn "*tbm_blcs_<mode>"
13700 [(set (match_operand:SWI48 0 "register_operand" "=r")
13701 (ior:SWI48
13702 (plus:SWI48
13703 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13704 (const_int 1))
13705 (match_dup 1)))
13706 (clobber (reg:CC FLAGS_REG))]
13707 "TARGET_TBM"
13708 "blcs\t{%1, %0|%0, %1}"
13709 [(set_attr "type" "bitmanip")
13710 (set_attr "mode" "<MODE>")])
13711
13712 (define_insn "*tbm_blsfill_<mode>"
13713 [(set (match_operand:SWI48 0 "register_operand" "=r")
13714 (ior:SWI48
13715 (plus:SWI48
13716 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13717 (const_int -1))
13718 (match_dup 1)))
13719 (clobber (reg:CC FLAGS_REG))]
13720 "TARGET_TBM"
13721 "blsfill\t{%1, %0|%0, %1}"
13722 [(set_attr "type" "bitmanip")
13723 (set_attr "mode" "<MODE>")])
13724
13725 (define_insn "*tbm_blsic_<mode>"
13726 [(set (match_operand:SWI48 0 "register_operand" "=r")
13727 (ior:SWI48
13728 (plus:SWI48
13729 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13730 (const_int -1))
13731 (not:SWI48
13732 (match_dup 1))))
13733 (clobber (reg:CC FLAGS_REG))]
13734 "TARGET_TBM"
13735 "blsic\t{%1, %0|%0, %1}"
13736 [(set_attr "type" "bitmanip")
13737 (set_attr "mode" "<MODE>")])
13738
13739 (define_insn "*tbm_t1mskc_<mode>"
13740 [(set (match_operand:SWI48 0 "register_operand" "=r")
13741 (ior:SWI48
13742 (plus:SWI48
13743 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13744 (const_int 1))
13745 (not:SWI48
13746 (match_dup 1))))
13747 (clobber (reg:CC FLAGS_REG))]
13748 "TARGET_TBM"
13749 "t1mskc\t{%1, %0|%0, %1}"
13750 [(set_attr "type" "bitmanip")
13751 (set_attr "mode" "<MODE>")])
13752
13753 (define_insn "*tbm_tzmsk_<mode>"
13754 [(set (match_operand:SWI48 0 "register_operand" "=r")
13755 (and:SWI48
13756 (plus:SWI48
13757 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13758 (const_int -1))
13759 (not:SWI48
13760 (match_dup 1))))
13761 (clobber (reg:CC FLAGS_REG))]
13762 "TARGET_TBM"
13763 "tzmsk\t{%1, %0|%0, %1}"
13764 [(set_attr "type" "bitmanip")
13765 (set_attr "mode" "<MODE>")])
13766
13767 (define_insn_and_split "popcount<mode>2"
13768 [(set (match_operand:SWI48 0 "register_operand" "=r")
13769 (popcount:SWI48
13770 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13771 (clobber (reg:CC FLAGS_REG))]
13772 "TARGET_POPCNT"
13773 {
13774 #if TARGET_MACHO
13775 return "popcnt\t{%1, %0|%0, %1}";
13776 #else
13777 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13778 #endif
13779 }
13780 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13781 && optimize_function_for_speed_p (cfun)
13782 && !reg_mentioned_p (operands[0], operands[1])"
13783 [(parallel
13784 [(set (match_dup 0)
13785 (popcount:SWI48 (match_dup 1)))
13786 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13787 (clobber (reg:CC FLAGS_REG))])]
13788 "ix86_expand_clear (operands[0]);"
13789 [(set_attr "prefix_rep" "1")
13790 (set_attr "type" "bitmanip")
13791 (set_attr "mode" "<MODE>")])
13792
13793 ; False dependency happens when destination is only updated by tzcnt,
13794 ; lzcnt or popcnt. There is no false dependency when destination is
13795 ; also used in source.
13796 (define_insn "*popcount<mode>2_falsedep"
13797 [(set (match_operand:SWI48 0 "register_operand" "=r")
13798 (popcount:SWI48
13799 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13800 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13801 UNSPEC_INSN_FALSE_DEP)
13802 (clobber (reg:CC FLAGS_REG))]
13803 "TARGET_POPCNT"
13804 {
13805 #if TARGET_MACHO
13806 return "popcnt\t{%1, %0|%0, %1}";
13807 #else
13808 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13809 #endif
13810 }
13811 [(set_attr "prefix_rep" "1")
13812 (set_attr "type" "bitmanip")
13813 (set_attr "mode" "<MODE>")])
13814
13815 (define_insn_and_split "*popcounthi2_1"
13816 [(set (match_operand:SI 0 "register_operand")
13817 (popcount:SI
13818 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
13819 (clobber (reg:CC FLAGS_REG))]
13820 "TARGET_POPCNT
13821 && can_create_pseudo_p ()"
13822 "#"
13823 "&& 1"
13824 [(const_int 0)]
13825 {
13826 rtx tmp = gen_reg_rtx (HImode);
13827
13828 emit_insn (gen_popcounthi2 (tmp, operands[1]));
13829 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
13830 DONE;
13831 })
13832
13833 (define_insn "popcounthi2"
13834 [(set (match_operand:HI 0 "register_operand" "=r")
13835 (popcount:HI
13836 (match_operand:HI 1 "nonimmediate_operand" "rm")))
13837 (clobber (reg:CC FLAGS_REG))]
13838 "TARGET_POPCNT"
13839 {
13840 #if TARGET_MACHO
13841 return "popcnt\t{%1, %0|%0, %1}";
13842 #else
13843 return "popcnt{w}\t{%1, %0|%0, %1}";
13844 #endif
13845 }
13846 [(set_attr "prefix_rep" "1")
13847 (set_attr "type" "bitmanip")
13848 (set_attr "mode" "HI")])
13849
13850 (define_expand "bswapdi2"
13851 [(set (match_operand:DI 0 "register_operand")
13852 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13853 "TARGET_64BIT"
13854 {
13855 if (!TARGET_MOVBE)
13856 operands[1] = force_reg (DImode, operands[1]);
13857 })
13858
13859 (define_expand "bswapsi2"
13860 [(set (match_operand:SI 0 "register_operand")
13861 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13862 ""
13863 {
13864 if (TARGET_MOVBE)
13865 ;
13866 else if (TARGET_BSWAP)
13867 operands[1] = force_reg (SImode, operands[1]);
13868 else
13869 {
13870 rtx x = operands[0];
13871
13872 emit_move_insn (x, operands[1]);
13873 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13874 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13875 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13876 DONE;
13877 }
13878 })
13879
13880 (define_insn "*bswap<mode>2_movbe"
13881 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13882 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13883 "TARGET_MOVBE
13884 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13885 "@
13886 bswap\t%0
13887 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
13888 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
13889 [(set_attr "type" "bitmanip,imov,imov")
13890 (set_attr "modrm" "0,1,1")
13891 (set_attr "prefix_0f" "*,1,1")
13892 (set_attr "prefix_extra" "*,1,1")
13893 (set_attr "mode" "<MODE>")])
13894
13895 (define_insn "*bswap<mode>2"
13896 [(set (match_operand:SWI48 0 "register_operand" "=r")
13897 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13898 "TARGET_BSWAP"
13899 "bswap\t%0"
13900 [(set_attr "type" "bitmanip")
13901 (set_attr "modrm" "0")
13902 (set_attr "mode" "<MODE>")])
13903
13904 (define_expand "bswaphi2"
13905 [(set (match_operand:HI 0 "register_operand")
13906 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
13907 "TARGET_MOVBE")
13908
13909 (define_insn "*bswaphi2_movbe"
13910 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
13911 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
13912 "TARGET_MOVBE
13913 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13914 "@
13915 xchg{b}\t{%h0, %b0|%b0, %h0}
13916 movbe{w}\t{%1, %0|%0, %1}
13917 movbe{w}\t{%1, %0|%0, %1}"
13918 [(set_attr "type" "imov")
13919 (set_attr "modrm" "*,1,1")
13920 (set_attr "prefix_0f" "*,1,1")
13921 (set_attr "prefix_extra" "*,1,1")
13922 (set_attr "pent_pair" "np,*,*")
13923 (set_attr "athlon_decode" "vector,*,*")
13924 (set_attr "amdfam10_decode" "double,*,*")
13925 (set_attr "bdver1_decode" "double,*,*")
13926 (set_attr "mode" "QI,HI,HI")])
13927
13928 (define_peephole2
13929 [(set (match_operand:HI 0 "general_reg_operand")
13930 (bswap:HI (match_dup 0)))]
13931 "TARGET_MOVBE
13932 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
13933 && peep2_regno_dead_p (0, FLAGS_REG)"
13934 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
13935 (clobber (reg:CC FLAGS_REG))])])
13936
13937 (define_insn "bswaphi_lowpart"
13938 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13939 (bswap:HI (match_dup 0)))
13940 (clobber (reg:CC FLAGS_REG))]
13941 ""
13942 "@
13943 xchg{b}\t{%h0, %b0|%b0, %h0}
13944 rol{w}\t{$8, %0|%0, 8}"
13945 [(set (attr "preferred_for_size")
13946 (cond [(eq_attr "alternative" "0")
13947 (symbol_ref "true")]
13948 (symbol_ref "false")))
13949 (set (attr "preferred_for_speed")
13950 (cond [(eq_attr "alternative" "0")
13951 (symbol_ref "TARGET_USE_XCHGB")]
13952 (symbol_ref "!TARGET_USE_XCHGB")))
13953 (set_attr "length" "2,4")
13954 (set_attr "mode" "QI,HI")])
13955
13956 (define_expand "paritydi2"
13957 [(set (match_operand:DI 0 "register_operand")
13958 (parity:DI (match_operand:DI 1 "register_operand")))]
13959 "! TARGET_POPCNT"
13960 {
13961 rtx scratch = gen_reg_rtx (QImode);
13962
13963 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13964 NULL_RTX, operands[1]));
13965
13966 ix86_expand_setcc (scratch, ORDERED,
13967 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13968
13969 if (TARGET_64BIT)
13970 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13971 else
13972 {
13973 rtx tmp = gen_reg_rtx (SImode);
13974
13975 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13976 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13977 }
13978 DONE;
13979 })
13980
13981 (define_expand "paritysi2"
13982 [(set (match_operand:SI 0 "register_operand")
13983 (parity:SI (match_operand:SI 1 "register_operand")))]
13984 "! TARGET_POPCNT"
13985 {
13986 rtx scratch = gen_reg_rtx (QImode);
13987
13988 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13989
13990 ix86_expand_setcc (scratch, ORDERED,
13991 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13992
13993 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13994 DONE;
13995 })
13996
13997 (define_insn_and_split "paritydi2_cmp"
13998 [(set (reg:CC FLAGS_REG)
13999 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14000 UNSPEC_PARITY))
14001 (clobber (match_scratch:DI 0 "=r"))
14002 (clobber (match_scratch:SI 1 "=&r"))
14003 (clobber (match_scratch:HI 2 "=Q"))]
14004 "! TARGET_POPCNT"
14005 "#"
14006 "&& reload_completed"
14007 [(parallel
14008 [(set (match_dup 1)
14009 (xor:SI (match_dup 1) (match_dup 4)))
14010 (clobber (reg:CC FLAGS_REG))])
14011 (parallel
14012 [(set (reg:CC FLAGS_REG)
14013 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14014 (clobber (match_dup 1))
14015 (clobber (match_dup 2))])]
14016 {
14017 operands[4] = gen_lowpart (SImode, operands[3]);
14018
14019 if (TARGET_64BIT)
14020 {
14021 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14022 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14023 }
14024 else
14025 operands[1] = gen_highpart (SImode, operands[3]);
14026 })
14027
14028 (define_insn_and_split "paritysi2_cmp"
14029 [(set (reg:CC FLAGS_REG)
14030 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14031 UNSPEC_PARITY))
14032 (clobber (match_scratch:SI 0 "=r"))
14033 (clobber (match_scratch:HI 1 "=&Q"))]
14034 "! TARGET_POPCNT"
14035 "#"
14036 "&& reload_completed"
14037 [(parallel
14038 [(set (match_dup 1)
14039 (xor:HI (match_dup 1) (match_dup 3)))
14040 (clobber (reg:CC FLAGS_REG))])
14041 (parallel
14042 [(set (reg:CC FLAGS_REG)
14043 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14044 (clobber (match_dup 1))])]
14045 {
14046 operands[3] = gen_lowpart (HImode, operands[2]);
14047
14048 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14049 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14050 })
14051
14052 (define_insn "*parityhi2_cmp"
14053 [(set (reg:CC FLAGS_REG)
14054 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14055 UNSPEC_PARITY))
14056 (clobber (match_scratch:HI 0 "=Q"))]
14057 "! TARGET_POPCNT"
14058 "xor{b}\t{%h0, %b0|%b0, %h0}"
14059 [(set_attr "length" "2")
14060 (set_attr "mode" "HI")])
14061
14062 \f
14063 ;; Thread-local storage patterns for ELF.
14064 ;;
14065 ;; Note that these code sequences must appear exactly as shown
14066 ;; in order to allow linker relaxation.
14067
14068 (define_insn "*tls_global_dynamic_32_gnu"
14069 [(set (match_operand:SI 0 "register_operand" "=a")
14070 (unspec:SI
14071 [(match_operand:SI 1 "register_operand" "Yb")
14072 (match_operand 2 "tls_symbolic_operand")
14073 (match_operand 3 "constant_call_address_operand" "Bz")
14074 (reg:SI SP_REG)]
14075 UNSPEC_TLS_GD))
14076 (clobber (match_scratch:SI 4 "=d"))
14077 (clobber (match_scratch:SI 5 "=c"))
14078 (clobber (reg:CC FLAGS_REG))]
14079 "!TARGET_64BIT && TARGET_GNU_TLS"
14080 {
14081 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14082 output_asm_insn
14083 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14084 else
14085 output_asm_insn
14086 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14087 if (TARGET_SUN_TLS)
14088 #ifdef HAVE_AS_IX86_TLSGDPLT
14089 return "call\t%a2@tlsgdplt";
14090 #else
14091 return "call\t%p3@plt";
14092 #endif
14093 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14094 return "call\t%P3";
14095 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14096 }
14097 [(set_attr "type" "multi")
14098 (set_attr "length" "12")])
14099
14100 (define_expand "tls_global_dynamic_32"
14101 [(parallel
14102 [(set (match_operand:SI 0 "register_operand")
14103 (unspec:SI [(match_operand:SI 2 "register_operand")
14104 (match_operand 1 "tls_symbolic_operand")
14105 (match_operand 3 "constant_call_address_operand")
14106 (reg:SI SP_REG)]
14107 UNSPEC_TLS_GD))
14108 (clobber (match_scratch:SI 4))
14109 (clobber (match_scratch:SI 5))
14110 (clobber (reg:CC FLAGS_REG))])]
14111 ""
14112 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14113
14114 (define_insn "*tls_global_dynamic_64_<mode>"
14115 [(set (match_operand:P 0 "register_operand" "=a")
14116 (call:P
14117 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14118 (match_operand 3)))
14119 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14120 (reg:P SP_REG)]
14121 UNSPEC_TLS_GD)]
14122 "TARGET_64BIT"
14123 {
14124 if (!TARGET_X32)
14125 /* The .loc directive has effect for 'the immediately following assembly
14126 instruction'. So for a sequence:
14127 .loc f l
14128 .byte x
14129 insn1
14130 the 'immediately following assembly instruction' is insn1.
14131 We want to emit an insn prefix here, but if we use .byte (as shown in
14132 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14133 inside the insn sequence, rather than to the start. After relaxation
14134 of the sequence by the linker, the .loc might point inside an insn.
14135 Use data16 prefix instead, which doesn't have this problem. */
14136 fputs ("\tdata16", asm_out_file);
14137 output_asm_insn
14138 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14139 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14140 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14141 else
14142 fputs (ASM_BYTE "0x66\n", asm_out_file);
14143 fputs ("\trex64\n", asm_out_file);
14144 if (TARGET_SUN_TLS)
14145 return "call\t%p2@plt";
14146 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14147 return "call\t%P2";
14148 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14149 }
14150 [(set_attr "type" "multi")
14151 (set (attr "length")
14152 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14153
14154 (define_insn "*tls_global_dynamic_64_largepic"
14155 [(set (match_operand:DI 0 "register_operand" "=a")
14156 (call:DI
14157 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14158 (match_operand:DI 3 "immediate_operand" "i")))
14159 (match_operand 4)))
14160 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14161 (reg:DI SP_REG)]
14162 UNSPEC_TLS_GD)]
14163 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14164 && GET_CODE (operands[3]) == CONST
14165 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14166 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14167 {
14168 output_asm_insn
14169 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14170 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14171 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14172 return "call\t{*%%rax|rax}";
14173 }
14174 [(set_attr "type" "multi")
14175 (set_attr "length" "22")])
14176
14177 (define_expand "@tls_global_dynamic_64_<mode>"
14178 [(parallel
14179 [(set (match_operand:P 0 "register_operand")
14180 (call:P
14181 (mem:QI (match_operand 2))
14182 (const_int 0)))
14183 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14184 (reg:P SP_REG)]
14185 UNSPEC_TLS_GD)])]
14186 "TARGET_64BIT"
14187 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14188
14189 (define_insn "*tls_local_dynamic_base_32_gnu"
14190 [(set (match_operand:SI 0 "register_operand" "=a")
14191 (unspec:SI
14192 [(match_operand:SI 1 "register_operand" "Yb")
14193 (match_operand 2 "constant_call_address_operand" "Bz")
14194 (reg:SI SP_REG)]
14195 UNSPEC_TLS_LD_BASE))
14196 (clobber (match_scratch:SI 3 "=d"))
14197 (clobber (match_scratch:SI 4 "=c"))
14198 (clobber (reg:CC FLAGS_REG))]
14199 "!TARGET_64BIT && TARGET_GNU_TLS"
14200 {
14201 output_asm_insn
14202 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14203 if (TARGET_SUN_TLS)
14204 {
14205 if (HAVE_AS_IX86_TLSLDMPLT)
14206 return "call\t%&@tlsldmplt";
14207 else
14208 return "call\t%p2@plt";
14209 }
14210 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14211 return "call\t%P2";
14212 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14213 }
14214 [(set_attr "type" "multi")
14215 (set_attr "length" "11")])
14216
14217 (define_expand "tls_local_dynamic_base_32"
14218 [(parallel
14219 [(set (match_operand:SI 0 "register_operand")
14220 (unspec:SI
14221 [(match_operand:SI 1 "register_operand")
14222 (match_operand 2 "constant_call_address_operand")
14223 (reg:SI SP_REG)]
14224 UNSPEC_TLS_LD_BASE))
14225 (clobber (match_scratch:SI 3))
14226 (clobber (match_scratch:SI 4))
14227 (clobber (reg:CC FLAGS_REG))])]
14228 ""
14229 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14230
14231 (define_insn "*tls_local_dynamic_base_64_<mode>"
14232 [(set (match_operand:P 0 "register_operand" "=a")
14233 (call:P
14234 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14235 (match_operand 2)))
14236 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14237 "TARGET_64BIT"
14238 {
14239 output_asm_insn
14240 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14241 if (TARGET_SUN_TLS)
14242 return "call\t%p1@plt";
14243 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14244 return "call\t%P1";
14245 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14246 }
14247 [(set_attr "type" "multi")
14248 (set_attr "length" "12")])
14249
14250 (define_insn "*tls_local_dynamic_base_64_largepic"
14251 [(set (match_operand:DI 0 "register_operand" "=a")
14252 (call:DI
14253 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14254 (match_operand:DI 2 "immediate_operand" "i")))
14255 (match_operand 3)))
14256 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14257 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14258 && GET_CODE (operands[2]) == CONST
14259 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14260 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14261 {
14262 output_asm_insn
14263 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14264 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14265 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14266 return "call\t{*%%rax|rax}";
14267 }
14268 [(set_attr "type" "multi")
14269 (set_attr "length" "22")])
14270
14271 (define_expand "@tls_local_dynamic_base_64_<mode>"
14272 [(parallel
14273 [(set (match_operand:P 0 "register_operand")
14274 (call:P
14275 (mem:QI (match_operand 1))
14276 (const_int 0)))
14277 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14278 "TARGET_64BIT"
14279 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14280
14281 ;; Local dynamic of a single variable is a lose. Show combine how
14282 ;; to convert that back to global dynamic.
14283
14284 (define_insn_and_split "*tls_local_dynamic_32_once"
14285 [(set (match_operand:SI 0 "register_operand" "=a")
14286 (plus:SI
14287 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14288 (match_operand 2 "constant_call_address_operand" "Bz")
14289 (reg:SI SP_REG)]
14290 UNSPEC_TLS_LD_BASE)
14291 (const:SI (unspec:SI
14292 [(match_operand 3 "tls_symbolic_operand")]
14293 UNSPEC_DTPOFF))))
14294 (clobber (match_scratch:SI 4 "=d"))
14295 (clobber (match_scratch:SI 5 "=c"))
14296 (clobber (reg:CC FLAGS_REG))]
14297 ""
14298 "#"
14299 ""
14300 [(parallel
14301 [(set (match_dup 0)
14302 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14303 (reg:SI SP_REG)]
14304 UNSPEC_TLS_GD))
14305 (clobber (match_dup 4))
14306 (clobber (match_dup 5))
14307 (clobber (reg:CC FLAGS_REG))])])
14308
14309 ;; Load and add the thread base pointer from %<tp_seg>:0.
14310 (define_insn_and_split "*load_tp_<mode>"
14311 [(set (match_operand:PTR 0 "register_operand" "=r")
14312 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14313 ""
14314 "#"
14315 ""
14316 [(set (match_dup 0)
14317 (match_dup 1))]
14318 {
14319 addr_space_t as = DEFAULT_TLS_SEG_REG;
14320
14321 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14322 set_mem_addr_space (operands[1], as);
14323 })
14324
14325 (define_insn_and_split "*load_tp_x32_zext"
14326 [(set (match_operand:DI 0 "register_operand" "=r")
14327 (zero_extend:DI
14328 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14329 "TARGET_X32"
14330 "#"
14331 ""
14332 [(set (match_dup 0)
14333 (zero_extend:DI (match_dup 1)))]
14334 {
14335 addr_space_t as = DEFAULT_TLS_SEG_REG;
14336
14337 operands[1] = gen_const_mem (SImode, const0_rtx);
14338 set_mem_addr_space (operands[1], as);
14339 })
14340
14341 (define_insn_and_split "*add_tp_<mode>"
14342 [(set (match_operand:PTR 0 "register_operand" "=r")
14343 (plus:PTR
14344 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14345 (match_operand:PTR 1 "register_operand" "0")))
14346 (clobber (reg:CC FLAGS_REG))]
14347 ""
14348 "#"
14349 ""
14350 [(parallel
14351 [(set (match_dup 0)
14352 (plus:PTR (match_dup 1) (match_dup 2)))
14353 (clobber (reg:CC FLAGS_REG))])]
14354 {
14355 addr_space_t as = DEFAULT_TLS_SEG_REG;
14356
14357 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14358 set_mem_addr_space (operands[2], as);
14359 })
14360
14361 (define_insn_and_split "*add_tp_x32_zext"
14362 [(set (match_operand:DI 0 "register_operand" "=r")
14363 (zero_extend:DI
14364 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14365 (match_operand:SI 1 "register_operand" "0"))))
14366 (clobber (reg:CC FLAGS_REG))]
14367 "TARGET_X32"
14368 "#"
14369 ""
14370 [(parallel
14371 [(set (match_dup 0)
14372 (zero_extend:DI
14373 (plus:SI (match_dup 1) (match_dup 2))))
14374 (clobber (reg:CC FLAGS_REG))])]
14375 {
14376 addr_space_t as = DEFAULT_TLS_SEG_REG;
14377
14378 operands[2] = gen_const_mem (SImode, const0_rtx);
14379 set_mem_addr_space (operands[2], as);
14380 })
14381
14382 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14383 ;; %rax as destination of the initial executable code sequence.
14384 (define_insn "tls_initial_exec_64_sun"
14385 [(set (match_operand:DI 0 "register_operand" "=a")
14386 (unspec:DI
14387 [(match_operand 1 "tls_symbolic_operand")]
14388 UNSPEC_TLS_IE_SUN))
14389 (clobber (reg:CC FLAGS_REG))]
14390 "TARGET_64BIT && TARGET_SUN_TLS"
14391 {
14392 output_asm_insn
14393 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14394 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14395 }
14396 [(set_attr "type" "multi")])
14397
14398 ;; GNU2 TLS patterns can be split.
14399
14400 (define_expand "tls_dynamic_gnu2_32"
14401 [(set (match_dup 3)
14402 (plus:SI (match_operand:SI 2 "register_operand")
14403 (const:SI
14404 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14405 UNSPEC_TLSDESC))))
14406 (parallel
14407 [(set (match_operand:SI 0 "register_operand")
14408 (unspec:SI [(match_dup 1) (match_dup 3)
14409 (match_dup 2) (reg:SI SP_REG)]
14410 UNSPEC_TLSDESC))
14411 (clobber (reg:CC FLAGS_REG))])]
14412 "!TARGET_64BIT && TARGET_GNU2_TLS"
14413 {
14414 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14415 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14416 })
14417
14418 (define_insn "*tls_dynamic_gnu2_lea_32"
14419 [(set (match_operand:SI 0 "register_operand" "=r")
14420 (plus:SI (match_operand:SI 1 "register_operand" "b")
14421 (const:SI
14422 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14423 UNSPEC_TLSDESC))))]
14424 "!TARGET_64BIT && TARGET_GNU2_TLS"
14425 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14426 [(set_attr "type" "lea")
14427 (set_attr "mode" "SI")
14428 (set_attr "length" "6")
14429 (set_attr "length_address" "4")])
14430
14431 (define_insn "*tls_dynamic_gnu2_call_32"
14432 [(set (match_operand:SI 0 "register_operand" "=a")
14433 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14434 (match_operand:SI 2 "register_operand" "0")
14435 ;; we have to make sure %ebx still points to the GOT
14436 (match_operand:SI 3 "register_operand" "b")
14437 (reg:SI SP_REG)]
14438 UNSPEC_TLSDESC))
14439 (clobber (reg:CC FLAGS_REG))]
14440 "!TARGET_64BIT && TARGET_GNU2_TLS"
14441 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14442 [(set_attr "type" "call")
14443 (set_attr "length" "2")
14444 (set_attr "length_address" "0")])
14445
14446 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14447 [(set (match_operand:SI 0 "register_operand" "=&a")
14448 (plus:SI
14449 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14450 (match_operand:SI 4)
14451 (match_operand:SI 2 "register_operand" "b")
14452 (reg:SI SP_REG)]
14453 UNSPEC_TLSDESC)
14454 (const:SI (unspec:SI
14455 [(match_operand 1 "tls_symbolic_operand")]
14456 UNSPEC_DTPOFF))))
14457 (clobber (reg:CC FLAGS_REG))]
14458 "!TARGET_64BIT && TARGET_GNU2_TLS"
14459 "#"
14460 ""
14461 [(set (match_dup 0) (match_dup 5))]
14462 {
14463 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14464 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14465 })
14466
14467 (define_expand "tls_dynamic_gnu2_64"
14468 [(set (match_dup 2)
14469 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14470 UNSPEC_TLSDESC))
14471 (parallel
14472 [(set (match_operand:DI 0 "register_operand")
14473 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14474 UNSPEC_TLSDESC))
14475 (clobber (reg:CC FLAGS_REG))])]
14476 "TARGET_64BIT && TARGET_GNU2_TLS"
14477 {
14478 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14479 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14480 })
14481
14482 (define_insn "*tls_dynamic_gnu2_lea_64"
14483 [(set (match_operand:DI 0 "register_operand" "=r")
14484 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14485 UNSPEC_TLSDESC))]
14486 "TARGET_64BIT && TARGET_GNU2_TLS"
14487 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14488 [(set_attr "type" "lea")
14489 (set_attr "mode" "DI")
14490 (set_attr "length" "7")
14491 (set_attr "length_address" "4")])
14492
14493 (define_insn "*tls_dynamic_gnu2_call_64"
14494 [(set (match_operand:DI 0 "register_operand" "=a")
14495 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14496 (match_operand:DI 2 "register_operand" "0")
14497 (reg:DI SP_REG)]
14498 UNSPEC_TLSDESC))
14499 (clobber (reg:CC FLAGS_REG))]
14500 "TARGET_64BIT && TARGET_GNU2_TLS"
14501 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14502 [(set_attr "type" "call")
14503 (set_attr "length" "2")
14504 (set_attr "length_address" "0")])
14505
14506 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14507 [(set (match_operand:DI 0 "register_operand" "=&a")
14508 (plus:DI
14509 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14510 (match_operand:DI 3)
14511 (reg:DI SP_REG)]
14512 UNSPEC_TLSDESC)
14513 (const:DI (unspec:DI
14514 [(match_operand 1 "tls_symbolic_operand")]
14515 UNSPEC_DTPOFF))))
14516 (clobber (reg:CC FLAGS_REG))]
14517 "TARGET_64BIT && TARGET_GNU2_TLS"
14518 "#"
14519 ""
14520 [(set (match_dup 0) (match_dup 4))]
14521 {
14522 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14523 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14524 })
14525
14526 (define_split
14527 [(match_operand 0 "tls_address_pattern")]
14528 "TARGET_TLS_DIRECT_SEG_REFS"
14529 [(match_dup 0)]
14530 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14531
14532 \f
14533 ;; These patterns match the binary 387 instructions for addM3, subM3,
14534 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14535 ;; SFmode. The first is the normal insn, the second the same insn but
14536 ;; with one operand a conversion, and the third the same insn but with
14537 ;; the other operand a conversion. The conversion may be SFmode or
14538 ;; SImode if the target mode DFmode, but only SImode if the target mode
14539 ;; is SFmode.
14540
14541 ;; Gcc is slightly more smart about handling normal two address instructions
14542 ;; so use special patterns for add and mull.
14543
14544 (define_insn "*fop_xf_comm_i387"
14545 [(set (match_operand:XF 0 "register_operand" "=f")
14546 (match_operator:XF 3 "binary_fp_operator"
14547 [(match_operand:XF 1 "register_operand" "%0")
14548 (match_operand:XF 2 "register_operand" "f")]))]
14549 "TARGET_80387
14550 && COMMUTATIVE_ARITH_P (operands[3])"
14551 "* return output_387_binary_op (insn, operands);"
14552 [(set (attr "type")
14553 (if_then_else (match_operand:XF 3 "mult_operator")
14554 (const_string "fmul")
14555 (const_string "fop")))
14556 (set_attr "mode" "XF")])
14557
14558 (define_insn "*fop_<mode>_comm"
14559 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14560 (match_operator:MODEF 3 "binary_fp_operator"
14561 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14562 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14563 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14564 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14565 && COMMUTATIVE_ARITH_P (operands[3])
14566 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14567 "* return output_387_binary_op (insn, operands);"
14568 [(set (attr "type")
14569 (if_then_else (eq_attr "alternative" "1,2")
14570 (if_then_else (match_operand:MODEF 3 "mult_operator")
14571 (const_string "ssemul")
14572 (const_string "sseadd"))
14573 (if_then_else (match_operand:MODEF 3 "mult_operator")
14574 (const_string "fmul")
14575 (const_string "fop"))))
14576 (set_attr "isa" "*,noavx,avx")
14577 (set_attr "prefix" "orig,orig,vex")
14578 (set_attr "mode" "<MODE>")
14579 (set (attr "enabled")
14580 (if_then_else
14581 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14582 (if_then_else
14583 (eq_attr "alternative" "0")
14584 (symbol_ref "TARGET_MIX_SSE_I387
14585 && X87_ENABLE_ARITH (<MODE>mode)")
14586 (const_string "*"))
14587 (if_then_else
14588 (eq_attr "alternative" "0")
14589 (symbol_ref "true")
14590 (symbol_ref "false"))))])
14591
14592 (define_insn "*rcpsf2_sse"
14593 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
14594 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
14595 UNSPEC_RCP))]
14596 "TARGET_SSE && TARGET_SSE_MATH"
14597 "@
14598 %vrcpss\t{%d1, %0|%0, %d1}
14599 %vrcpss\t{%d1, %0|%0, %d1}
14600 %vrcpss\t{%1, %d0|%d0, %1}"
14601 [(set_attr "type" "sse")
14602 (set_attr "atom_sse_attr" "rcp")
14603 (set_attr "btver2_sse_attr" "rcp")
14604 (set_attr "prefix" "maybe_vex")
14605 (set_attr "mode" "SF")
14606 (set (attr "preferred_for_speed")
14607 (cond [(eq_attr "alternative" "1")
14608 (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14609 (eq_attr "alternative" "2")
14610 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14611 ]
14612 (symbol_ref "true")))])
14613
14614 (define_insn "*fop_xf_1_i387"
14615 [(set (match_operand:XF 0 "register_operand" "=f,f")
14616 (match_operator:XF 3 "binary_fp_operator"
14617 [(match_operand:XF 1 "register_operand" "0,f")
14618 (match_operand:XF 2 "register_operand" "f,0")]))]
14619 "TARGET_80387
14620 && !COMMUTATIVE_ARITH_P (operands[3])"
14621 "* return output_387_binary_op (insn, operands);"
14622 [(set (attr "type")
14623 (if_then_else (match_operand:XF 3 "div_operator")
14624 (const_string "fdiv")
14625 (const_string "fop")))
14626 (set_attr "mode" "XF")])
14627
14628 (define_insn "*fop_<mode>_1"
14629 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14630 (match_operator:MODEF 3 "binary_fp_operator"
14631 [(match_operand:MODEF 1
14632 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14633 (match_operand:MODEF 2
14634 "nonimmediate_operand" "fm,0,xm,vm")]))]
14635 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14636 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14637 && !COMMUTATIVE_ARITH_P (operands[3])
14638 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14639 "* return output_387_binary_op (insn, operands);"
14640 [(set (attr "type")
14641 (if_then_else (eq_attr "alternative" "2,3")
14642 (if_then_else (match_operand:MODEF 3 "div_operator")
14643 (const_string "ssediv")
14644 (const_string "sseadd"))
14645 (if_then_else (match_operand:MODEF 3 "div_operator")
14646 (const_string "fdiv")
14647 (const_string "fop"))))
14648 (set_attr "isa" "*,*,noavx,avx")
14649 (set_attr "prefix" "orig,orig,orig,vex")
14650 (set_attr "mode" "<MODE>")
14651 (set (attr "enabled")
14652 (if_then_else
14653 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14654 (if_then_else
14655 (eq_attr "alternative" "0,1")
14656 (symbol_ref "TARGET_MIX_SSE_I387
14657 && X87_ENABLE_ARITH (<MODE>mode)")
14658 (const_string "*"))
14659 (if_then_else
14660 (eq_attr "alternative" "0,1")
14661 (symbol_ref "true")
14662 (symbol_ref "false"))))])
14663
14664 (define_insn "*fop_<X87MODEF:mode>_2_i387"
14665 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14666 (match_operator:X87MODEF 3 "binary_fp_operator"
14667 [(float:X87MODEF
14668 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14669 (match_operand:X87MODEF 2 "register_operand" "0")]))]
14670 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14671 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14672 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14673 || optimize_function_for_size_p (cfun))"
14674 "* return output_387_binary_op (insn, operands);"
14675 [(set (attr "type")
14676 (cond [(match_operand:X87MODEF 3 "mult_operator")
14677 (const_string "fmul")
14678 (match_operand:X87MODEF 3 "div_operator")
14679 (const_string "fdiv")
14680 ]
14681 (const_string "fop")))
14682 (set_attr "fp_int_src" "true")
14683 (set_attr "mode" "<SWI24:MODE>")])
14684
14685 (define_insn "*fop_<X87MODEF:mode>_3_i387"
14686 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14687 (match_operator:X87MODEF 3 "binary_fp_operator"
14688 [(match_operand:X87MODEF 1 "register_operand" "0")
14689 (float:X87MODEF
14690 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14691 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14692 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14693 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14694 || optimize_function_for_size_p (cfun))"
14695 "* return output_387_binary_op (insn, operands);"
14696 [(set (attr "type")
14697 (cond [(match_operand:X87MODEF 3 "mult_operator")
14698 (const_string "fmul")
14699 (match_operand:X87MODEF 3 "div_operator")
14700 (const_string "fdiv")
14701 ]
14702 (const_string "fop")))
14703 (set_attr "fp_int_src" "true")
14704 (set_attr "mode" "<MODE>")])
14705
14706 (define_insn "*fop_xf_4_i387"
14707 [(set (match_operand:XF 0 "register_operand" "=f,f")
14708 (match_operator:XF 3 "binary_fp_operator"
14709 [(float_extend:XF
14710 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14711 (match_operand:XF 2 "register_operand" "0,f")]))]
14712 "TARGET_80387"
14713 "* return output_387_binary_op (insn, operands);"
14714 [(set (attr "type")
14715 (cond [(match_operand:XF 3 "mult_operator")
14716 (const_string "fmul")
14717 (match_operand:XF 3 "div_operator")
14718 (const_string "fdiv")
14719 ]
14720 (const_string "fop")))
14721 (set_attr "mode" "<MODE>")])
14722
14723 (define_insn "*fop_df_4_i387"
14724 [(set (match_operand:DF 0 "register_operand" "=f,f")
14725 (match_operator:DF 3 "binary_fp_operator"
14726 [(float_extend:DF
14727 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14728 (match_operand:DF 2 "register_operand" "0,f")]))]
14729 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14730 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14731 "* return output_387_binary_op (insn, operands);"
14732 [(set (attr "type")
14733 (cond [(match_operand:DF 3 "mult_operator")
14734 (const_string "fmul")
14735 (match_operand:DF 3 "div_operator")
14736 (const_string "fdiv")
14737 ]
14738 (const_string "fop")))
14739 (set_attr "mode" "SF")])
14740
14741 (define_insn "*fop_xf_5_i387"
14742 [(set (match_operand:XF 0 "register_operand" "=f,f")
14743 (match_operator:XF 3 "binary_fp_operator"
14744 [(match_operand:XF 1 "register_operand" "0,f")
14745 (float_extend:XF
14746 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14747 "TARGET_80387"
14748 "* return output_387_binary_op (insn, operands);"
14749 [(set (attr "type")
14750 (cond [(match_operand:XF 3 "mult_operator")
14751 (const_string "fmul")
14752 (match_operand:XF 3 "div_operator")
14753 (const_string "fdiv")
14754 ]
14755 (const_string "fop")))
14756 (set_attr "mode" "<MODE>")])
14757
14758 (define_insn "*fop_df_5_i387"
14759 [(set (match_operand:DF 0 "register_operand" "=f,f")
14760 (match_operator:DF 3 "binary_fp_operator"
14761 [(match_operand:DF 1 "register_operand" "0,f")
14762 (float_extend:DF
14763 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14764 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14765 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14766 "* return output_387_binary_op (insn, operands);"
14767 [(set (attr "type")
14768 (cond [(match_operand:DF 3 "mult_operator")
14769 (const_string "fmul")
14770 (match_operand:DF 3 "div_operator")
14771 (const_string "fdiv")
14772 ]
14773 (const_string "fop")))
14774 (set_attr "mode" "SF")])
14775
14776 (define_insn "*fop_xf_6_i387"
14777 [(set (match_operand:XF 0 "register_operand" "=f,f")
14778 (match_operator:XF 3 "binary_fp_operator"
14779 [(float_extend:XF
14780 (match_operand:MODEF 1 "register_operand" "0,f"))
14781 (float_extend:XF
14782 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14783 "TARGET_80387"
14784 "* return output_387_binary_op (insn, operands);"
14785 [(set (attr "type")
14786 (cond [(match_operand:XF 3 "mult_operator")
14787 (const_string "fmul")
14788 (match_operand:XF 3 "div_operator")
14789 (const_string "fdiv")
14790 ]
14791 (const_string "fop")))
14792 (set_attr "mode" "<MODE>")])
14793
14794 (define_insn "*fop_df_6_i387"
14795 [(set (match_operand:DF 0 "register_operand" "=f,f")
14796 (match_operator:DF 3 "binary_fp_operator"
14797 [(float_extend:DF
14798 (match_operand:SF 1 "register_operand" "0,f"))
14799 (float_extend:DF
14800 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14801 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14802 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14803 "* return output_387_binary_op (insn, operands);"
14804 [(set (attr "type")
14805 (cond [(match_operand:DF 3 "mult_operator")
14806 (const_string "fmul")
14807 (match_operand:DF 3 "div_operator")
14808 (const_string "fdiv")
14809 ]
14810 (const_string "fop")))
14811 (set_attr "mode" "SF")])
14812 \f
14813 ;; FPU special functions.
14814
14815 ;; This pattern implements a no-op XFmode truncation for
14816 ;; all fancy i386 XFmode math functions.
14817
14818 (define_insn "truncxf<mode>2_i387_noop_unspec"
14819 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
14820 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14821 UNSPEC_TRUNC_NOOP))]
14822 "TARGET_USE_FANCY_MATH_387"
14823 "* return output_387_reg_move (insn, operands);"
14824 [(set_attr "type" "fmov")
14825 (set_attr "mode" "<MODE>")])
14826
14827 (define_insn "sqrtxf2"
14828 [(set (match_operand:XF 0 "register_operand" "=f")
14829 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14830 "TARGET_USE_FANCY_MATH_387"
14831 "fsqrt"
14832 [(set_attr "type" "fpspc")
14833 (set_attr "mode" "XF")
14834 (set_attr "athlon_decode" "direct")
14835 (set_attr "amdfam10_decode" "direct")
14836 (set_attr "bdver1_decode" "direct")])
14837
14838 (define_insn "*rsqrtsf2_sse"
14839 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
14840 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
14841 UNSPEC_RSQRT))]
14842 "TARGET_SSE && TARGET_SSE_MATH"
14843 "@
14844 %vrsqrtss\t{%d1, %0|%0, %d1}
14845 %vrsqrtss\t{%d1, %0|%0, %d1}
14846 %vrsqrtss\t{%1, %d0|%d0, %1}"
14847 [(set_attr "type" "sse")
14848 (set_attr "atom_sse_attr" "rcp")
14849 (set_attr "btver2_sse_attr" "rcp")
14850 (set_attr "prefix" "maybe_vex")
14851 (set_attr "mode" "SF")
14852 (set (attr "preferred_for_speed")
14853 (cond [(eq_attr "alternative" "1")
14854 (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14855 (eq_attr "alternative" "2")
14856 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14857 ]
14858 (symbol_ref "true")))])
14859
14860 (define_expand "rsqrtsf2"
14861 [(set (match_operand:SF 0 "register_operand")
14862 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14863 UNSPEC_RSQRT))]
14864 "TARGET_SSE && TARGET_SSE_MATH"
14865 {
14866 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14867 DONE;
14868 })
14869
14870 (define_insn "*sqrt<mode>2_sse"
14871 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
14872 (sqrt:MODEF
14873 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
14874 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14875 "@
14876 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
14877 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
14878 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14879 [(set_attr "type" "sse")
14880 (set_attr "atom_sse_attr" "sqrt")
14881 (set_attr "btver2_sse_attr" "sqrt")
14882 (set_attr "prefix" "maybe_vex")
14883 (set_attr "mode" "<MODE>")
14884 (set (attr "preferred_for_speed")
14885 (cond [(eq_attr "alternative" "1")
14886 (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14887 (eq_attr "alternative" "2")
14888 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14889 ]
14890 (symbol_ref "true")))])
14891
14892 (define_expand "sqrt<mode>2"
14893 [(set (match_operand:MODEF 0 "register_operand")
14894 (sqrt:MODEF
14895 (match_operand:MODEF 1 "nonimmediate_operand")))]
14896 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14897 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14898 {
14899 if (<MODE>mode == SFmode
14900 && TARGET_SSE && TARGET_SSE_MATH
14901 && TARGET_RECIP_SQRT
14902 && !optimize_function_for_size_p (cfun)
14903 && flag_finite_math_only && !flag_trapping_math
14904 && flag_unsafe_math_optimizations)
14905 {
14906 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14907 DONE;
14908 }
14909
14910 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14911 {
14912 rtx op0 = gen_reg_rtx (XFmode);
14913 rtx op1 = gen_reg_rtx (XFmode);
14914
14915 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14916 emit_insn (gen_sqrtxf2 (op0, op1));
14917 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14918 DONE;
14919 }
14920 })
14921
14922 (define_expand "hypot<mode>3"
14923 [(use (match_operand:MODEF 0 "register_operand"))
14924 (use (match_operand:MODEF 1 "general_operand"))
14925 (use (match_operand:MODEF 2 "general_operand"))]
14926 "TARGET_USE_FANCY_MATH_387
14927 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14928 || TARGET_MIX_SSE_I387)
14929 && flag_finite_math_only
14930 && flag_unsafe_math_optimizations"
14931 {
14932 rtx op0 = gen_reg_rtx (XFmode);
14933 rtx op1 = gen_reg_rtx (XFmode);
14934 rtx op2 = gen_reg_rtx (XFmode);
14935
14936 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14937 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14938
14939 emit_insn (gen_mulxf3 (op1, op1, op1));
14940 emit_insn (gen_mulxf3 (op2, op2, op2));
14941 emit_insn (gen_addxf3 (op0, op2, op1));
14942 emit_insn (gen_sqrtxf2 (op0, op0));
14943
14944 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
14945 DONE;
14946 })
14947
14948 (define_insn "x86_fnstsw_1"
14949 [(set (match_operand:HI 0 "register_operand" "=a")
14950 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
14951 "TARGET_80387"
14952 "fnstsw\t%0"
14953 [(set_attr "length" "2")
14954 (set_attr "mode" "SI")
14955 (set_attr "unit" "i387")])
14956
14957 (define_insn "fpremxf4_i387"
14958 [(set (match_operand:XF 0 "register_operand" "=f")
14959 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14960 (match_operand:XF 3 "register_operand" "1")]
14961 UNSPEC_FPREM_F))
14962 (set (match_operand:XF 1 "register_operand" "=f")
14963 (unspec:XF [(match_dup 2) (match_dup 3)]
14964 UNSPEC_FPREM_U))
14965 (set (reg:CCFP FPSR_REG)
14966 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14967 UNSPEC_C2_FLAG))]
14968 "TARGET_USE_FANCY_MATH_387
14969 && flag_finite_math_only"
14970 "fprem"
14971 [(set_attr "type" "fpspc")
14972 (set_attr "znver1_decode" "vector")
14973 (set_attr "mode" "XF")])
14974
14975 (define_expand "fmodxf3"
14976 [(use (match_operand:XF 0 "register_operand"))
14977 (use (match_operand:XF 1 "general_operand"))
14978 (use (match_operand:XF 2 "general_operand"))]
14979 "TARGET_USE_FANCY_MATH_387
14980 && flag_finite_math_only"
14981 {
14982 rtx_code_label *label = gen_label_rtx ();
14983
14984 rtx op1 = gen_reg_rtx (XFmode);
14985 rtx op2 = gen_reg_rtx (XFmode);
14986
14987 emit_move_insn (op2, operands[2]);
14988 emit_move_insn (op1, operands[1]);
14989
14990 emit_label (label);
14991 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14992 ix86_emit_fp_unordered_jump (label);
14993 LABEL_NUSES (label) = 1;
14994
14995 emit_move_insn (operands[0], op1);
14996 DONE;
14997 })
14998
14999 (define_expand "fmod<mode>3"
15000 [(use (match_operand:MODEF 0 "register_operand"))
15001 (use (match_operand:MODEF 1 "general_operand"))
15002 (use (match_operand:MODEF 2 "general_operand"))]
15003 "TARGET_USE_FANCY_MATH_387
15004 && flag_finite_math_only"
15005 {
15006 rtx (*gen_truncxf) (rtx, rtx);
15007
15008 rtx_code_label *label = gen_label_rtx ();
15009
15010 rtx op1 = gen_reg_rtx (XFmode);
15011 rtx op2 = gen_reg_rtx (XFmode);
15012
15013 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15014 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15015
15016 emit_label (label);
15017 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15018 ix86_emit_fp_unordered_jump (label);
15019 LABEL_NUSES (label) = 1;
15020
15021 /* Truncate the result properly for strict SSE math. */
15022 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15023 && !TARGET_MIX_SSE_I387)
15024 gen_truncxf = gen_truncxf<mode>2;
15025 else
15026 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15027
15028 emit_insn (gen_truncxf (operands[0], op1));
15029 DONE;
15030 })
15031
15032 (define_insn "fprem1xf4_i387"
15033 [(set (match_operand:XF 0 "register_operand" "=f")
15034 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15035 (match_operand:XF 3 "register_operand" "1")]
15036 UNSPEC_FPREM1_F))
15037 (set (match_operand:XF 1 "register_operand" "=f")
15038 (unspec:XF [(match_dup 2) (match_dup 3)]
15039 UNSPEC_FPREM1_U))
15040 (set (reg:CCFP FPSR_REG)
15041 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15042 UNSPEC_C2_FLAG))]
15043 "TARGET_USE_FANCY_MATH_387
15044 && flag_finite_math_only"
15045 "fprem1"
15046 [(set_attr "type" "fpspc")
15047 (set_attr "znver1_decode" "vector")
15048 (set_attr "mode" "XF")])
15049
15050 (define_expand "remainderxf3"
15051 [(use (match_operand:XF 0 "register_operand"))
15052 (use (match_operand:XF 1 "general_operand"))
15053 (use (match_operand:XF 2 "general_operand"))]
15054 "TARGET_USE_FANCY_MATH_387
15055 && flag_finite_math_only"
15056 {
15057 rtx_code_label *label = gen_label_rtx ();
15058
15059 rtx op1 = gen_reg_rtx (XFmode);
15060 rtx op2 = gen_reg_rtx (XFmode);
15061
15062 emit_move_insn (op2, operands[2]);
15063 emit_move_insn (op1, operands[1]);
15064
15065 emit_label (label);
15066 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15067 ix86_emit_fp_unordered_jump (label);
15068 LABEL_NUSES (label) = 1;
15069
15070 emit_move_insn (operands[0], op1);
15071 DONE;
15072 })
15073
15074 (define_expand "remainder<mode>3"
15075 [(use (match_operand:MODEF 0 "register_operand"))
15076 (use (match_operand:MODEF 1 "general_operand"))
15077 (use (match_operand:MODEF 2 "general_operand"))]
15078 "TARGET_USE_FANCY_MATH_387
15079 && flag_finite_math_only"
15080 {
15081 rtx (*gen_truncxf) (rtx, rtx);
15082
15083 rtx_code_label *label = gen_label_rtx ();
15084
15085 rtx op1 = gen_reg_rtx (XFmode);
15086 rtx op2 = gen_reg_rtx (XFmode);
15087
15088 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15089 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15090
15091 emit_label (label);
15092
15093 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15094 ix86_emit_fp_unordered_jump (label);
15095 LABEL_NUSES (label) = 1;
15096
15097 /* Truncate the result properly for strict SSE math. */
15098 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15099 && !TARGET_MIX_SSE_I387)
15100 gen_truncxf = gen_truncxf<mode>2;
15101 else
15102 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15103
15104 emit_insn (gen_truncxf (operands[0], op1));
15105 DONE;
15106 })
15107
15108 (define_int_iterator SINCOS
15109 [UNSPEC_SIN
15110 UNSPEC_COS])
15111
15112 (define_int_attr sincos
15113 [(UNSPEC_SIN "sin")
15114 (UNSPEC_COS "cos")])
15115
15116 (define_insn "<sincos>xf2"
15117 [(set (match_operand:XF 0 "register_operand" "=f")
15118 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15119 SINCOS))]
15120 "TARGET_USE_FANCY_MATH_387
15121 && flag_unsafe_math_optimizations"
15122 "f<sincos>"
15123 [(set_attr "type" "fpspc")
15124 (set_attr "znver1_decode" "vector")
15125 (set_attr "mode" "XF")])
15126
15127 (define_expand "<sincos><mode>2"
15128 [(set (match_operand:MODEF 0 "register_operand")
15129 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
15130 SINCOS))]
15131 "TARGET_USE_FANCY_MATH_387
15132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15133 || TARGET_MIX_SSE_I387)
15134 && flag_unsafe_math_optimizations"
15135 {
15136 rtx op0 = gen_reg_rtx (XFmode);
15137 rtx op1 = gen_reg_rtx (XFmode);
15138
15139 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15140 emit_insn (gen_<sincos>xf2 (op0, op1));
15141 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15142 DONE;
15143 })
15144
15145 (define_insn "sincosxf3"
15146 [(set (match_operand:XF 0 "register_operand" "=f")
15147 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15148 UNSPEC_SINCOS_COS))
15149 (set (match_operand:XF 1 "register_operand" "=f")
15150 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15151 "TARGET_USE_FANCY_MATH_387
15152 && flag_unsafe_math_optimizations"
15153 "fsincos"
15154 [(set_attr "type" "fpspc")
15155 (set_attr "znver1_decode" "vector")
15156 (set_attr "mode" "XF")])
15157
15158 (define_expand "sincos<mode>3"
15159 [(use (match_operand:MODEF 0 "register_operand"))
15160 (use (match_operand:MODEF 1 "register_operand"))
15161 (use (match_operand:MODEF 2 "general_operand"))]
15162 "TARGET_USE_FANCY_MATH_387
15163 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15164 || TARGET_MIX_SSE_I387)
15165 && flag_unsafe_math_optimizations"
15166 {
15167 rtx op0 = gen_reg_rtx (XFmode);
15168 rtx op1 = gen_reg_rtx (XFmode);
15169 rtx op2 = gen_reg_rtx (XFmode);
15170
15171 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15172 emit_insn (gen_sincosxf3 (op0, op1, op2));
15173 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15174 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
15175 DONE;
15176 })
15177
15178 (define_insn "fptanxf4_i387"
15179 [(set (match_operand:SF 0 "register_operand" "=f")
15180 (match_operand:SF 3 "const1_operand"))
15181 (set (match_operand:XF 1 "register_operand" "=f")
15182 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15183 UNSPEC_TAN))]
15184 "TARGET_USE_FANCY_MATH_387
15185 && flag_unsafe_math_optimizations"
15186 "fptan"
15187 [(set_attr "type" "fpspc")
15188 (set_attr "znver1_decode" "vector")
15189 (set_attr "mode" "XF")])
15190
15191 (define_expand "tanxf2"
15192 [(use (match_operand:XF 0 "register_operand"))
15193 (use (match_operand:XF 1 "register_operand"))]
15194 "TARGET_USE_FANCY_MATH_387
15195 && flag_unsafe_math_optimizations"
15196 {
15197 rtx one = gen_reg_rtx (SFmode);
15198 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
15199 CONST1_RTX (SFmode)));
15200 DONE;
15201 })
15202
15203 (define_expand "tan<mode>2"
15204 [(use (match_operand:MODEF 0 "register_operand"))
15205 (use (match_operand:MODEF 1 "general_operand"))]
15206 "TARGET_USE_FANCY_MATH_387
15207 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15208 || TARGET_MIX_SSE_I387)
15209 && flag_unsafe_math_optimizations"
15210 {
15211 rtx op0 = gen_reg_rtx (XFmode);
15212 rtx op1 = gen_reg_rtx (XFmode);
15213
15214 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15215 emit_insn (gen_tanxf2 (op0, op1));
15216 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15217 DONE;
15218 })
15219
15220 (define_insn "atan2xf3"
15221 [(set (match_operand:XF 0 "register_operand" "=f")
15222 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15223 (match_operand:XF 2 "register_operand" "f")]
15224 UNSPEC_FPATAN))
15225 (clobber (match_scratch:XF 3 "=2"))]
15226 "TARGET_USE_FANCY_MATH_387
15227 && flag_unsafe_math_optimizations"
15228 "fpatan"
15229 [(set_attr "type" "fpspc")
15230 (set_attr "znver1_decode" "vector")
15231 (set_attr "mode" "XF")])
15232
15233 (define_expand "atan2<mode>3"
15234 [(use (match_operand:MODEF 0 "register_operand"))
15235 (use (match_operand:MODEF 1 "general_operand"))
15236 (use (match_operand:MODEF 2 "general_operand"))]
15237 "TARGET_USE_FANCY_MATH_387
15238 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15239 || TARGET_MIX_SSE_I387)
15240 && flag_unsafe_math_optimizations"
15241 {
15242 rtx op0 = gen_reg_rtx (XFmode);
15243 rtx op1 = gen_reg_rtx (XFmode);
15244 rtx op2 = gen_reg_rtx (XFmode);
15245
15246 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15247 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15248
15249 emit_insn (gen_atan2xf3 (op0, op2, op1));
15250 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15251 DONE;
15252 })
15253
15254 (define_expand "atanxf2"
15255 [(parallel [(set (match_operand:XF 0 "register_operand")
15256 (unspec:XF [(match_dup 2)
15257 (match_operand:XF 1 "register_operand")]
15258 UNSPEC_FPATAN))
15259 (clobber (match_scratch:XF 3))])]
15260 "TARGET_USE_FANCY_MATH_387
15261 && flag_unsafe_math_optimizations"
15262 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15263
15264 (define_expand "atan<mode>2"
15265 [(use (match_operand:MODEF 0 "register_operand"))
15266 (use (match_operand:MODEF 1 "general_operand"))]
15267 "TARGET_USE_FANCY_MATH_387
15268 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15269 || TARGET_MIX_SSE_I387)
15270 && flag_unsafe_math_optimizations"
15271 {
15272 rtx op0 = gen_reg_rtx (XFmode);
15273 rtx op1 = gen_reg_rtx (XFmode);
15274
15275 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15276 emit_insn (gen_atanxf2 (op0, op1));
15277 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15278 DONE;
15279 })
15280
15281 (define_expand "asinxf2"
15282 [(set (match_dup 2)
15283 (mult:XF (match_operand:XF 1 "register_operand")
15284 (match_dup 1)))
15285 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15286 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15287 (parallel [(set (match_operand:XF 0 "register_operand")
15288 (unspec:XF [(match_dup 5) (match_dup 1)]
15289 UNSPEC_FPATAN))
15290 (clobber (match_scratch:XF 6))])]
15291 "TARGET_USE_FANCY_MATH_387
15292 && flag_unsafe_math_optimizations"
15293 {
15294 int i;
15295
15296 for (i = 2; i < 6; i++)
15297 operands[i] = gen_reg_rtx (XFmode);
15298
15299 emit_move_insn (operands[3], CONST1_RTX (XFmode));
15300 })
15301
15302 (define_expand "asin<mode>2"
15303 [(use (match_operand:MODEF 0 "register_operand"))
15304 (use (match_operand:MODEF 1 "general_operand"))]
15305 "TARGET_USE_FANCY_MATH_387
15306 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15307 || TARGET_MIX_SSE_I387)
15308 && flag_unsafe_math_optimizations"
15309 {
15310 rtx op0 = gen_reg_rtx (XFmode);
15311 rtx op1 = gen_reg_rtx (XFmode);
15312
15313 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15314 emit_insn (gen_asinxf2 (op0, op1));
15315 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15316 DONE;
15317 })
15318
15319 (define_expand "acosxf2"
15320 [(set (match_dup 2)
15321 (mult:XF (match_operand:XF 1 "register_operand")
15322 (match_dup 1)))
15323 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15324 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15325 (parallel [(set (match_operand:XF 0 "register_operand")
15326 (unspec:XF [(match_dup 1) (match_dup 5)]
15327 UNSPEC_FPATAN))
15328 (clobber (match_scratch:XF 6))])]
15329 "TARGET_USE_FANCY_MATH_387
15330 && flag_unsafe_math_optimizations"
15331 {
15332 int i;
15333
15334 for (i = 2; i < 6; i++)
15335 operands[i] = gen_reg_rtx (XFmode);
15336
15337 emit_move_insn (operands[3], CONST1_RTX (XFmode));
15338 })
15339
15340 (define_expand "acos<mode>2"
15341 [(use (match_operand:MODEF 0 "register_operand"))
15342 (use (match_operand:MODEF 1 "general_operand"))]
15343 "TARGET_USE_FANCY_MATH_387
15344 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15345 || TARGET_MIX_SSE_I387)
15346 && flag_unsafe_math_optimizations"
15347 {
15348 rtx op0 = gen_reg_rtx (XFmode);
15349 rtx op1 = gen_reg_rtx (XFmode);
15350
15351 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15352 emit_insn (gen_acosxf2 (op0, op1));
15353 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15354 DONE;
15355 })
15356
15357 (define_expand "sinhxf2"
15358 [(use (match_operand:XF 0 "register_operand"))
15359 (use (match_operand:XF 1 "register_operand"))]
15360 "TARGET_USE_FANCY_MATH_387
15361 && flag_finite_math_only
15362 && flag_unsafe_math_optimizations"
15363 {
15364 ix86_emit_i387_sinh (operands[0], operands[1]);
15365 DONE;
15366 })
15367
15368 (define_expand "sinh<mode>2"
15369 [(use (match_operand:MODEF 0 "register_operand"))
15370 (use (match_operand:MODEF 1 "general_operand"))]
15371 "TARGET_USE_FANCY_MATH_387
15372 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15373 || TARGET_MIX_SSE_I387)
15374 && flag_finite_math_only
15375 && flag_unsafe_math_optimizations"
15376 {
15377 rtx op0 = gen_reg_rtx (XFmode);
15378 rtx op1 = gen_reg_rtx (XFmode);
15379
15380 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15381 emit_insn (gen_sinhxf2 (op0, op1));
15382 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15383 DONE;
15384 })
15385
15386 (define_expand "coshxf2"
15387 [(use (match_operand:XF 0 "register_operand"))
15388 (use (match_operand:XF 1 "register_operand"))]
15389 "TARGET_USE_FANCY_MATH_387
15390 && flag_unsafe_math_optimizations"
15391 {
15392 ix86_emit_i387_cosh (operands[0], operands[1]);
15393 DONE;
15394 })
15395
15396 (define_expand "cosh<mode>2"
15397 [(use (match_operand:MODEF 0 "register_operand"))
15398 (use (match_operand:MODEF 1 "general_operand"))]
15399 "TARGET_USE_FANCY_MATH_387
15400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15401 || TARGET_MIX_SSE_I387)
15402 && flag_unsafe_math_optimizations"
15403 {
15404 rtx op0 = gen_reg_rtx (XFmode);
15405 rtx op1 = gen_reg_rtx (XFmode);
15406
15407 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15408 emit_insn (gen_coshxf2 (op0, op1));
15409 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15410 DONE;
15411 })
15412
15413 (define_expand "tanhxf2"
15414 [(use (match_operand:XF 0 "register_operand"))
15415 (use (match_operand:XF 1 "register_operand"))]
15416 "TARGET_USE_FANCY_MATH_387
15417 && flag_unsafe_math_optimizations"
15418 {
15419 ix86_emit_i387_tanh (operands[0], operands[1]);
15420 DONE;
15421 })
15422
15423 (define_expand "tanh<mode>2"
15424 [(use (match_operand:MODEF 0 "register_operand"))
15425 (use (match_operand:MODEF 1 "general_operand"))]
15426 "TARGET_USE_FANCY_MATH_387
15427 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15428 || TARGET_MIX_SSE_I387)
15429 && flag_unsafe_math_optimizations"
15430 {
15431 rtx op0 = gen_reg_rtx (XFmode);
15432 rtx op1 = gen_reg_rtx (XFmode);
15433
15434 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15435 emit_insn (gen_tanhxf2 (op0, op1));
15436 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15437 DONE;
15438 })
15439
15440 (define_expand "asinhxf2"
15441 [(use (match_operand:XF 0 "register_operand"))
15442 (use (match_operand:XF 1 "register_operand"))]
15443 "TARGET_USE_FANCY_MATH_387
15444 && flag_finite_math_only
15445 && flag_unsafe_math_optimizations"
15446 {
15447 ix86_emit_i387_asinh (operands[0], operands[1]);
15448 DONE;
15449 })
15450
15451 (define_expand "asinh<mode>2"
15452 [(use (match_operand:MODEF 0 "register_operand"))
15453 (use (match_operand:MODEF 1 "general_operand"))]
15454 "TARGET_USE_FANCY_MATH_387
15455 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15456 || TARGET_MIX_SSE_I387)
15457 && flag_finite_math_only
15458 && flag_unsafe_math_optimizations"
15459 {
15460 rtx op0 = gen_reg_rtx (XFmode);
15461 rtx op1 = gen_reg_rtx (XFmode);
15462
15463 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15464 emit_insn (gen_asinhxf2 (op0, op1));
15465 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15466 DONE;
15467 })
15468
15469 (define_expand "acoshxf2"
15470 [(use (match_operand:XF 0 "register_operand"))
15471 (use (match_operand:XF 1 "register_operand"))]
15472 "TARGET_USE_FANCY_MATH_387
15473 && flag_unsafe_math_optimizations"
15474 {
15475 ix86_emit_i387_acosh (operands[0], operands[1]);
15476 DONE;
15477 })
15478
15479 (define_expand "acosh<mode>2"
15480 [(use (match_operand:MODEF 0 "register_operand"))
15481 (use (match_operand:MODEF 1 "general_operand"))]
15482 "TARGET_USE_FANCY_MATH_387
15483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15484 || TARGET_MIX_SSE_I387)
15485 && flag_unsafe_math_optimizations"
15486 {
15487 rtx op0 = gen_reg_rtx (XFmode);
15488 rtx op1 = gen_reg_rtx (XFmode);
15489
15490 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15491 emit_insn (gen_acoshxf2 (op0, op1));
15492 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15493 DONE;
15494 })
15495
15496 (define_expand "atanhxf2"
15497 [(use (match_operand:XF 0 "register_operand"))
15498 (use (match_operand:XF 1 "register_operand"))]
15499 "TARGET_USE_FANCY_MATH_387
15500 && flag_unsafe_math_optimizations"
15501 {
15502 ix86_emit_i387_atanh (operands[0], operands[1]);
15503 DONE;
15504 })
15505
15506 (define_expand "atanh<mode>2"
15507 [(use (match_operand:MODEF 0 "register_operand"))
15508 (use (match_operand:MODEF 1 "general_operand"))]
15509 "TARGET_USE_FANCY_MATH_387
15510 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15511 || TARGET_MIX_SSE_I387)
15512 && flag_unsafe_math_optimizations"
15513 {
15514 rtx op0 = gen_reg_rtx (XFmode);
15515 rtx op1 = gen_reg_rtx (XFmode);
15516
15517 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15518 emit_insn (gen_atanhxf2 (op0, op1));
15519 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15520 DONE;
15521 })
15522
15523 (define_insn "fyl2xxf3_i387"
15524 [(set (match_operand:XF 0 "register_operand" "=f")
15525 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15526 (match_operand:XF 2 "register_operand" "f")]
15527 UNSPEC_FYL2X))
15528 (clobber (match_scratch:XF 3 "=2"))]
15529 "TARGET_USE_FANCY_MATH_387
15530 && flag_unsafe_math_optimizations"
15531 "fyl2x"
15532 [(set_attr "type" "fpspc")
15533 (set_attr "znver1_decode" "vector")
15534 (set_attr "mode" "XF")])
15535
15536 (define_expand "logxf2"
15537 [(parallel [(set (match_operand:XF 0 "register_operand")
15538 (unspec:XF [(match_operand:XF 1 "register_operand")
15539 (match_dup 2)] UNSPEC_FYL2X))
15540 (clobber (match_scratch:XF 3))])]
15541 "TARGET_USE_FANCY_MATH_387
15542 && flag_unsafe_math_optimizations"
15543 {
15544 operands[2]
15545 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
15546 })
15547
15548 (define_expand "log<mode>2"
15549 [(use (match_operand:MODEF 0 "register_operand"))
15550 (use (match_operand:MODEF 1 "general_operand"))]
15551 "TARGET_USE_FANCY_MATH_387
15552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15553 || TARGET_MIX_SSE_I387)
15554 && flag_unsafe_math_optimizations"
15555 {
15556 rtx op0 = gen_reg_rtx (XFmode);
15557 rtx op1 = gen_reg_rtx (XFmode);
15558
15559 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15560 emit_insn (gen_logxf2 (op0, op1));
15561 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15562 DONE;
15563 })
15564
15565 (define_expand "log10xf2"
15566 [(parallel [(set (match_operand:XF 0 "register_operand")
15567 (unspec:XF [(match_operand:XF 1 "register_operand")
15568 (match_dup 2)] UNSPEC_FYL2X))
15569 (clobber (match_scratch:XF 3))])]
15570 "TARGET_USE_FANCY_MATH_387
15571 && flag_unsafe_math_optimizations"
15572 {
15573 operands[2]
15574 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
15575 })
15576
15577 (define_expand "log10<mode>2"
15578 [(use (match_operand:MODEF 0 "register_operand"))
15579 (use (match_operand:MODEF 1 "general_operand"))]
15580 "TARGET_USE_FANCY_MATH_387
15581 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15582 || TARGET_MIX_SSE_I387)
15583 && flag_unsafe_math_optimizations"
15584 {
15585 rtx op0 = gen_reg_rtx (XFmode);
15586 rtx op1 = gen_reg_rtx (XFmode);
15587
15588 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15589 emit_insn (gen_log10xf2 (op0, op1));
15590 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15591 DONE;
15592 })
15593
15594 (define_expand "log2xf2"
15595 [(parallel [(set (match_operand:XF 0 "register_operand")
15596 (unspec:XF [(match_operand:XF 1 "register_operand")
15597 (match_dup 2)] UNSPEC_FYL2X))
15598 (clobber (match_scratch:XF 3))])]
15599 "TARGET_USE_FANCY_MATH_387
15600 && flag_unsafe_math_optimizations"
15601 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15602
15603 (define_expand "log2<mode>2"
15604 [(use (match_operand:MODEF 0 "register_operand"))
15605 (use (match_operand:MODEF 1 "general_operand"))]
15606 "TARGET_USE_FANCY_MATH_387
15607 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15608 || TARGET_MIX_SSE_I387)
15609 && flag_unsafe_math_optimizations"
15610 {
15611 rtx op0 = gen_reg_rtx (XFmode);
15612 rtx op1 = gen_reg_rtx (XFmode);
15613
15614 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15615 emit_insn (gen_log2xf2 (op0, op1));
15616 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15617 DONE;
15618 })
15619
15620 (define_insn "fyl2xp1xf3_i387"
15621 [(set (match_operand:XF 0 "register_operand" "=f")
15622 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15623 (match_operand:XF 2 "register_operand" "f")]
15624 UNSPEC_FYL2XP1))
15625 (clobber (match_scratch:XF 3 "=2"))]
15626 "TARGET_USE_FANCY_MATH_387
15627 && flag_unsafe_math_optimizations"
15628 "fyl2xp1"
15629 [(set_attr "type" "fpspc")
15630 (set_attr "znver1_decode" "vector")
15631 (set_attr "mode" "XF")])
15632
15633 (define_expand "log1pxf2"
15634 [(use (match_operand:XF 0 "register_operand"))
15635 (use (match_operand:XF 1 "register_operand"))]
15636 "TARGET_USE_FANCY_MATH_387
15637 && flag_unsafe_math_optimizations"
15638 {
15639 ix86_emit_i387_log1p (operands[0], operands[1]);
15640 DONE;
15641 })
15642
15643 (define_expand "log1p<mode>2"
15644 [(use (match_operand:MODEF 0 "register_operand"))
15645 (use (match_operand:MODEF 1 "general_operand"))]
15646 "TARGET_USE_FANCY_MATH_387
15647 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15648 || TARGET_MIX_SSE_I387)
15649 && flag_unsafe_math_optimizations"
15650 {
15651 rtx op0 = gen_reg_rtx (XFmode);
15652 rtx op1 = gen_reg_rtx (XFmode);
15653
15654 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15655 emit_insn (gen_log1pxf2 (op0, op1));
15656 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15657 DONE;
15658 })
15659
15660 (define_insn "fxtractxf3_i387"
15661 [(set (match_operand:XF 0 "register_operand" "=f")
15662 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15663 UNSPEC_XTRACT_FRACT))
15664 (set (match_operand:XF 1 "register_operand" "=f")
15665 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15666 "TARGET_USE_FANCY_MATH_387
15667 && flag_unsafe_math_optimizations"
15668 "fxtract"
15669 [(set_attr "type" "fpspc")
15670 (set_attr "znver1_decode" "vector")
15671 (set_attr "mode" "XF")])
15672
15673 (define_expand "logbxf2"
15674 [(parallel [(set (match_dup 2)
15675 (unspec:XF [(match_operand:XF 1 "register_operand")]
15676 UNSPEC_XTRACT_FRACT))
15677 (set (match_operand:XF 0 "register_operand")
15678 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15679 "TARGET_USE_FANCY_MATH_387
15680 && flag_unsafe_math_optimizations"
15681 "operands[2] = gen_reg_rtx (XFmode);")
15682
15683 (define_expand "logb<mode>2"
15684 [(use (match_operand:MODEF 0 "register_operand"))
15685 (use (match_operand:MODEF 1 "general_operand"))]
15686 "TARGET_USE_FANCY_MATH_387
15687 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15688 || TARGET_MIX_SSE_I387)
15689 && flag_unsafe_math_optimizations"
15690 {
15691 rtx op0 = gen_reg_rtx (XFmode);
15692 rtx op1 = gen_reg_rtx (XFmode);
15693
15694 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15695 emit_insn (gen_logbxf2 (op0, op1));
15696 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15697 DONE;
15698 })
15699
15700 (define_expand "ilogbxf2"
15701 [(use (match_operand:SI 0 "register_operand"))
15702 (use (match_operand:XF 1 "register_operand"))]
15703 "TARGET_USE_FANCY_MATH_387
15704 && flag_unsafe_math_optimizations"
15705 {
15706 rtx op0, op1;
15707
15708 if (optimize_insn_for_size_p ())
15709 FAIL;
15710
15711 op0 = gen_reg_rtx (XFmode);
15712 op1 = gen_reg_rtx (XFmode);
15713
15714 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15715 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15716 DONE;
15717 })
15718
15719 (define_expand "ilogb<mode>2"
15720 [(use (match_operand:SI 0 "register_operand"))
15721 (use (match_operand:MODEF 1 "general_operand"))]
15722 "TARGET_USE_FANCY_MATH_387
15723 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15724 || TARGET_MIX_SSE_I387)
15725 && flag_unsafe_math_optimizations"
15726 {
15727 rtx op0, op1, op2;
15728
15729 if (optimize_insn_for_size_p ())
15730 FAIL;
15731
15732 op0 = gen_reg_rtx (XFmode);
15733 op1 = gen_reg_rtx (XFmode);
15734 op2 = gen_reg_rtx (XFmode);
15735
15736 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
15737 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
15738 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15739 DONE;
15740 })
15741
15742 (define_insn "*f2xm1xf2_i387"
15743 [(set (match_operand:XF 0 "register_operand" "=f")
15744 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15745 UNSPEC_F2XM1))]
15746 "TARGET_USE_FANCY_MATH_387
15747 && flag_unsafe_math_optimizations"
15748 "f2xm1"
15749 [(set_attr "type" "fpspc")
15750 (set_attr "znver1_decode" "vector")
15751 (set_attr "mode" "XF")])
15752
15753 (define_insn "fscalexf4_i387"
15754 [(set (match_operand:XF 0 "register_operand" "=f")
15755 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15756 (match_operand:XF 3 "register_operand" "1")]
15757 UNSPEC_FSCALE_FRACT))
15758 (set (match_operand:XF 1 "register_operand" "=f")
15759 (unspec:XF [(match_dup 2) (match_dup 3)]
15760 UNSPEC_FSCALE_EXP))]
15761 "TARGET_USE_FANCY_MATH_387
15762 && flag_unsafe_math_optimizations"
15763 "fscale"
15764 [(set_attr "type" "fpspc")
15765 (set_attr "znver1_decode" "vector")
15766 (set_attr "mode" "XF")])
15767
15768 (define_expand "expNcorexf3"
15769 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15770 (match_operand:XF 2 "register_operand")))
15771 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15772 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15773 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15774 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15775 (parallel [(set (match_operand:XF 0 "register_operand")
15776 (unspec:XF [(match_dup 8) (match_dup 4)]
15777 UNSPEC_FSCALE_FRACT))
15778 (set (match_dup 9)
15779 (unspec:XF [(match_dup 8) (match_dup 4)]
15780 UNSPEC_FSCALE_EXP))])]
15781 "TARGET_USE_FANCY_MATH_387
15782 && flag_unsafe_math_optimizations"
15783 {
15784 int i;
15785
15786 for (i = 3; i < 10; i++)
15787 operands[i] = gen_reg_rtx (XFmode);
15788
15789 emit_move_insn (operands[7], CONST1_RTX (XFmode));
15790 })
15791
15792 (define_expand "expxf2"
15793 [(use (match_operand:XF 0 "register_operand"))
15794 (use (match_operand:XF 1 "register_operand"))]
15795 "TARGET_USE_FANCY_MATH_387
15796 && flag_unsafe_math_optimizations"
15797 {
15798 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
15799
15800 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15801 DONE;
15802 })
15803
15804 (define_expand "exp<mode>2"
15805 [(use (match_operand:MODEF 0 "register_operand"))
15806 (use (match_operand:MODEF 1 "general_operand"))]
15807 "TARGET_USE_FANCY_MATH_387
15808 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15809 || TARGET_MIX_SSE_I387)
15810 && flag_unsafe_math_optimizations"
15811 {
15812 rtx op0 = gen_reg_rtx (XFmode);
15813 rtx op1 = gen_reg_rtx (XFmode);
15814
15815 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15816 emit_insn (gen_expxf2 (op0, op1));
15817 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15818 DONE;
15819 })
15820
15821 (define_expand "exp10xf2"
15822 [(use (match_operand:XF 0 "register_operand"))
15823 (use (match_operand:XF 1 "register_operand"))]
15824 "TARGET_USE_FANCY_MATH_387
15825 && flag_unsafe_math_optimizations"
15826 {
15827 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
15828
15829 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15830 DONE;
15831 })
15832
15833 (define_expand "exp10<mode>2"
15834 [(use (match_operand:MODEF 0 "register_operand"))
15835 (use (match_operand:MODEF 1 "general_operand"))]
15836 "TARGET_USE_FANCY_MATH_387
15837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15838 || TARGET_MIX_SSE_I387)
15839 && flag_unsafe_math_optimizations"
15840 {
15841 rtx op0 = gen_reg_rtx (XFmode);
15842 rtx op1 = gen_reg_rtx (XFmode);
15843
15844 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15845 emit_insn (gen_exp10xf2 (op0, op1));
15846 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15847 DONE;
15848 })
15849
15850 (define_expand "exp2xf2"
15851 [(use (match_operand:XF 0 "register_operand"))
15852 (use (match_operand:XF 1 "register_operand"))]
15853 "TARGET_USE_FANCY_MATH_387
15854 && flag_unsafe_math_optimizations"
15855 {
15856 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
15857
15858 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15859 DONE;
15860 })
15861
15862 (define_expand "exp2<mode>2"
15863 [(use (match_operand:MODEF 0 "register_operand"))
15864 (use (match_operand:MODEF 1 "general_operand"))]
15865 "TARGET_USE_FANCY_MATH_387
15866 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15867 || TARGET_MIX_SSE_I387)
15868 && flag_unsafe_math_optimizations"
15869 {
15870 rtx op0 = gen_reg_rtx (XFmode);
15871 rtx op1 = gen_reg_rtx (XFmode);
15872
15873 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15874 emit_insn (gen_exp2xf2 (op0, op1));
15875 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15876 DONE;
15877 })
15878
15879 (define_expand "expm1xf2"
15880 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15881 (match_dup 2)))
15882 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15883 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15884 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15885 (parallel [(set (match_dup 7)
15886 (unspec:XF [(match_dup 6) (match_dup 4)]
15887 UNSPEC_FSCALE_FRACT))
15888 (set (match_dup 8)
15889 (unspec:XF [(match_dup 6) (match_dup 4)]
15890 UNSPEC_FSCALE_EXP))])
15891 (parallel [(set (match_dup 10)
15892 (unspec:XF [(match_dup 9) (match_dup 8)]
15893 UNSPEC_FSCALE_FRACT))
15894 (set (match_dup 11)
15895 (unspec:XF [(match_dup 9) (match_dup 8)]
15896 UNSPEC_FSCALE_EXP))])
15897 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
15898 (set (match_operand:XF 0 "register_operand")
15899 (plus:XF (match_dup 12) (match_dup 7)))]
15900 "TARGET_USE_FANCY_MATH_387
15901 && flag_unsafe_math_optimizations"
15902 {
15903 int i;
15904
15905 for (i = 2; i < 13; i++)
15906 operands[i] = gen_reg_rtx (XFmode);
15907
15908 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15909 emit_move_insn (operands[9], CONST1_RTX (XFmode));
15910 })
15911
15912 (define_expand "expm1<mode>2"
15913 [(use (match_operand:MODEF 0 "register_operand"))
15914 (use (match_operand:MODEF 1 "general_operand"))]
15915 "TARGET_USE_FANCY_MATH_387
15916 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15917 || TARGET_MIX_SSE_I387)
15918 && flag_unsafe_math_optimizations"
15919 {
15920 rtx op0 = gen_reg_rtx (XFmode);
15921 rtx op1 = gen_reg_rtx (XFmode);
15922
15923 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15924 emit_insn (gen_expm1xf2 (op0, op1));
15925 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15926 DONE;
15927 })
15928
15929 (define_expand "ldexpxf3"
15930 [(match_operand:XF 0 "register_operand")
15931 (match_operand:XF 1 "register_operand")
15932 (match_operand:SI 2 "register_operand")]
15933 "TARGET_USE_FANCY_MATH_387
15934 && flag_unsafe_math_optimizations"
15935 {
15936 rtx tmp1 = gen_reg_rtx (XFmode);
15937 rtx tmp2 = gen_reg_rtx (XFmode);
15938
15939 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15940 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15941 operands[1], tmp1));
15942 DONE;
15943 })
15944
15945 (define_expand "ldexp<mode>3"
15946 [(use (match_operand:MODEF 0 "register_operand"))
15947 (use (match_operand:MODEF 1 "general_operand"))
15948 (use (match_operand:SI 2 "register_operand"))]
15949 "TARGET_USE_FANCY_MATH_387
15950 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15951 || TARGET_MIX_SSE_I387)
15952 && flag_unsafe_math_optimizations"
15953 {
15954 rtx op0 = gen_reg_rtx (XFmode);
15955 rtx op1 = gen_reg_rtx (XFmode);
15956
15957 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15958 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15959 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15960 DONE;
15961 })
15962
15963 (define_expand "scalbxf3"
15964 [(parallel [(set (match_operand:XF 0 " register_operand")
15965 (unspec:XF [(match_operand:XF 1 "register_operand")
15966 (match_operand:XF 2 "register_operand")]
15967 UNSPEC_FSCALE_FRACT))
15968 (set (match_dup 3)
15969 (unspec:XF [(match_dup 1) (match_dup 2)]
15970 UNSPEC_FSCALE_EXP))])]
15971 "TARGET_USE_FANCY_MATH_387
15972 && flag_unsafe_math_optimizations"
15973 "operands[3] = gen_reg_rtx (XFmode);")
15974
15975 (define_expand "scalb<mode>3"
15976 [(use (match_operand:MODEF 0 "register_operand"))
15977 (use (match_operand:MODEF 1 "general_operand"))
15978 (use (match_operand:MODEF 2 "general_operand"))]
15979 "TARGET_USE_FANCY_MATH_387
15980 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15981 || TARGET_MIX_SSE_I387)
15982 && flag_unsafe_math_optimizations"
15983 {
15984 rtx op0 = gen_reg_rtx (XFmode);
15985 rtx op1 = gen_reg_rtx (XFmode);
15986 rtx op2 = gen_reg_rtx (XFmode);
15987
15988 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15989 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15990 emit_insn (gen_scalbxf3 (op0, op1, op2));
15991 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15992 DONE;
15993 })
15994
15995 (define_expand "significandxf2"
15996 [(parallel [(set (match_operand:XF 0 "register_operand")
15997 (unspec:XF [(match_operand:XF 1 "register_operand")]
15998 UNSPEC_XTRACT_FRACT))
15999 (set (match_dup 2)
16000 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16001 "TARGET_USE_FANCY_MATH_387
16002 && flag_unsafe_math_optimizations"
16003 "operands[2] = gen_reg_rtx (XFmode);")
16004
16005 (define_expand "significand<mode>2"
16006 [(use (match_operand:MODEF 0 "register_operand"))
16007 (use (match_operand:MODEF 1 "general_operand"))]
16008 "TARGET_USE_FANCY_MATH_387
16009 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16010 || TARGET_MIX_SSE_I387)
16011 && flag_unsafe_math_optimizations"
16012 {
16013 rtx op0 = gen_reg_rtx (XFmode);
16014 rtx op1 = gen_reg_rtx (XFmode);
16015
16016 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16017 emit_insn (gen_significandxf2 (op0, op1));
16018 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16019 DONE;
16020 })
16021 \f
16022
16023 (define_insn "sse4_1_round<mode>2"
16024 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,v")
16025 (unspec:MODEF
16026 [(match_operand:MODEF 1 "nonimmediate_operand" "0,x,m,vm")
16027 (match_operand:SI 2 "const_0_to_15_operand" "n,n,n,n")]
16028 UNSPEC_ROUND))]
16029 "TARGET_SSE4_1"
16030 "@
16031 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16032 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16033 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16034 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16035 [(set_attr "type" "ssecvt")
16036 (set_attr "prefix_extra" "1,1,1,*")
16037 (set_attr "length_immediate" "*,*,*,1")
16038 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex")
16039 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f")
16040 (set_attr "mode" "<MODE>")
16041 (set (attr "preferred_for_speed")
16042 (cond [(eq_attr "alternative" "1")
16043 (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16044 (eq_attr "alternative" "2")
16045 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16046 ]
16047 (symbol_ref "true")))])
16048
16049 (define_insn "rintxf2"
16050 [(set (match_operand:XF 0 "register_operand" "=f")
16051 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16052 UNSPEC_FRNDINT))]
16053 "TARGET_USE_FANCY_MATH_387"
16054 "frndint"
16055 [(set_attr "type" "fpspc")
16056 (set_attr "znver1_decode" "vector")
16057 (set_attr "mode" "XF")])
16058
16059 (define_expand "rint<mode>2"
16060 [(use (match_operand:MODEF 0 "register_operand"))
16061 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16062 "TARGET_USE_FANCY_MATH_387
16063 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16064 {
16065 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16066 {
16067 if (TARGET_SSE4_1)
16068 emit_insn (gen_sse4_1_round<mode>2
16069 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16070 else
16071 ix86_expand_rint (operands[0], operands[1]);
16072 }
16073 else
16074 {
16075 rtx op0 = gen_reg_rtx (XFmode);
16076 rtx op1 = gen_reg_rtx (XFmode);
16077
16078 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16079 emit_insn (gen_rintxf2 (op0, op1));
16080 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16081 }
16082 DONE;
16083 })
16084
16085 (define_expand "nearbyintxf2"
16086 [(set (match_operand:XF 0 "register_operand")
16087 (unspec:XF [(match_operand:XF 1 "register_operand")]
16088 UNSPEC_FRNDINT))]
16089 "TARGET_USE_FANCY_MATH_387
16090 && !flag_trapping_math")
16091
16092 (define_expand "nearbyint<mode>2"
16093 [(use (match_operand:MODEF 0 "register_operand"))
16094 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16095 "(TARGET_USE_FANCY_MATH_387
16096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16097 || TARGET_MIX_SSE_I387)
16098 && !flag_trapping_math)
16099 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
16100 {
16101 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
16102 emit_insn (gen_sse4_1_round<mode>2
16103 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
16104 | ROUND_NO_EXC)));
16105 else
16106 {
16107 rtx op0 = gen_reg_rtx (XFmode);
16108 rtx op1 = gen_reg_rtx (XFmode);
16109
16110 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16111 emit_insn (gen_nearbyintxf2 (op0, op1));
16112 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16113 }
16114 DONE;
16115 })
16116
16117 (define_expand "round<mode>2"
16118 [(match_operand:X87MODEF 0 "register_operand")
16119 (match_operand:X87MODEF 1 "nonimmediate_operand")]
16120 "(TARGET_USE_FANCY_MATH_387
16121 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16122 || TARGET_MIX_SSE_I387)
16123 && flag_unsafe_math_optimizations
16124 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16125 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16126 && !flag_trapping_math && !flag_rounding_math)"
16127 {
16128 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16129 && !flag_trapping_math && !flag_rounding_math)
16130 {
16131 if (TARGET_SSE4_1)
16132 {
16133 operands[1] = force_reg (<MODE>mode, operands[1]);
16134 ix86_expand_round_sse4 (operands[0], operands[1]);
16135 }
16136 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16137 ix86_expand_round (operands[0], operands[1]);
16138 else
16139 ix86_expand_rounddf_32 (operands[0], operands[1]);
16140 }
16141 else
16142 {
16143 operands[1] = force_reg (<MODE>mode, operands[1]);
16144 ix86_emit_i387_round (operands[0], operands[1]);
16145 }
16146 DONE;
16147 })
16148
16149 (define_insn "lrintxfdi2"
16150 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16151 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16152 UNSPEC_FIST))
16153 (clobber (match_scratch:XF 2 "=&f"))]
16154 "TARGET_USE_FANCY_MATH_387"
16155 "* return output_fix_trunc (insn, operands, false);"
16156 [(set_attr "type" "fpspc")
16157 (set_attr "mode" "DI")])
16158
16159 (define_insn "lrintxf<mode>2"
16160 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16161 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16162 UNSPEC_FIST))]
16163 "TARGET_USE_FANCY_MATH_387"
16164 "* return output_fix_trunc (insn, operands, false);"
16165 [(set_attr "type" "fpspc")
16166 (set_attr "mode" "<MODE>")])
16167
16168 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16169 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16170 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16171 UNSPEC_FIX_NOTRUNC))]
16172 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16173
16174 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16175 [(match_operand:SWI248x 0 "nonimmediate_operand")
16176 (match_operand:X87MODEF 1 "register_operand")]
16177 "(TARGET_USE_FANCY_MATH_387
16178 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16179 || TARGET_MIX_SSE_I387)
16180 && flag_unsafe_math_optimizations)
16181 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16182 && <SWI248x:MODE>mode != HImode
16183 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16184 && !flag_trapping_math && !flag_rounding_math)"
16185 {
16186 if (optimize_insn_for_size_p ())
16187 FAIL;
16188
16189 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16190 && <SWI248x:MODE>mode != HImode
16191 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16192 && !flag_trapping_math && !flag_rounding_math)
16193 ix86_expand_lround (operands[0], operands[1]);
16194 else
16195 ix86_emit_i387_round (operands[0], operands[1]);
16196 DONE;
16197 })
16198
16199 (define_int_iterator FRNDINT_ROUNDING
16200 [UNSPEC_FRNDINT_FLOOR
16201 UNSPEC_FRNDINT_CEIL
16202 UNSPEC_FRNDINT_TRUNC])
16203
16204 (define_int_iterator FIST_ROUNDING
16205 [UNSPEC_FIST_FLOOR
16206 UNSPEC_FIST_CEIL])
16207
16208 ;; Base name for define_insn
16209 (define_int_attr rounding_insn
16210 [(UNSPEC_FRNDINT_FLOOR "floor")
16211 (UNSPEC_FRNDINT_CEIL "ceil")
16212 (UNSPEC_FRNDINT_TRUNC "btrunc")
16213 (UNSPEC_FIST_FLOOR "floor")
16214 (UNSPEC_FIST_CEIL "ceil")])
16215
16216 (define_int_attr rounding
16217 [(UNSPEC_FRNDINT_FLOOR "floor")
16218 (UNSPEC_FRNDINT_CEIL "ceil")
16219 (UNSPEC_FRNDINT_TRUNC "trunc")
16220 (UNSPEC_FIST_FLOOR "floor")
16221 (UNSPEC_FIST_CEIL "ceil")])
16222
16223 (define_int_attr ROUNDING
16224 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16225 (UNSPEC_FRNDINT_CEIL "CEIL")
16226 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16227 (UNSPEC_FIST_FLOOR "FLOOR")
16228 (UNSPEC_FIST_CEIL "CEIL")])
16229
16230 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16231 (define_insn_and_split "frndintxf2_<rounding>"
16232 [(set (match_operand:XF 0 "register_operand")
16233 (unspec:XF [(match_operand:XF 1 "register_operand")]
16234 FRNDINT_ROUNDING))
16235 (clobber (reg:CC FLAGS_REG))]
16236 "TARGET_USE_FANCY_MATH_387
16237 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16238 && can_create_pseudo_p ()"
16239 "#"
16240 "&& 1"
16241 [(const_int 0)]
16242 {
16243 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16244
16245 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16246 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16247
16248 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
16249 operands[2], operands[3]));
16250 DONE;
16251 }
16252 [(set_attr "type" "frndint")
16253 (set_attr "i387_cw" "<rounding>")
16254 (set_attr "mode" "XF")])
16255
16256 (define_insn "frndintxf2_<rounding>_i387"
16257 [(set (match_operand:XF 0 "register_operand" "=f")
16258 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16259 FRNDINT_ROUNDING))
16260 (use (match_operand:HI 2 "memory_operand" "m"))
16261 (use (match_operand:HI 3 "memory_operand" "m"))]
16262 "TARGET_USE_FANCY_MATH_387
16263 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16264 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16265 [(set_attr "type" "frndint")
16266 (set_attr "i387_cw" "<rounding>")
16267 (set_attr "mode" "XF")])
16268
16269 (define_expand "<rounding_insn>xf2"
16270 [(parallel [(set (match_operand:XF 0 "register_operand")
16271 (unspec:XF [(match_operand:XF 1 "register_operand")]
16272 FRNDINT_ROUNDING))
16273 (clobber (reg:CC FLAGS_REG))])]
16274 "TARGET_USE_FANCY_MATH_387
16275 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16276
16277 (define_expand "<rounding_insn><mode>2"
16278 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16279 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16280 FRNDINT_ROUNDING))
16281 (clobber (reg:CC FLAGS_REG))])]
16282 "(TARGET_USE_FANCY_MATH_387
16283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16284 || TARGET_MIX_SSE_I387)
16285 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16286 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16287 && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact
16288 || !flag_trapping_math))"
16289 {
16290 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16291 && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact || !flag_trapping_math))
16292 {
16293 if (TARGET_SSE4_1)
16294 emit_insn (gen_sse4_1_round<mode>2
16295 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16296 | ROUND_NO_EXC)));
16297 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16298 {
16299 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16300 ix86_expand_floorceil (operands[0], operands[1], true);
16301 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16302 ix86_expand_floorceil (operands[0], operands[1], false);
16303 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16304 ix86_expand_trunc (operands[0], operands[1]);
16305 else
16306 gcc_unreachable ();
16307 }
16308 else
16309 {
16310 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16311 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16312 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16313 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16314 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16315 ix86_expand_truncdf_32 (operands[0], operands[1]);
16316 else
16317 gcc_unreachable ();
16318 }
16319 }
16320 else
16321 {
16322 rtx op0 = gen_reg_rtx (XFmode);
16323 rtx op1 = gen_reg_rtx (XFmode);
16324
16325 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16326 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
16327 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16328 }
16329 DONE;
16330 })
16331
16332 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16333 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16334 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16335 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16336 FIST_ROUNDING))
16337 (clobber (reg:CC FLAGS_REG))]
16338 "TARGET_USE_FANCY_MATH_387
16339 && flag_unsafe_math_optimizations
16340 && can_create_pseudo_p ()"
16341 "#"
16342 "&& 1"
16343 [(const_int 0)]
16344 {
16345 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16346
16347 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16348 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16349
16350 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16351 operands[2], operands[3]));
16352 DONE;
16353 }
16354 [(set_attr "type" "fistp")
16355 (set_attr "i387_cw" "<rounding>")
16356 (set_attr "mode" "<MODE>")])
16357
16358 (define_insn "fistdi2_<rounding>"
16359 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16360 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16361 FIST_ROUNDING))
16362 (use (match_operand:HI 2 "memory_operand" "m"))
16363 (use (match_operand:HI 3 "memory_operand" "m"))
16364 (clobber (match_scratch:XF 4 "=&f"))]
16365 "TARGET_USE_FANCY_MATH_387
16366 && flag_unsafe_math_optimizations"
16367 "* return output_fix_trunc (insn, operands, false);"
16368 [(set_attr "type" "fistp")
16369 (set_attr "i387_cw" "<rounding>")
16370 (set_attr "mode" "DI")])
16371
16372 (define_insn "fist<mode>2_<rounding>"
16373 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16374 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16375 FIST_ROUNDING))
16376 (use (match_operand:HI 2 "memory_operand" "m"))
16377 (use (match_operand:HI 3 "memory_operand" "m"))]
16378 "TARGET_USE_FANCY_MATH_387
16379 && flag_unsafe_math_optimizations"
16380 "* return output_fix_trunc (insn, operands, false);"
16381 [(set_attr "type" "fistp")
16382 (set_attr "i387_cw" "<rounding>")
16383 (set_attr "mode" "<MODE>")])
16384
16385 (define_expand "l<rounding_insn>xf<mode>2"
16386 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16387 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16388 FIST_ROUNDING))
16389 (clobber (reg:CC FLAGS_REG))])]
16390 "TARGET_USE_FANCY_MATH_387
16391 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16392 && flag_unsafe_math_optimizations")
16393
16394 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16395 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16396 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16397 FIST_ROUNDING))
16398 (clobber (reg:CC FLAGS_REG))])]
16399 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16400 && (TARGET_SSE4_1 || !flag_trapping_math)"
16401 {
16402 if (TARGET_SSE4_1)
16403 {
16404 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
16405
16406 emit_insn (gen_sse4_1_round<mode>2
16407 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
16408 | ROUND_NO_EXC)));
16409 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
16410 (operands[0], tmp));
16411 }
16412 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
16413 ix86_expand_lfloorceil (operands[0], operands[1], true);
16414 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16415 ix86_expand_lfloorceil (operands[0], operands[1], false);
16416 else
16417 gcc_unreachable ();
16418
16419 DONE;
16420 })
16421
16422 (define_insn "fxam<mode>2_i387"
16423 [(set (match_operand:HI 0 "register_operand" "=a")
16424 (unspec:HI
16425 [(match_operand:X87MODEF 1 "register_operand" "f")]
16426 UNSPEC_FXAM))]
16427 "TARGET_USE_FANCY_MATH_387"
16428 "fxam\n\tfnstsw\t%0"
16429 [(set_attr "type" "multi")
16430 (set_attr "length" "4")
16431 (set_attr "unit" "i387")
16432 (set_attr "mode" "<MODE>")])
16433
16434 (define_expand "signbittf2"
16435 [(use (match_operand:SI 0 "register_operand"))
16436 (use (match_operand:TF 1 "register_operand"))]
16437 "TARGET_SSE"
16438 {
16439 if (TARGET_SSE4_1)
16440 {
16441 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16442 rtx scratch = gen_reg_rtx (QImode);
16443
16444 emit_insn (gen_ptesttf2 (operands[1], mask));
16445 ix86_expand_setcc (scratch, NE,
16446 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16447
16448 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16449 }
16450 else
16451 {
16452 emit_insn (gen_sse_movmskps (operands[0],
16453 gen_lowpart (V4SFmode, operands[1])));
16454 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16455 }
16456 DONE;
16457 })
16458
16459 (define_expand "signbitxf2"
16460 [(use (match_operand:SI 0 "register_operand"))
16461 (use (match_operand:XF 1 "register_operand"))]
16462 "TARGET_USE_FANCY_MATH_387"
16463 {
16464 rtx scratch = gen_reg_rtx (HImode);
16465
16466 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16467 emit_insn (gen_andsi3 (operands[0],
16468 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16469 DONE;
16470 })
16471
16472 (define_insn "movmsk_df"
16473 [(set (match_operand:SI 0 "register_operand" "=r")
16474 (unspec:SI
16475 [(match_operand:DF 1 "register_operand" "x")]
16476 UNSPEC_MOVMSK))]
16477 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16478 "%vmovmskpd\t{%1, %0|%0, %1}"
16479 [(set_attr "type" "ssemov")
16480 (set_attr "prefix" "maybe_vex")
16481 (set_attr "mode" "DF")])
16482
16483 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16484 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16485 (define_expand "signbitdf2"
16486 [(use (match_operand:SI 0 "register_operand"))
16487 (use (match_operand:DF 1 "register_operand"))]
16488 "TARGET_USE_FANCY_MATH_387
16489 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16490 {
16491 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16492 {
16493 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16494 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16495 }
16496 else
16497 {
16498 rtx scratch = gen_reg_rtx (HImode);
16499
16500 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16501 emit_insn (gen_andsi3 (operands[0],
16502 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16503 }
16504 DONE;
16505 })
16506
16507 (define_expand "signbitsf2"
16508 [(use (match_operand:SI 0 "register_operand"))
16509 (use (match_operand:SF 1 "register_operand"))]
16510 "TARGET_USE_FANCY_MATH_387
16511 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16512 {
16513 rtx scratch = gen_reg_rtx (HImode);
16514
16515 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16516 emit_insn (gen_andsi3 (operands[0],
16517 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16518 DONE;
16519 })
16520 \f
16521 ;; Block operation instructions
16522
16523 (define_insn "cld"
16524 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16525 ""
16526 "cld"
16527 [(set_attr "length" "1")
16528 (set_attr "length_immediate" "0")
16529 (set_attr "modrm" "0")])
16530
16531 (define_expand "movmem<mode>"
16532 [(use (match_operand:BLK 0 "memory_operand"))
16533 (use (match_operand:BLK 1 "memory_operand"))
16534 (use (match_operand:SWI48 2 "nonmemory_operand"))
16535 (use (match_operand:SWI48 3 "const_int_operand"))
16536 (use (match_operand:SI 4 "const_int_operand"))
16537 (use (match_operand:SI 5 "const_int_operand"))
16538 (use (match_operand:SI 6 ""))
16539 (use (match_operand:SI 7 ""))
16540 (use (match_operand:SI 8 ""))]
16541 ""
16542 {
16543 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16544 operands[2], NULL, operands[3],
16545 operands[4], operands[5],
16546 operands[6], operands[7],
16547 operands[8], false))
16548 DONE;
16549 else
16550 FAIL;
16551 })
16552
16553 ;; Most CPUs don't like single string operations
16554 ;; Handle this case here to simplify previous expander.
16555
16556 (define_expand "strmov"
16557 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16558 (set (match_operand 1 "memory_operand") (match_dup 4))
16559 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16560 (clobber (reg:CC FLAGS_REG))])
16561 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16562 (clobber (reg:CC FLAGS_REG))])]
16563 ""
16564 {
16565 /* Can't use this for non-default address spaces. */
16566 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16567 FAIL;
16568
16569 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16570
16571 /* If .md ever supports :P for Pmode, these can be directly
16572 in the pattern above. */
16573 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16574 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16575
16576 /* Can't use this if the user has appropriated esi or edi. */
16577 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16578 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16579 {
16580 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16581 operands[2], operands[3],
16582 operands[5], operands[6]));
16583 DONE;
16584 }
16585
16586 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16587 })
16588
16589 (define_expand "strmov_singleop"
16590 [(parallel [(set (match_operand 1 "memory_operand")
16591 (match_operand 3 "memory_operand"))
16592 (set (match_operand 0 "register_operand")
16593 (match_operand 4))
16594 (set (match_operand 2 "register_operand")
16595 (match_operand 5))])]
16596 ""
16597 {
16598 if (TARGET_CLD)
16599 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16600 })
16601
16602 (define_insn "*strmovdi_rex_1"
16603 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16604 (mem:DI (match_operand:P 3 "register_operand" "1")))
16605 (set (match_operand:P 0 "register_operand" "=D")
16606 (plus:P (match_dup 2)
16607 (const_int 8)))
16608 (set (match_operand:P 1 "register_operand" "=S")
16609 (plus:P (match_dup 3)
16610 (const_int 8)))]
16611 "TARGET_64BIT
16612 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16613 && ix86_check_no_addr_space (insn)"
16614 "%^movsq"
16615 [(set_attr "type" "str")
16616 (set_attr "memory" "both")
16617 (set_attr "mode" "DI")])
16618
16619 (define_insn "*strmovsi_1"
16620 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16621 (mem:SI (match_operand:P 3 "register_operand" "1")))
16622 (set (match_operand:P 0 "register_operand" "=D")
16623 (plus:P (match_dup 2)
16624 (const_int 4)))
16625 (set (match_operand:P 1 "register_operand" "=S")
16626 (plus:P (match_dup 3)
16627 (const_int 4)))]
16628 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16629 && ix86_check_no_addr_space (insn)"
16630 "%^movs{l|d}"
16631 [(set_attr "type" "str")
16632 (set_attr "memory" "both")
16633 (set_attr "mode" "SI")])
16634
16635 (define_insn "*strmovhi_1"
16636 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16637 (mem:HI (match_operand:P 3 "register_operand" "1")))
16638 (set (match_operand:P 0 "register_operand" "=D")
16639 (plus:P (match_dup 2)
16640 (const_int 2)))
16641 (set (match_operand:P 1 "register_operand" "=S")
16642 (plus:P (match_dup 3)
16643 (const_int 2)))]
16644 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16645 && ix86_check_no_addr_space (insn)"
16646 "%^movsw"
16647 [(set_attr "type" "str")
16648 (set_attr "memory" "both")
16649 (set_attr "mode" "HI")])
16650
16651 (define_insn "*strmovqi_1"
16652 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16653 (mem:QI (match_operand:P 3 "register_operand" "1")))
16654 (set (match_operand:P 0 "register_operand" "=D")
16655 (plus:P (match_dup 2)
16656 (const_int 1)))
16657 (set (match_operand:P 1 "register_operand" "=S")
16658 (plus:P (match_dup 3)
16659 (const_int 1)))]
16660 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16661 && ix86_check_no_addr_space (insn)"
16662 "%^movsb"
16663 [(set_attr "type" "str")
16664 (set_attr "memory" "both")
16665 (set (attr "prefix_rex")
16666 (if_then_else
16667 (match_test "<P:MODE>mode == DImode")
16668 (const_string "0")
16669 (const_string "*")))
16670 (set_attr "mode" "QI")])
16671
16672 (define_expand "rep_mov"
16673 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16674 (set (match_operand 0 "register_operand")
16675 (match_operand 5))
16676 (set (match_operand 2 "register_operand")
16677 (match_operand 6))
16678 (set (match_operand 1 "memory_operand")
16679 (match_operand 3 "memory_operand"))
16680 (use (match_dup 4))])]
16681 ""
16682 {
16683 if (TARGET_CLD)
16684 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16685 })
16686
16687 (define_insn "*rep_movdi_rex64"
16688 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16689 (set (match_operand:P 0 "register_operand" "=D")
16690 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16691 (const_int 3))
16692 (match_operand:P 3 "register_operand" "0")))
16693 (set (match_operand:P 1 "register_operand" "=S")
16694 (plus:P (ashift:P (match_dup 5) (const_int 3))
16695 (match_operand:P 4 "register_operand" "1")))
16696 (set (mem:BLK (match_dup 3))
16697 (mem:BLK (match_dup 4)))
16698 (use (match_dup 5))]
16699 "TARGET_64BIT
16700 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16701 && ix86_check_no_addr_space (insn)"
16702 "%^rep{%;} movsq"
16703 [(set_attr "type" "str")
16704 (set_attr "prefix_rep" "1")
16705 (set_attr "memory" "both")
16706 (set_attr "mode" "DI")])
16707
16708 (define_insn "*rep_movsi"
16709 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16710 (set (match_operand:P 0 "register_operand" "=D")
16711 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16712 (const_int 2))
16713 (match_operand:P 3 "register_operand" "0")))
16714 (set (match_operand:P 1 "register_operand" "=S")
16715 (plus:P (ashift:P (match_dup 5) (const_int 2))
16716 (match_operand:P 4 "register_operand" "1")))
16717 (set (mem:BLK (match_dup 3))
16718 (mem:BLK (match_dup 4)))
16719 (use (match_dup 5))]
16720 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16721 && ix86_check_no_addr_space (insn)"
16722 "%^rep{%;} movs{l|d}"
16723 [(set_attr "type" "str")
16724 (set_attr "prefix_rep" "1")
16725 (set_attr "memory" "both")
16726 (set_attr "mode" "SI")])
16727
16728 (define_insn "*rep_movqi"
16729 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16730 (set (match_operand:P 0 "register_operand" "=D")
16731 (plus:P (match_operand:P 3 "register_operand" "0")
16732 (match_operand:P 5 "register_operand" "2")))
16733 (set (match_operand:P 1 "register_operand" "=S")
16734 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16735 (set (mem:BLK (match_dup 3))
16736 (mem:BLK (match_dup 4)))
16737 (use (match_dup 5))]
16738 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16739 && ix86_check_no_addr_space (insn)"
16740 "%^rep{%;} movsb"
16741 [(set_attr "type" "str")
16742 (set_attr "prefix_rep" "1")
16743 (set_attr "memory" "both")
16744 (set_attr "mode" "QI")])
16745
16746 (define_expand "setmem<mode>"
16747 [(use (match_operand:BLK 0 "memory_operand"))
16748 (use (match_operand:SWI48 1 "nonmemory_operand"))
16749 (use (match_operand:QI 2 "nonmemory_operand"))
16750 (use (match_operand 3 "const_int_operand"))
16751 (use (match_operand:SI 4 "const_int_operand"))
16752 (use (match_operand:SI 5 "const_int_operand"))
16753 (use (match_operand:SI 6 ""))
16754 (use (match_operand:SI 7 ""))
16755 (use (match_operand:SI 8 ""))]
16756 ""
16757 {
16758 if (ix86_expand_set_or_movmem (operands[0], NULL,
16759 operands[1], operands[2],
16760 operands[3], operands[4],
16761 operands[5], operands[6],
16762 operands[7], operands[8], true))
16763 DONE;
16764 else
16765 FAIL;
16766 })
16767
16768 ;; Most CPUs don't like single string operations
16769 ;; Handle this case here to simplify previous expander.
16770
16771 (define_expand "strset"
16772 [(set (match_operand 1 "memory_operand")
16773 (match_operand 2 "register_operand"))
16774 (parallel [(set (match_operand 0 "register_operand")
16775 (match_dup 3))
16776 (clobber (reg:CC FLAGS_REG))])]
16777 ""
16778 {
16779 /* Can't use this for non-default address spaces. */
16780 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16781 FAIL;
16782
16783 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16784 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16785
16786 /* If .md ever supports :P for Pmode, this can be directly
16787 in the pattern above. */
16788 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16789 GEN_INT (GET_MODE_SIZE (GET_MODE
16790 (operands[2]))));
16791 /* Can't use this if the user has appropriated eax or edi. */
16792 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16793 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16794 {
16795 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16796 operands[3]));
16797 DONE;
16798 }
16799 })
16800
16801 (define_expand "strset_singleop"
16802 [(parallel [(set (match_operand 1 "memory_operand")
16803 (match_operand 2 "register_operand"))
16804 (set (match_operand 0 "register_operand")
16805 (match_operand 3))
16806 (unspec [(const_int 0)] UNSPEC_STOS)])]
16807 ""
16808 {
16809 if (TARGET_CLD)
16810 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16811 })
16812
16813 (define_insn "*strsetdi_rex_1"
16814 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16815 (match_operand:DI 2 "register_operand" "a"))
16816 (set (match_operand:P 0 "register_operand" "=D")
16817 (plus:P (match_dup 1)
16818 (const_int 8)))
16819 (unspec [(const_int 0)] UNSPEC_STOS)]
16820 "TARGET_64BIT
16821 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16822 && ix86_check_no_addr_space (insn)"
16823 "%^stosq"
16824 [(set_attr "type" "str")
16825 (set_attr "memory" "store")
16826 (set_attr "mode" "DI")])
16827
16828 (define_insn "*strsetsi_1"
16829 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16830 (match_operand:SI 2 "register_operand" "a"))
16831 (set (match_operand:P 0 "register_operand" "=D")
16832 (plus:P (match_dup 1)
16833 (const_int 4)))
16834 (unspec [(const_int 0)] UNSPEC_STOS)]
16835 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16836 && ix86_check_no_addr_space (insn)"
16837 "%^stos{l|d}"
16838 [(set_attr "type" "str")
16839 (set_attr "memory" "store")
16840 (set_attr "mode" "SI")])
16841
16842 (define_insn "*strsethi_1"
16843 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16844 (match_operand:HI 2 "register_operand" "a"))
16845 (set (match_operand:P 0 "register_operand" "=D")
16846 (plus:P (match_dup 1)
16847 (const_int 2)))
16848 (unspec [(const_int 0)] UNSPEC_STOS)]
16849 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16850 && ix86_check_no_addr_space (insn)"
16851 "%^stosw"
16852 [(set_attr "type" "str")
16853 (set_attr "memory" "store")
16854 (set_attr "mode" "HI")])
16855
16856 (define_insn "*strsetqi_1"
16857 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16858 (match_operand:QI 2 "register_operand" "a"))
16859 (set (match_operand:P 0 "register_operand" "=D")
16860 (plus:P (match_dup 1)
16861 (const_int 1)))
16862 (unspec [(const_int 0)] UNSPEC_STOS)]
16863 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16864 && ix86_check_no_addr_space (insn)"
16865 "%^stosb"
16866 [(set_attr "type" "str")
16867 (set_attr "memory" "store")
16868 (set (attr "prefix_rex")
16869 (if_then_else
16870 (match_test "<P:MODE>mode == DImode")
16871 (const_string "0")
16872 (const_string "*")))
16873 (set_attr "mode" "QI")])
16874
16875 (define_expand "rep_stos"
16876 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16877 (set (match_operand 0 "register_operand")
16878 (match_operand 4))
16879 (set (match_operand 2 "memory_operand") (const_int 0))
16880 (use (match_operand 3 "register_operand"))
16881 (use (match_dup 1))])]
16882 ""
16883 {
16884 if (TARGET_CLD)
16885 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16886 })
16887
16888 (define_insn "*rep_stosdi_rex64"
16889 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16890 (set (match_operand:P 0 "register_operand" "=D")
16891 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16892 (const_int 3))
16893 (match_operand:P 3 "register_operand" "0")))
16894 (set (mem:BLK (match_dup 3))
16895 (const_int 0))
16896 (use (match_operand:DI 2 "register_operand" "a"))
16897 (use (match_dup 4))]
16898 "TARGET_64BIT
16899 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16900 && ix86_check_no_addr_space (insn)"
16901 "%^rep{%;} stosq"
16902 [(set_attr "type" "str")
16903 (set_attr "prefix_rep" "1")
16904 (set_attr "memory" "store")
16905 (set_attr "mode" "DI")])
16906
16907 (define_insn "*rep_stossi"
16908 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16909 (set (match_operand:P 0 "register_operand" "=D")
16910 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16911 (const_int 2))
16912 (match_operand:P 3 "register_operand" "0")))
16913 (set (mem:BLK (match_dup 3))
16914 (const_int 0))
16915 (use (match_operand:SI 2 "register_operand" "a"))
16916 (use (match_dup 4))]
16917 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16918 && ix86_check_no_addr_space (insn)"
16919 "%^rep{%;} stos{l|d}"
16920 [(set_attr "type" "str")
16921 (set_attr "prefix_rep" "1")
16922 (set_attr "memory" "store")
16923 (set_attr "mode" "SI")])
16924
16925 (define_insn "*rep_stosqi"
16926 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16927 (set (match_operand:P 0 "register_operand" "=D")
16928 (plus:P (match_operand:P 3 "register_operand" "0")
16929 (match_operand:P 4 "register_operand" "1")))
16930 (set (mem:BLK (match_dup 3))
16931 (const_int 0))
16932 (use (match_operand:QI 2 "register_operand" "a"))
16933 (use (match_dup 4))]
16934 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16935 && ix86_check_no_addr_space (insn)"
16936 "%^rep{%;} stosb"
16937 [(set_attr "type" "str")
16938 (set_attr "prefix_rep" "1")
16939 (set_attr "memory" "store")
16940 (set (attr "prefix_rex")
16941 (if_then_else
16942 (match_test "<P:MODE>mode == DImode")
16943 (const_string "0")
16944 (const_string "*")))
16945 (set_attr "mode" "QI")])
16946
16947 (define_expand "cmpstrnsi"
16948 [(set (match_operand:SI 0 "register_operand")
16949 (compare:SI (match_operand:BLK 1 "general_operand")
16950 (match_operand:BLK 2 "general_operand")))
16951 (use (match_operand 3 "general_operand"))
16952 (use (match_operand 4 "immediate_operand"))]
16953 ""
16954 {
16955 rtx addr1, addr2, out, outlow, count, countreg, align;
16956
16957 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16958 FAIL;
16959
16960 /* Can't use this if the user has appropriated ecx, esi or edi. */
16961 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16962 FAIL;
16963
16964 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
16965 will have rewritten the length arg to be the minimum of the const string
16966 length and the actual length arg. If both strings are the same and
16967 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
16968 will incorrectly base the results on chars past the 0 byte. */
16969 tree t1 = MEM_EXPR (operands[1]);
16970 tree t2 = MEM_EXPR (operands[2]);
16971 if (!((t1 && TREE_CODE (t1) == MEM_REF
16972 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
16973 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
16974 || (t2 && TREE_CODE (t2) == MEM_REF
16975 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
16976 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
16977 FAIL;
16978
16979 out = operands[0];
16980 if (!REG_P (out))
16981 out = gen_reg_rtx (SImode);
16982
16983 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16984 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16985 if (addr1 != XEXP (operands[1], 0))
16986 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16987 if (addr2 != XEXP (operands[2], 0))
16988 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16989
16990 count = operands[3];
16991 countreg = ix86_zero_extend_to_Pmode (count);
16992
16993 /* %%% Iff we are testing strict equality, we can use known alignment
16994 to good advantage. This may be possible with combine, particularly
16995 once cc0 is dead. */
16996 align = operands[4];
16997
16998 if (CONST_INT_P (count))
16999 {
17000 if (INTVAL (count) == 0)
17001 {
17002 emit_move_insn (operands[0], const0_rtx);
17003 DONE;
17004 }
17005 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17006 operands[1], operands[2]));
17007 }
17008 else
17009 {
17010 rtx (*gen_cmp) (rtx, rtx);
17011
17012 gen_cmp = (TARGET_64BIT
17013 ? gen_cmpdi_1 : gen_cmpsi_1);
17014
17015 emit_insn (gen_cmp (countreg, countreg));
17016 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17017 operands[1], operands[2]));
17018 }
17019
17020 outlow = gen_lowpart (QImode, out);
17021 emit_insn (gen_cmpintqi (outlow));
17022 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17023
17024 if (operands[0] != out)
17025 emit_move_insn (operands[0], out);
17026
17027 DONE;
17028 })
17029
17030 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17031
17032 (define_expand "cmpintqi"
17033 [(set (match_dup 1)
17034 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17035 (set (match_dup 2)
17036 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17037 (parallel [(set (match_operand:QI 0 "register_operand")
17038 (minus:QI (match_dup 1)
17039 (match_dup 2)))
17040 (clobber (reg:CC FLAGS_REG))])]
17041 ""
17042 {
17043 operands[1] = gen_reg_rtx (QImode);
17044 operands[2] = gen_reg_rtx (QImode);
17045 })
17046
17047 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17048 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17049
17050 (define_expand "cmpstrnqi_nz_1"
17051 [(parallel [(set (reg:CC FLAGS_REG)
17052 (compare:CC (match_operand 4 "memory_operand")
17053 (match_operand 5 "memory_operand")))
17054 (use (match_operand 2 "register_operand"))
17055 (use (match_operand:SI 3 "immediate_operand"))
17056 (clobber (match_operand 0 "register_operand"))
17057 (clobber (match_operand 1 "register_operand"))
17058 (clobber (match_dup 2))])]
17059 ""
17060 {
17061 if (TARGET_CLD)
17062 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17063 })
17064
17065 (define_insn "*cmpstrnqi_nz_1"
17066 [(set (reg:CC FLAGS_REG)
17067 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17068 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17069 (use (match_operand:P 6 "register_operand" "2"))
17070 (use (match_operand:SI 3 "immediate_operand" "i"))
17071 (clobber (match_operand:P 0 "register_operand" "=S"))
17072 (clobber (match_operand:P 1 "register_operand" "=D"))
17073 (clobber (match_operand:P 2 "register_operand" "=c"))]
17074 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17075 && ix86_check_no_addr_space (insn)"
17076 "%^repz{%;} cmpsb"
17077 [(set_attr "type" "str")
17078 (set_attr "mode" "QI")
17079 (set (attr "prefix_rex")
17080 (if_then_else
17081 (match_test "<P:MODE>mode == DImode")
17082 (const_string "0")
17083 (const_string "*")))
17084 (set_attr "prefix_rep" "1")])
17085
17086 ;; The same, but the count is not known to not be zero.
17087
17088 (define_expand "cmpstrnqi_1"
17089 [(parallel [(set (reg:CC FLAGS_REG)
17090 (if_then_else:CC (ne (match_operand 2 "register_operand")
17091 (const_int 0))
17092 (compare:CC (match_operand 4 "memory_operand")
17093 (match_operand 5 "memory_operand"))
17094 (const_int 0)))
17095 (use (match_operand:SI 3 "immediate_operand"))
17096 (use (reg:CC FLAGS_REG))
17097 (clobber (match_operand 0 "register_operand"))
17098 (clobber (match_operand 1 "register_operand"))
17099 (clobber (match_dup 2))])]
17100 ""
17101 {
17102 if (TARGET_CLD)
17103 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17104 })
17105
17106 (define_insn "*cmpstrnqi_1"
17107 [(set (reg:CC FLAGS_REG)
17108 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17109 (const_int 0))
17110 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17111 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17112 (const_int 0)))
17113 (use (match_operand:SI 3 "immediate_operand" "i"))
17114 (use (reg:CC FLAGS_REG))
17115 (clobber (match_operand:P 0 "register_operand" "=S"))
17116 (clobber (match_operand:P 1 "register_operand" "=D"))
17117 (clobber (match_operand:P 2 "register_operand" "=c"))]
17118 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17119 && ix86_check_no_addr_space (insn)"
17120 "%^repz{%;} cmpsb"
17121 [(set_attr "type" "str")
17122 (set_attr "mode" "QI")
17123 (set (attr "prefix_rex")
17124 (if_then_else
17125 (match_test "<P:MODE>mode == DImode")
17126 (const_string "0")
17127 (const_string "*")))
17128 (set_attr "prefix_rep" "1")])
17129
17130 (define_expand "strlen<mode>"
17131 [(set (match_operand:P 0 "register_operand")
17132 (unspec:P [(match_operand:BLK 1 "general_operand")
17133 (match_operand:QI 2 "immediate_operand")
17134 (match_operand 3 "immediate_operand")]
17135 UNSPEC_SCAS))]
17136 ""
17137 {
17138 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17139 DONE;
17140 else
17141 FAIL;
17142 })
17143
17144 (define_expand "strlenqi_1"
17145 [(parallel [(set (match_operand 0 "register_operand")
17146 (match_operand 2))
17147 (clobber (match_operand 1 "register_operand"))
17148 (clobber (reg:CC FLAGS_REG))])]
17149 ""
17150 {
17151 if (TARGET_CLD)
17152 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17153 })
17154
17155 (define_insn "*strlenqi_1"
17156 [(set (match_operand:P 0 "register_operand" "=&c")
17157 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17158 (match_operand:QI 2 "register_operand" "a")
17159 (match_operand:P 3 "immediate_operand" "i")
17160 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17161 (clobber (match_operand:P 1 "register_operand" "=D"))
17162 (clobber (reg:CC FLAGS_REG))]
17163 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17164 && ix86_check_no_addr_space (insn)"
17165 "%^repnz{%;} scasb"
17166 [(set_attr "type" "str")
17167 (set_attr "mode" "QI")
17168 (set (attr "prefix_rex")
17169 (if_then_else
17170 (match_test "<P:MODE>mode == DImode")
17171 (const_string "0")
17172 (const_string "*")))
17173 (set_attr "prefix_rep" "1")])
17174
17175 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17176 ;; handled in combine, but it is not currently up to the task.
17177 ;; When used for their truth value, the cmpstrn* expanders generate
17178 ;; code like this:
17179 ;;
17180 ;; repz cmpsb
17181 ;; seta %al
17182 ;; setb %dl
17183 ;; cmpb %al, %dl
17184 ;; jcc label
17185 ;;
17186 ;; The intermediate three instructions are unnecessary.
17187
17188 ;; This one handles cmpstrn*_nz_1...
17189 (define_peephole2
17190 [(parallel[
17191 (set (reg:CC FLAGS_REG)
17192 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17193 (mem:BLK (match_operand 5 "register_operand"))))
17194 (use (match_operand 6 "register_operand"))
17195 (use (match_operand:SI 3 "immediate_operand"))
17196 (clobber (match_operand 0 "register_operand"))
17197 (clobber (match_operand 1 "register_operand"))
17198 (clobber (match_operand 2 "register_operand"))])
17199 (set (match_operand:QI 7 "register_operand")
17200 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17201 (set (match_operand:QI 8 "register_operand")
17202 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17203 (set (reg FLAGS_REG)
17204 (compare (match_dup 7) (match_dup 8)))
17205 ]
17206 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17207 [(parallel[
17208 (set (reg:CC FLAGS_REG)
17209 (compare:CC (mem:BLK (match_dup 4))
17210 (mem:BLK (match_dup 5))))
17211 (use (match_dup 6))
17212 (use (match_dup 3))
17213 (clobber (match_dup 0))
17214 (clobber (match_dup 1))
17215 (clobber (match_dup 2))])])
17216
17217 ;; ...and this one handles cmpstrn*_1.
17218 (define_peephole2
17219 [(parallel[
17220 (set (reg:CC FLAGS_REG)
17221 (if_then_else:CC (ne (match_operand 6 "register_operand")
17222 (const_int 0))
17223 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17224 (mem:BLK (match_operand 5 "register_operand")))
17225 (const_int 0)))
17226 (use (match_operand:SI 3 "immediate_operand"))
17227 (use (reg:CC FLAGS_REG))
17228 (clobber (match_operand 0 "register_operand"))
17229 (clobber (match_operand 1 "register_operand"))
17230 (clobber (match_operand 2 "register_operand"))])
17231 (set (match_operand:QI 7 "register_operand")
17232 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17233 (set (match_operand:QI 8 "register_operand")
17234 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17235 (set (reg FLAGS_REG)
17236 (compare (match_dup 7) (match_dup 8)))
17237 ]
17238 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17239 [(parallel[
17240 (set (reg:CC FLAGS_REG)
17241 (if_then_else:CC (ne (match_dup 6)
17242 (const_int 0))
17243 (compare:CC (mem:BLK (match_dup 4))
17244 (mem:BLK (match_dup 5)))
17245 (const_int 0)))
17246 (use (match_dup 3))
17247 (use (reg:CC FLAGS_REG))
17248 (clobber (match_dup 0))
17249 (clobber (match_dup 1))
17250 (clobber (match_dup 2))])])
17251 \f
17252 ;; Conditional move instructions.
17253
17254 (define_expand "mov<mode>cc"
17255 [(set (match_operand:SWIM 0 "register_operand")
17256 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17257 (match_operand:SWIM 2 "<general_operand>")
17258 (match_operand:SWIM 3 "<general_operand>")))]
17259 ""
17260 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17261
17262 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17263 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17264 ;; So just document what we're doing explicitly.
17265
17266 (define_expand "x86_mov<mode>cc_0_m1"
17267 [(parallel
17268 [(set (match_operand:SWI48 0 "register_operand")
17269 (if_then_else:SWI48
17270 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17271 [(match_operand 1 "flags_reg_operand")
17272 (const_int 0)])
17273 (const_int -1)
17274 (const_int 0)))
17275 (clobber (reg:CC FLAGS_REG))])])
17276
17277 (define_insn "*x86_mov<mode>cc_0_m1"
17278 [(set (match_operand:SWI48 0 "register_operand" "=r")
17279 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17280 [(reg FLAGS_REG) (const_int 0)])
17281 (const_int -1)
17282 (const_int 0)))
17283 (clobber (reg:CC FLAGS_REG))]
17284 ""
17285 "sbb{<imodesuffix>}\t%0, %0"
17286 [(set_attr "type" "alu1")
17287 (set_attr "use_carry" "1")
17288 (set_attr "pent_pair" "pu")
17289 (set_attr "mode" "<MODE>")
17290 (set_attr "length_immediate" "0")])
17291
17292 (define_insn "*x86_mov<mode>cc_0_m1_se"
17293 [(set (match_operand:SWI48 0 "register_operand" "=r")
17294 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17295 [(reg FLAGS_REG) (const_int 0)])
17296 (const_int 1)
17297 (const_int 0)))
17298 (clobber (reg:CC FLAGS_REG))]
17299 ""
17300 "sbb{<imodesuffix>}\t%0, %0"
17301 [(set_attr "type" "alu1")
17302 (set_attr "use_carry" "1")
17303 (set_attr "pent_pair" "pu")
17304 (set_attr "mode" "<MODE>")
17305 (set_attr "length_immediate" "0")])
17306
17307 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17308 [(set (match_operand:SWI48 0 "register_operand" "=r")
17309 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17310 [(reg FLAGS_REG) (const_int 0)])))
17311 (clobber (reg:CC FLAGS_REG))]
17312 ""
17313 "sbb{<imodesuffix>}\t%0, %0"
17314 [(set_attr "type" "alu1")
17315 (set_attr "use_carry" "1")
17316 (set_attr "pent_pair" "pu")
17317 (set_attr "mode" "<MODE>")
17318 (set_attr "length_immediate" "0")])
17319
17320 (define_insn_and_split "*x86_mov<SWI48:mode>cc_0_m1_neg_leu<SWI:mode>"
17321 [(set (match_operand:SWI48 0 "register_operand" "=r")
17322 (neg:SWI48
17323 (leu:SWI48
17324 (match_operand:SWI 1 "nonimmediate_operand" "<SWI:r>m")
17325 (match_operand:SWI 2 "<SWI:immediate_operand>" "<SWI:i>"))))
17326 (clobber (reg:CC FLAGS_REG))]
17327 "CONST_INT_P (operands[2])
17328 && INTVAL (operands[2]) != -1
17329 && INTVAL (operands[2]) != 2147483647"
17330 "#"
17331 ""
17332 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
17333 (parallel [(set (match_dup 0)
17334 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))
17335 (clobber (reg:CC FLAGS_REG))])]
17336 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
17337
17338 (define_insn "*mov<mode>cc_noc"
17339 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17340 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17341 [(reg FLAGS_REG) (const_int 0)])
17342 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17343 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17344 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17345 "@
17346 cmov%O2%C1\t{%2, %0|%0, %2}
17347 cmov%O2%c1\t{%3, %0|%0, %3}"
17348 [(set_attr "type" "icmov")
17349 (set_attr "mode" "<MODE>")])
17350
17351 (define_insn "*movsicc_noc_zext"
17352 [(set (match_operand:DI 0 "register_operand" "=r,r")
17353 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17354 [(reg FLAGS_REG) (const_int 0)])
17355 (zero_extend:DI
17356 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17357 (zero_extend:DI
17358 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17359 "TARGET_64BIT
17360 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17361 "@
17362 cmov%O2%C1\t{%2, %k0|%k0, %2}
17363 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17364 [(set_attr "type" "icmov")
17365 (set_attr "mode" "SI")])
17366
17367 ;; Don't do conditional moves with memory inputs. This splitter helps
17368 ;; register starved x86_32 by forcing inputs into registers before reload.
17369 (define_split
17370 [(set (match_operand:SWI248 0 "register_operand")
17371 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17372 [(reg FLAGS_REG) (const_int 0)])
17373 (match_operand:SWI248 2 "nonimmediate_operand")
17374 (match_operand:SWI248 3 "nonimmediate_operand")))]
17375 "!TARGET_64BIT && TARGET_CMOVE
17376 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17377 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17378 && can_create_pseudo_p ()
17379 && optimize_insn_for_speed_p ()"
17380 [(set (match_dup 0)
17381 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17382 {
17383 if (MEM_P (operands[2]))
17384 operands[2] = force_reg (<MODE>mode, operands[2]);
17385 if (MEM_P (operands[3]))
17386 operands[3] = force_reg (<MODE>mode, operands[3]);
17387 })
17388
17389 (define_insn "*movqicc_noc"
17390 [(set (match_operand:QI 0 "register_operand" "=r,r")
17391 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17392 [(reg FLAGS_REG) (const_int 0)])
17393 (match_operand:QI 2 "register_operand" "r,0")
17394 (match_operand:QI 3 "register_operand" "0,r")))]
17395 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17396 "#"
17397 [(set_attr "type" "icmov")
17398 (set_attr "mode" "QI")])
17399
17400 (define_split
17401 [(set (match_operand:SWI12 0 "register_operand")
17402 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17403 [(reg FLAGS_REG) (const_int 0)])
17404 (match_operand:SWI12 2 "register_operand")
17405 (match_operand:SWI12 3 "register_operand")))]
17406 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17407 && reload_completed"
17408 [(set (match_dup 0)
17409 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17410 {
17411 operands[0] = gen_lowpart (SImode, operands[0]);
17412 operands[2] = gen_lowpart (SImode, operands[2]);
17413 operands[3] = gen_lowpart (SImode, operands[3]);
17414 })
17415
17416 ;; Don't do conditional moves with memory inputs
17417 (define_peephole2
17418 [(match_scratch:SWI248 4 "r")
17419 (set (match_operand:SWI248 0 "register_operand")
17420 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17421 [(reg FLAGS_REG) (const_int 0)])
17422 (match_operand:SWI248 2 "nonimmediate_operand")
17423 (match_operand:SWI248 3 "nonimmediate_operand")))]
17424 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17425 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17426 && optimize_insn_for_speed_p ()"
17427 [(set (match_dup 4) (match_dup 5))
17428 (set (match_dup 0)
17429 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17430 {
17431 if (MEM_P (operands[2]))
17432 {
17433 operands[5] = operands[2];
17434 operands[2] = operands[4];
17435 }
17436 else if (MEM_P (operands[3]))
17437 {
17438 operands[5] = operands[3];
17439 operands[3] = operands[4];
17440 }
17441 else
17442 gcc_unreachable ();
17443 })
17444
17445 (define_peephole2
17446 [(match_scratch:SI 4 "r")
17447 (set (match_operand:DI 0 "register_operand")
17448 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17449 [(reg FLAGS_REG) (const_int 0)])
17450 (zero_extend:DI
17451 (match_operand:SI 2 "nonimmediate_operand"))
17452 (zero_extend:DI
17453 (match_operand:SI 3 "nonimmediate_operand"))))]
17454 "TARGET_64BIT
17455 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17456 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17457 && optimize_insn_for_speed_p ()"
17458 [(set (match_dup 4) (match_dup 5))
17459 (set (match_dup 0)
17460 (if_then_else:DI (match_dup 1)
17461 (zero_extend:DI (match_dup 2))
17462 (zero_extend:DI (match_dup 3))))]
17463 {
17464 if (MEM_P (operands[2]))
17465 {
17466 operands[5] = operands[2];
17467 operands[2] = operands[4];
17468 }
17469 else if (MEM_P (operands[3]))
17470 {
17471 operands[5] = operands[3];
17472 operands[3] = operands[4];
17473 }
17474 else
17475 gcc_unreachable ();
17476 })
17477
17478 (define_expand "mov<mode>cc"
17479 [(set (match_operand:X87MODEF 0 "register_operand")
17480 (if_then_else:X87MODEF
17481 (match_operand 1 "comparison_operator")
17482 (match_operand:X87MODEF 2 "register_operand")
17483 (match_operand:X87MODEF 3 "register_operand")))]
17484 "(TARGET_80387 && TARGET_CMOVE)
17485 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17486 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17487
17488 (define_insn "*movxfcc_1"
17489 [(set (match_operand:XF 0 "register_operand" "=f,f")
17490 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17491 [(reg FLAGS_REG) (const_int 0)])
17492 (match_operand:XF 2 "register_operand" "f,0")
17493 (match_operand:XF 3 "register_operand" "0,f")))]
17494 "TARGET_80387 && TARGET_CMOVE"
17495 "@
17496 fcmov%F1\t{%2, %0|%0, %2}
17497 fcmov%f1\t{%3, %0|%0, %3}"
17498 [(set_attr "type" "fcmov")
17499 (set_attr "mode" "XF")])
17500
17501 (define_insn "*movdfcc_1"
17502 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17503 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17504 [(reg FLAGS_REG) (const_int 0)])
17505 (match_operand:DF 2 "nonimmediate_operand"
17506 "f ,0,rm,0 ,rm,0")
17507 (match_operand:DF 3 "nonimmediate_operand"
17508 "0 ,f,0 ,rm,0, rm")))]
17509 "TARGET_80387 && TARGET_CMOVE
17510 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17511 "@
17512 fcmov%F1\t{%2, %0|%0, %2}
17513 fcmov%f1\t{%3, %0|%0, %3}
17514 #
17515 #
17516 cmov%O2%C1\t{%2, %0|%0, %2}
17517 cmov%O2%c1\t{%3, %0|%0, %3}"
17518 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17519 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17520 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17521
17522 (define_split
17523 [(set (match_operand:DF 0 "general_reg_operand")
17524 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17525 [(reg FLAGS_REG) (const_int 0)])
17526 (match_operand:DF 2 "nonimmediate_operand")
17527 (match_operand:DF 3 "nonimmediate_operand")))]
17528 "!TARGET_64BIT && reload_completed"
17529 [(set (match_dup 2)
17530 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17531 (set (match_dup 3)
17532 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17533 {
17534 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17535 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17536 })
17537
17538 (define_insn "*movsfcc_1_387"
17539 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17540 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17541 [(reg FLAGS_REG) (const_int 0)])
17542 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17543 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17544 "TARGET_80387 && TARGET_CMOVE
17545 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17546 "@
17547 fcmov%F1\t{%2, %0|%0, %2}
17548 fcmov%f1\t{%3, %0|%0, %3}
17549 cmov%O2%C1\t{%2, %0|%0, %2}
17550 cmov%O2%c1\t{%3, %0|%0, %3}"
17551 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17552 (set_attr "mode" "SF,SF,SI,SI")])
17553
17554 ;; Don't do conditional moves with memory inputs. This splitter helps
17555 ;; register starved x86_32 by forcing inputs into registers before reload.
17556 (define_split
17557 [(set (match_operand:MODEF 0 "register_operand")
17558 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17559 [(reg FLAGS_REG) (const_int 0)])
17560 (match_operand:MODEF 2 "nonimmediate_operand")
17561 (match_operand:MODEF 3 "nonimmediate_operand")))]
17562 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17563 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17564 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17565 && can_create_pseudo_p ()
17566 && optimize_insn_for_speed_p ()"
17567 [(set (match_dup 0)
17568 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17569 {
17570 if (MEM_P (operands[2]))
17571 operands[2] = force_reg (<MODE>mode, operands[2]);
17572 if (MEM_P (operands[3]))
17573 operands[3] = force_reg (<MODE>mode, operands[3]);
17574 })
17575
17576 ;; Don't do conditional moves with memory inputs
17577 (define_peephole2
17578 [(match_scratch:MODEF 4 "r")
17579 (set (match_operand:MODEF 0 "general_reg_operand")
17580 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17581 [(reg FLAGS_REG) (const_int 0)])
17582 (match_operand:MODEF 2 "nonimmediate_operand")
17583 (match_operand:MODEF 3 "nonimmediate_operand")))]
17584 "(<MODE>mode != DFmode || TARGET_64BIT)
17585 && TARGET_80387 && TARGET_CMOVE
17586 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17587 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17588 && optimize_insn_for_speed_p ()"
17589 [(set (match_dup 4) (match_dup 5))
17590 (set (match_dup 0)
17591 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17592 {
17593 if (MEM_P (operands[2]))
17594 {
17595 operands[5] = operands[2];
17596 operands[2] = operands[4];
17597 }
17598 else if (MEM_P (operands[3]))
17599 {
17600 operands[5] = operands[3];
17601 operands[3] = operands[4];
17602 }
17603 else
17604 gcc_unreachable ();
17605 })
17606
17607 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17608 ;; the scalar versions to have only XMM registers as operands.
17609
17610 ;; XOP conditional move
17611 (define_insn "*xop_pcmov_<mode>"
17612 [(set (match_operand:MODEF 0 "register_operand" "=x")
17613 (if_then_else:MODEF
17614 (match_operand:MODEF 1 "register_operand" "x")
17615 (match_operand:MODEF 2 "register_operand" "x")
17616 (match_operand:MODEF 3 "register_operand" "x")))]
17617 "TARGET_XOP"
17618 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17619 [(set_attr "type" "sse4arg")])
17620
17621 ;; These versions of the min/max patterns are intentionally ignorant of
17622 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17623 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17624 ;; are undefined in this condition, we're certain this is correct.
17625
17626 (define_insn "<code><mode>3"
17627 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17628 (smaxmin:MODEF
17629 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17630 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17631 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17632 "@
17633 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17634 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17635 [(set_attr "isa" "noavx,avx")
17636 (set_attr "prefix" "orig,vex")
17637 (set_attr "type" "sseadd")
17638 (set_attr "mode" "<MODE>")])
17639
17640 ;; These versions of the min/max patterns implement exactly the operations
17641 ;; min = (op1 < op2 ? op1 : op2)
17642 ;; max = (!(op1 < op2) ? op1 : op2)
17643 ;; Their operands are not commutative, and thus they may be used in the
17644 ;; presence of -0.0 and NaN.
17645
17646 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17647 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17648 (unspec:MODEF
17649 [(match_operand:MODEF 1 "register_operand" "0,v")
17650 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17651 IEEE_MAXMIN))]
17652 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17653 "@
17654 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17655 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17656 [(set_attr "isa" "noavx,avx")
17657 (set_attr "prefix" "orig,maybe_evex")
17658 (set_attr "type" "sseadd")
17659 (set_attr "mode" "<MODE>")])
17660
17661 ;; Make two stack loads independent:
17662 ;; fld aa fld aa
17663 ;; fld %st(0) -> fld bb
17664 ;; fmul bb fmul %st(1), %st
17665 ;;
17666 ;; Actually we only match the last two instructions for simplicity.
17667
17668 (define_peephole2
17669 [(set (match_operand 0 "fp_register_operand")
17670 (match_operand 1 "fp_register_operand"))
17671 (set (match_dup 0)
17672 (match_operator 2 "binary_fp_operator"
17673 [(match_dup 0)
17674 (match_operand 3 "memory_operand")]))]
17675 "REGNO (operands[0]) != REGNO (operands[1])"
17676 [(set (match_dup 0) (match_dup 3))
17677 (set (match_dup 0)
17678 (match_op_dup 2
17679 [(match_dup 5) (match_dup 4)]))]
17680 {
17681 operands[4] = operands[0];
17682 operands[5] = operands[1];
17683
17684 /* The % modifier is not operational anymore in peephole2's, so we have to
17685 swap the operands manually in the case of addition and multiplication. */
17686 if (COMMUTATIVE_ARITH_P (operands[2]))
17687 std::swap (operands[4], operands[5]);
17688 })
17689
17690 (define_peephole2
17691 [(set (match_operand 0 "fp_register_operand")
17692 (match_operand 1 "fp_register_operand"))
17693 (set (match_dup 0)
17694 (match_operator 2 "binary_fp_operator"
17695 [(match_operand 3 "memory_operand")
17696 (match_dup 0)]))]
17697 "REGNO (operands[0]) != REGNO (operands[1])"
17698 [(set (match_dup 0) (match_dup 3))
17699 (set (match_dup 0)
17700 (match_op_dup 2
17701 [(match_dup 4) (match_dup 5)]))]
17702 {
17703 operands[4] = operands[0];
17704 operands[5] = operands[1];
17705
17706 /* The % modifier is not operational anymore in peephole2's, so we have to
17707 swap the operands manually in the case of addition and multiplication. */
17708 if (COMMUTATIVE_ARITH_P (operands[2]))
17709 std::swap (operands[4], operands[5]);
17710 })
17711
17712 ;; Conditional addition patterns
17713 (define_expand "add<mode>cc"
17714 [(match_operand:SWI 0 "register_operand")
17715 (match_operand 1 "ordered_comparison_operator")
17716 (match_operand:SWI 2 "register_operand")
17717 (match_operand:SWI 3 "const_int_operand")]
17718 ""
17719 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17720 \f
17721 ;; Misc patterns (?)
17722
17723 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17724 ;; Otherwise there will be nothing to keep
17725 ;;
17726 ;; [(set (reg ebp) (reg esp))]
17727 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17728 ;; (clobber (eflags)]
17729 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17730 ;;
17731 ;; in proper program order.
17732
17733 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
17734 [(set (match_operand:P 0 "register_operand" "=r,r")
17735 (plus:P (match_operand:P 1 "register_operand" "0,r")
17736 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17737 (clobber (reg:CC FLAGS_REG))
17738 (clobber (mem:BLK (scratch)))]
17739 ""
17740 {
17741 switch (get_attr_type (insn))
17742 {
17743 case TYPE_IMOV:
17744 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17745
17746 case TYPE_ALU:
17747 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17748 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17749 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17750
17751 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17752
17753 default:
17754 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17755 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17756 }
17757 }
17758 [(set (attr "type")
17759 (cond [(and (eq_attr "alternative" "0")
17760 (not (match_test "TARGET_OPT_AGU")))
17761 (const_string "alu")
17762 (match_operand:<MODE> 2 "const0_operand")
17763 (const_string "imov")
17764 ]
17765 (const_string "lea")))
17766 (set (attr "length_immediate")
17767 (cond [(eq_attr "type" "imov")
17768 (const_string "0")
17769 (and (eq_attr "type" "alu")
17770 (match_operand 2 "const128_operand"))
17771 (const_string "1")
17772 ]
17773 (const_string "*")))
17774 (set_attr "mode" "<MODE>")])
17775
17776 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
17777 [(set (match_operand:P 0 "register_operand" "=r")
17778 (minus:P (match_operand:P 1 "register_operand" "0")
17779 (match_operand:P 2 "register_operand" "r")))
17780 (clobber (reg:CC FLAGS_REG))
17781 (clobber (mem:BLK (scratch)))]
17782 ""
17783 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17784 [(set_attr "type" "alu")
17785 (set_attr "mode" "<MODE>")])
17786
17787 (define_insn "@allocate_stack_worker_probe_<mode>"
17788 [(set (match_operand:P 0 "register_operand" "=a")
17789 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17790 UNSPECV_STACK_PROBE))
17791 (clobber (reg:CC FLAGS_REG))]
17792 "ix86_target_stack_probe ()"
17793 "call\t___chkstk_ms"
17794 [(set_attr "type" "multi")
17795 (set_attr "length" "5")])
17796
17797 (define_expand "allocate_stack"
17798 [(match_operand 0 "register_operand")
17799 (match_operand 1 "general_operand")]
17800 "ix86_target_stack_probe ()"
17801 {
17802 rtx x;
17803
17804 #ifndef CHECK_STACK_LIMIT
17805 #define CHECK_STACK_LIMIT 0
17806 #endif
17807
17808 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17809 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17810 x = operands[1];
17811 else
17812 {
17813 x = copy_to_mode_reg (Pmode, operands[1]);
17814
17815 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
17816 }
17817
17818 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17819 stack_pointer_rtx, 0, OPTAB_DIRECT);
17820
17821 if (x != stack_pointer_rtx)
17822 emit_move_insn (stack_pointer_rtx, x);
17823
17824 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17825 DONE;
17826 })
17827
17828 (define_expand "probe_stack"
17829 [(match_operand 0 "memory_operand")]
17830 ""
17831 {
17832 emit_insn (gen_probe_stack_1
17833 (word_mode, operands[0], const0_rtx));
17834 DONE;
17835 })
17836
17837 ;; Use OR for stack probes, this is shorter.
17838 (define_insn "@probe_stack_1_<mode>"
17839 [(set (match_operand:W 0 "memory_operand" "=m")
17840 (unspec:W [(match_operand:W 1 "const0_operand")]
17841 UNSPEC_PROBE_STACK))
17842 (clobber (reg:CC FLAGS_REG))]
17843 ""
17844 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17845 [(set_attr "type" "alu1")
17846 (set_attr "mode" "<MODE>")
17847 (set_attr "length_immediate" "1")])
17848
17849 (define_insn "@adjust_stack_and_probe_<mode>"
17850 [(set (match_operand:P 0 "register_operand" "=r")
17851 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17852 UNSPECV_PROBE_STACK_RANGE))
17853 (set (reg:P SP_REG)
17854 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17855 (clobber (reg:CC FLAGS_REG))
17856 (clobber (mem:BLK (scratch)))]
17857 ""
17858 "* return output_adjust_stack_and_probe (operands[0]);"
17859 [(set_attr "type" "multi")])
17860
17861 (define_insn "@probe_stack_range_<mode>"
17862 [(set (match_operand:P 0 "register_operand" "=r")
17863 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17864 (match_operand:P 2 "const_int_operand" "n")]
17865 UNSPECV_PROBE_STACK_RANGE))
17866 (clobber (reg:CC FLAGS_REG))]
17867 ""
17868 "* return output_probe_stack_range (operands[0], operands[2]);"
17869 [(set_attr "type" "multi")])
17870
17871 (define_expand "builtin_setjmp_receiver"
17872 [(label_ref (match_operand 0))]
17873 "!TARGET_64BIT && flag_pic"
17874 {
17875 #if TARGET_MACHO
17876 if (TARGET_MACHO)
17877 {
17878 rtx xops[3];
17879 rtx_code_label *label_rtx = gen_label_rtx ();
17880 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17881 xops[0] = xops[1] = pic_offset_table_rtx;
17882 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17883 ix86_expand_binary_operator (MINUS, SImode, xops);
17884 }
17885 else
17886 #endif
17887 emit_insn (gen_set_got (pic_offset_table_rtx));
17888 DONE;
17889 })
17890
17891 (define_expand "save_stack_nonlocal"
17892 [(set (match_operand 0 "memory_operand")
17893 (match_operand 1 "register_operand"))]
17894 ""
17895 {
17896 rtx stack_slot;
17897 if ((flag_cf_protection & CF_RETURN))
17898 {
17899 /* Copy shadow stack pointer to the first slot and stack ppointer
17900 to the second slot. */
17901 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
17902 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
17903 rtx ssp = gen_reg_rtx (word_mode);
17904 emit_insn ((word_mode == SImode)
17905 ? gen_rdsspsi (ssp)
17906 : gen_rdsspdi (ssp));
17907 emit_move_insn (ssp_slot, ssp);
17908 }
17909 else
17910 stack_slot = adjust_address (operands[0], Pmode, 0);
17911 emit_move_insn (stack_slot, operands[1]);
17912 DONE;
17913 })
17914
17915 (define_expand "restore_stack_nonlocal"
17916 [(set (match_operand 0 "register_operand" "")
17917 (match_operand 1 "memory_operand" ""))]
17918 ""
17919 {
17920 rtx stack_slot;
17921 if ((flag_cf_protection & CF_RETURN))
17922 {
17923 /* Restore shadow stack pointer from the first slot and stack
17924 pointer from the second slot. */
17925 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
17926 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
17927
17928 rtx flags, jump, noadj_label, inc_label, loop_label;
17929 rtx reg_adj, reg_ssp, tmp, clob;
17930
17931 /* Get the current shadow stack pointer. The code below will check if
17932 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
17933 is a NOP. */
17934 reg_ssp = gen_reg_rtx (word_mode);
17935 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
17936 emit_insn ((word_mode == SImode)
17937 ? gen_rdsspsi (reg_ssp)
17938 : gen_rdsspdi (reg_ssp));
17939
17940 /* Compare through substraction the saved and the current ssp to decide
17941 if ssp has to be adjusted. */
17942 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
17943 ssp_slot));
17944 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
17945 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
17946 emit_insn (tmp);
17947
17948 /* Compare and jump over adjustment code. */
17949 noadj_label = gen_label_rtx ();
17950 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17951 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
17952 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
17953 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
17954 pc_rtx);
17955 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
17956 JUMP_LABEL (jump) = noadj_label;
17957
17958 /* Compute the numebr of frames to adjust. */
17959 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
17960 tmp = gen_rtx_SET (reg_adj,
17961 gen_rtx_LSHIFTRT (ptr_mode,
17962 negate_rtx (ptr_mode, reg_adj),
17963 GEN_INT ((word_mode == SImode)
17964 ? 2
17965 : 3)));
17966 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
17967 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
17968 emit_insn (tmp);
17969
17970 /* Check if number of frames <= 255 so no loop is needed. */
17971 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
17972 flags = gen_rtx_REG (CCmode, FLAGS_REG);
17973 emit_insn (gen_rtx_SET (flags, tmp));
17974
17975 inc_label = gen_label_rtx ();
17976 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
17977 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
17978 gen_rtx_LABEL_REF (VOIDmode, inc_label),
17979 pc_rtx);
17980 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
17981 JUMP_LABEL (jump) = inc_label;
17982
17983 rtx reg_255 = gen_reg_rtx (word_mode);
17984 emit_move_insn (reg_255, GEN_INT (255));
17985
17986 /* Adjust the ssp in a loop. */
17987 loop_label = gen_label_rtx ();
17988 emit_label (loop_label);
17989 LABEL_NUSES (loop_label) = 1;
17990
17991 emit_insn ((word_mode == SImode)
17992 ? gen_incsspsi (reg_255)
17993 : gen_incsspdi (reg_255));
17994 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
17995 reg_adj,
17996 GEN_INT (255)));
17997 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
17998 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
17999 emit_insn (tmp);
18000
18001 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18002 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18003 emit_insn (gen_rtx_SET (flags, tmp));
18004
18005 /* Jump to the loop label. */
18006 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18007 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18008 gen_rtx_LABEL_REF (VOIDmode, loop_label),
18009 pc_rtx);
18010 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18011 JUMP_LABEL (jump) = loop_label;
18012
18013 emit_label (inc_label);
18014 LABEL_NUSES (inc_label) = 1;
18015 emit_insn ((word_mode == SImode)
18016 ? gen_incsspsi (reg_ssp)
18017 : gen_incsspdi (reg_ssp));
18018
18019 emit_label (noadj_label);
18020 LABEL_NUSES (noadj_label) = 1;
18021 }
18022 else
18023 stack_slot = adjust_address (operands[1], Pmode, 0);
18024 emit_move_insn (operands[0], stack_slot);
18025 DONE;
18026 })
18027
18028
18029 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18030 ;; Do not split instructions with mask registers.
18031 (define_split
18032 [(set (match_operand 0 "general_reg_operand")
18033 (match_operator 3 "promotable_binary_operator"
18034 [(match_operand 1 "general_reg_operand")
18035 (match_operand 2 "aligned_operand")]))
18036 (clobber (reg:CC FLAGS_REG))]
18037 "! TARGET_PARTIAL_REG_STALL && reload_completed
18038 && ((GET_MODE (operands[0]) == HImode
18039 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18040 /* ??? next two lines just !satisfies_constraint_K (...) */
18041 || !CONST_INT_P (operands[2])
18042 || satisfies_constraint_K (operands[2])))
18043 || (GET_MODE (operands[0]) == QImode
18044 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18045 [(parallel [(set (match_dup 0)
18046 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18047 (clobber (reg:CC FLAGS_REG))])]
18048 {
18049 operands[0] = gen_lowpart (SImode, operands[0]);
18050 operands[1] = gen_lowpart (SImode, operands[1]);
18051 if (GET_CODE (operands[3]) != ASHIFT)
18052 operands[2] = gen_lowpart (SImode, operands[2]);
18053 operands[3] = shallow_copy_rtx (operands[3]);
18054 PUT_MODE (operands[3], SImode);
18055 })
18056
18057 ; Promote the QImode tests, as i386 has encoding of the AND
18058 ; instruction with 32-bit sign-extended immediate and thus the
18059 ; instruction size is unchanged, except in the %eax case for
18060 ; which it is increased by one byte, hence the ! optimize_size.
18061 (define_split
18062 [(set (match_operand 0 "flags_reg_operand")
18063 (match_operator 2 "compare_operator"
18064 [(and (match_operand 3 "aligned_operand")
18065 (match_operand 4 "const_int_operand"))
18066 (const_int 0)]))
18067 (set (match_operand 1 "register_operand")
18068 (and (match_dup 3) (match_dup 4)))]
18069 "! TARGET_PARTIAL_REG_STALL && reload_completed
18070 && optimize_insn_for_speed_p ()
18071 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18072 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18073 /* Ensure that the operand will remain sign-extended immediate. */
18074 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18075 [(parallel [(set (match_dup 0)
18076 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18077 (const_int 0)]))
18078 (set (match_dup 1)
18079 (and:SI (match_dup 3) (match_dup 4)))])]
18080 {
18081 operands[4]
18082 = gen_int_mode (INTVAL (operands[4])
18083 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18084 operands[1] = gen_lowpart (SImode, operands[1]);
18085 operands[3] = gen_lowpart (SImode, operands[3]);
18086 })
18087
18088 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18089 ; the TEST instruction with 32-bit sign-extended immediate and thus
18090 ; the instruction size would at least double, which is not what we
18091 ; want even with ! optimize_size.
18092 (define_split
18093 [(set (match_operand 0 "flags_reg_operand")
18094 (match_operator 1 "compare_operator"
18095 [(and (match_operand:HI 2 "aligned_operand")
18096 (match_operand:HI 3 "const_int_operand"))
18097 (const_int 0)]))]
18098 "! TARGET_PARTIAL_REG_STALL && reload_completed
18099 && ! TARGET_FAST_PREFIX
18100 && optimize_insn_for_speed_p ()
18101 /* Ensure that the operand will remain sign-extended immediate. */
18102 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18103 [(set (match_dup 0)
18104 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18105 (const_int 0)]))]
18106 {
18107 operands[3]
18108 = gen_int_mode (INTVAL (operands[3])
18109 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18110 operands[2] = gen_lowpart (SImode, operands[2]);
18111 })
18112
18113 (define_split
18114 [(set (match_operand 0 "register_operand")
18115 (neg (match_operand 1 "register_operand")))
18116 (clobber (reg:CC FLAGS_REG))]
18117 "! TARGET_PARTIAL_REG_STALL && reload_completed
18118 && (GET_MODE (operands[0]) == HImode
18119 || (GET_MODE (operands[0]) == QImode
18120 && (TARGET_PROMOTE_QImode
18121 || optimize_insn_for_size_p ())))"
18122 [(parallel [(set (match_dup 0)
18123 (neg:SI (match_dup 1)))
18124 (clobber (reg:CC FLAGS_REG))])]
18125 {
18126 operands[0] = gen_lowpart (SImode, operands[0]);
18127 operands[1] = gen_lowpart (SImode, operands[1]);
18128 })
18129
18130 ;; Do not split instructions with mask regs.
18131 (define_split
18132 [(set (match_operand 0 "general_reg_operand")
18133 (not (match_operand 1 "general_reg_operand")))]
18134 "! TARGET_PARTIAL_REG_STALL && reload_completed
18135 && (GET_MODE (operands[0]) == HImode
18136 || (GET_MODE (operands[0]) == QImode
18137 && (TARGET_PROMOTE_QImode
18138 || optimize_insn_for_size_p ())))"
18139 [(set (match_dup 0)
18140 (not:SI (match_dup 1)))]
18141 {
18142 operands[0] = gen_lowpart (SImode, operands[0]);
18143 operands[1] = gen_lowpart (SImode, operands[1]);
18144 })
18145 \f
18146 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18147 ;; transform a complex memory operation into two memory to register operations.
18148
18149 ;; Don't push memory operands
18150 (define_peephole2
18151 [(set (match_operand:SWI 0 "push_operand")
18152 (match_operand:SWI 1 "memory_operand"))
18153 (match_scratch:SWI 2 "<r>")]
18154 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18155 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18156 [(set (match_dup 2) (match_dup 1))
18157 (set (match_dup 0) (match_dup 2))])
18158
18159 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18160 ;; SImode pushes.
18161 (define_peephole2
18162 [(set (match_operand:SF 0 "push_operand")
18163 (match_operand:SF 1 "memory_operand"))
18164 (match_scratch:SF 2 "r")]
18165 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18166 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18167 [(set (match_dup 2) (match_dup 1))
18168 (set (match_dup 0) (match_dup 2))])
18169
18170 ;; Don't move an immediate directly to memory when the instruction
18171 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18172 (define_peephole2
18173 [(match_scratch:SWI124 1 "<r>")
18174 (set (match_operand:SWI124 0 "memory_operand")
18175 (const_int 0))]
18176 "optimize_insn_for_speed_p ()
18177 && ((<MODE>mode == HImode
18178 && TARGET_LCP_STALL)
18179 || (!TARGET_USE_MOV0
18180 && TARGET_SPLIT_LONG_MOVES
18181 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18182 && peep2_regno_dead_p (0, FLAGS_REG)"
18183 [(parallel [(set (match_dup 2) (const_int 0))
18184 (clobber (reg:CC FLAGS_REG))])
18185 (set (match_dup 0) (match_dup 1))]
18186 "operands[2] = gen_lowpart (SImode, operands[1]);")
18187
18188 (define_peephole2
18189 [(match_scratch:SWI124 2 "<r>")
18190 (set (match_operand:SWI124 0 "memory_operand")
18191 (match_operand:SWI124 1 "immediate_operand"))]
18192 "optimize_insn_for_speed_p ()
18193 && ((<MODE>mode == HImode
18194 && TARGET_LCP_STALL)
18195 || (TARGET_SPLIT_LONG_MOVES
18196 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18197 [(set (match_dup 2) (match_dup 1))
18198 (set (match_dup 0) (match_dup 2))])
18199
18200 ;; Don't compare memory with zero, load and use a test instead.
18201 (define_peephole2
18202 [(set (match_operand 0 "flags_reg_operand")
18203 (match_operator 1 "compare_operator"
18204 [(match_operand:SI 2 "memory_operand")
18205 (const_int 0)]))
18206 (match_scratch:SI 3 "r")]
18207 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18208 [(set (match_dup 3) (match_dup 2))
18209 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18210
18211 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18212 ;; Don't split NOTs with a displacement operand, because resulting XOR
18213 ;; will not be pairable anyway.
18214 ;;
18215 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18216 ;; represented using a modRM byte. The XOR replacement is long decoded,
18217 ;; so this split helps here as well.
18218 ;;
18219 ;; Note: Can't do this as a regular split because we can't get proper
18220 ;; lifetime information then.
18221
18222 (define_peephole2
18223 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18224 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18225 "optimize_insn_for_speed_p ()
18226 && ((TARGET_NOT_UNPAIRABLE
18227 && (!MEM_P (operands[0])
18228 || !memory_displacement_operand (operands[0], <MODE>mode)))
18229 || (TARGET_NOT_VECTORMODE
18230 && long_memory_operand (operands[0], <MODE>mode)))
18231 && peep2_regno_dead_p (0, FLAGS_REG)"
18232 [(parallel [(set (match_dup 0)
18233 (xor:SWI124 (match_dup 1) (const_int -1)))
18234 (clobber (reg:CC FLAGS_REG))])])
18235
18236 ;; Non pairable "test imm, reg" instructions can be translated to
18237 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18238 ;; byte opcode instead of two, have a short form for byte operands),
18239 ;; so do it for other CPUs as well. Given that the value was dead,
18240 ;; this should not create any new dependencies. Pass on the sub-word
18241 ;; versions if we're concerned about partial register stalls.
18242
18243 (define_peephole2
18244 [(set (match_operand 0 "flags_reg_operand")
18245 (match_operator 1 "compare_operator"
18246 [(and:SI (match_operand:SI 2 "register_operand")
18247 (match_operand:SI 3 "immediate_operand"))
18248 (const_int 0)]))]
18249 "ix86_match_ccmode (insn, CCNOmode)
18250 && (REGNO (operands[2]) != AX_REG
18251 || satisfies_constraint_K (operands[3]))
18252 && peep2_reg_dead_p (1, operands[2])"
18253 [(parallel
18254 [(set (match_dup 0)
18255 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18256 (const_int 0)]))
18257 (set (match_dup 2)
18258 (and:SI (match_dup 2) (match_dup 3)))])])
18259
18260 ;; We don't need to handle HImode case, because it will be promoted to SImode
18261 ;; on ! TARGET_PARTIAL_REG_STALL
18262
18263 (define_peephole2
18264 [(set (match_operand 0 "flags_reg_operand")
18265 (match_operator 1 "compare_operator"
18266 [(and:QI (match_operand:QI 2 "register_operand")
18267 (match_operand:QI 3 "immediate_operand"))
18268 (const_int 0)]))]
18269 "! TARGET_PARTIAL_REG_STALL
18270 && ix86_match_ccmode (insn, CCNOmode)
18271 && REGNO (operands[2]) != AX_REG
18272 && peep2_reg_dead_p (1, operands[2])"
18273 [(parallel
18274 [(set (match_dup 0)
18275 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18276 (const_int 0)]))
18277 (set (match_dup 2)
18278 (and:QI (match_dup 2) (match_dup 3)))])])
18279
18280 (define_peephole2
18281 [(set (match_operand 0 "flags_reg_operand")
18282 (match_operator 1 "compare_operator"
18283 [(and:QI
18284 (subreg:QI
18285 (zero_extract:SI (match_operand 2 "QIreg_operand")
18286 (const_int 8)
18287 (const_int 8)) 0)
18288 (match_operand 3 "const_int_operand"))
18289 (const_int 0)]))]
18290 "! TARGET_PARTIAL_REG_STALL
18291 && ix86_match_ccmode (insn, CCNOmode)
18292 && REGNO (operands[2]) != AX_REG
18293 && peep2_reg_dead_p (1, operands[2])"
18294 [(parallel
18295 [(set (match_dup 0)
18296 (match_op_dup 1
18297 [(and:QI
18298 (subreg:QI
18299 (zero_extract:SI (match_dup 2)
18300 (const_int 8)
18301 (const_int 8)) 0)
18302 (match_dup 3))
18303 (const_int 0)]))
18304 (set (zero_extract:SI (match_dup 2)
18305 (const_int 8)
18306 (const_int 8))
18307 (subreg:SI
18308 (and:QI
18309 (subreg:QI
18310 (zero_extract:SI (match_dup 2)
18311 (const_int 8)
18312 (const_int 8)) 0)
18313 (match_dup 3)) 0))])])
18314
18315 ;; Don't do logical operations with memory inputs.
18316 (define_peephole2
18317 [(match_scratch:SWI 2 "<r>")
18318 (parallel [(set (match_operand:SWI 0 "register_operand")
18319 (match_operator:SWI 3 "arith_or_logical_operator"
18320 [(match_dup 0)
18321 (match_operand:SWI 1 "memory_operand")]))
18322 (clobber (reg:CC FLAGS_REG))])]
18323 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18324 [(set (match_dup 2) (match_dup 1))
18325 (parallel [(set (match_dup 0)
18326 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18327 (clobber (reg:CC FLAGS_REG))])])
18328
18329 (define_peephole2
18330 [(match_scratch:SWI 2 "<r>")
18331 (parallel [(set (match_operand:SWI 0 "register_operand")
18332 (match_operator:SWI 3 "arith_or_logical_operator"
18333 [(match_operand:SWI 1 "memory_operand")
18334 (match_dup 0)]))
18335 (clobber (reg:CC FLAGS_REG))])]
18336 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18337 [(set (match_dup 2) (match_dup 1))
18338 (parallel [(set (match_dup 0)
18339 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18340 (clobber (reg:CC FLAGS_REG))])])
18341
18342 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
18343 ;; the memory address refers to the destination of the load!
18344
18345 (define_peephole2
18346 [(set (match_operand:SWI 0 "general_reg_operand")
18347 (match_operand:SWI 1 "general_reg_operand"))
18348 (parallel [(set (match_dup 0)
18349 (match_operator:SWI 3 "commutative_operator"
18350 [(match_dup 0)
18351 (match_operand:SWI 2 "memory_operand")]))
18352 (clobber (reg:CC FLAGS_REG))])]
18353 "REGNO (operands[0]) != REGNO (operands[1])
18354 && (<MODE>mode != QImode
18355 || any_QIreg_operand (operands[1], QImode))"
18356 [(set (match_dup 0) (match_dup 4))
18357 (parallel [(set (match_dup 0)
18358 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18359 (clobber (reg:CC FLAGS_REG))])]
18360 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18361
18362 (define_peephole2
18363 [(set (match_operand 0 "mmx_reg_operand")
18364 (match_operand 1 "mmx_reg_operand"))
18365 (set (match_dup 0)
18366 (match_operator 3 "commutative_operator"
18367 [(match_dup 0)
18368 (match_operand 2 "memory_operand")]))]
18369 "REGNO (operands[0]) != REGNO (operands[1])"
18370 [(set (match_dup 0) (match_dup 2))
18371 (set (match_dup 0)
18372 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18373
18374 (define_peephole2
18375 [(set (match_operand 0 "sse_reg_operand")
18376 (match_operand 1 "sse_reg_operand"))
18377 (set (match_dup 0)
18378 (match_operator 3 "commutative_operator"
18379 [(match_dup 0)
18380 (match_operand 2 "memory_operand")]))]
18381 "REGNO (operands[0]) != REGNO (operands[1])"
18382 [(set (match_dup 0) (match_dup 2))
18383 (set (match_dup 0)
18384 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18385
18386 ; Don't do logical operations with memory outputs
18387 ;
18388 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18389 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18390 ; the same decoder scheduling characteristics as the original.
18391
18392 (define_peephole2
18393 [(match_scratch:SWI 2 "<r>")
18394 (parallel [(set (match_operand:SWI 0 "memory_operand")
18395 (match_operator:SWI 3 "arith_or_logical_operator"
18396 [(match_dup 0)
18397 (match_operand:SWI 1 "<nonmemory_operand>")]))
18398 (clobber (reg:CC FLAGS_REG))])]
18399 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18400 [(set (match_dup 2) (match_dup 0))
18401 (parallel [(set (match_dup 2)
18402 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18403 (clobber (reg:CC FLAGS_REG))])
18404 (set (match_dup 0) (match_dup 2))])
18405
18406 (define_peephole2
18407 [(match_scratch:SWI 2 "<r>")
18408 (parallel [(set (match_operand:SWI 0 "memory_operand")
18409 (match_operator:SWI 3 "arith_or_logical_operator"
18410 [(match_operand:SWI 1 "<nonmemory_operand>")
18411 (match_dup 0)]))
18412 (clobber (reg:CC FLAGS_REG))])]
18413 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18414 [(set (match_dup 2) (match_dup 0))
18415 (parallel [(set (match_dup 2)
18416 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18417 (clobber (reg:CC FLAGS_REG))])
18418 (set (match_dup 0) (match_dup 2))])
18419
18420 ;; Attempt to use arith or logical operations with memory outputs with
18421 ;; setting of flags.
18422 (define_peephole2
18423 [(set (match_operand:SWI 0 "register_operand")
18424 (match_operand:SWI 1 "memory_operand"))
18425 (parallel [(set (match_dup 0)
18426 (match_operator:SWI 3 "plusminuslogic_operator"
18427 [(match_dup 0)
18428 (match_operand:SWI 2 "<nonmemory_operand>")]))
18429 (clobber (reg:CC FLAGS_REG))])
18430 (set (match_dup 1) (match_dup 0))
18431 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18432 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18433 && peep2_reg_dead_p (4, operands[0])
18434 && !reg_overlap_mentioned_p (operands[0], operands[1])
18435 && !reg_overlap_mentioned_p (operands[0], operands[2])
18436 && (<MODE>mode != QImode
18437 || immediate_operand (operands[2], QImode)
18438 || any_QIreg_operand (operands[2], QImode))
18439 && ix86_match_ccmode (peep2_next_insn (3),
18440 (GET_CODE (operands[3]) == PLUS
18441 || GET_CODE (operands[3]) == MINUS)
18442 ? CCGOCmode : CCNOmode)"
18443 [(parallel [(set (match_dup 4) (match_dup 6))
18444 (set (match_dup 1) (match_dup 5))])]
18445 {
18446 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18447 operands[5]
18448 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18449 copy_rtx (operands[1]),
18450 operands[2]);
18451 operands[6]
18452 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18453 copy_rtx (operands[5]),
18454 const0_rtx);
18455 })
18456
18457 ;; Likewise for cmpelim optimized pattern.
18458 (define_peephole2
18459 [(set (match_operand:SWI 0 "register_operand")
18460 (match_operand:SWI 1 "memory_operand"))
18461 (parallel [(set (reg FLAGS_REG)
18462 (compare (match_operator:SWI 3 "plusminuslogic_operator"
18463 [(match_dup 0)
18464 (match_operand:SWI 2 "<nonmemory_operand>")])
18465 (const_int 0)))
18466 (set (match_dup 0) (match_dup 3))])
18467 (set (match_dup 1) (match_dup 0))]
18468 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18469 && peep2_reg_dead_p (3, operands[0])
18470 && !reg_overlap_mentioned_p (operands[0], operands[1])
18471 && !reg_overlap_mentioned_p (operands[0], operands[2])
18472 && ix86_match_ccmode (peep2_next_insn (1),
18473 (GET_CODE (operands[3]) == PLUS
18474 || GET_CODE (operands[3]) == MINUS)
18475 ? CCGOCmode : CCNOmode)"
18476 [(parallel [(set (match_dup 4) (match_dup 6))
18477 (set (match_dup 1) (match_dup 5))])]
18478 {
18479 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
18480 operands[5]
18481 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18482 copy_rtx (operands[1]), operands[2]);
18483 operands[6]
18484 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
18485 const0_rtx);
18486 })
18487
18488 ;; Likewise for instances where we have a lea pattern.
18489 (define_peephole2
18490 [(set (match_operand:SWI 0 "register_operand")
18491 (match_operand:SWI 1 "memory_operand"))
18492 (set (match_operand:<LEAMODE> 3 "register_operand")
18493 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
18494 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
18495 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
18496 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
18497 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18498 && REGNO (operands[4]) == REGNO (operands[0])
18499 && REGNO (operands[5]) == REGNO (operands[3])
18500 && peep2_reg_dead_p (4, operands[3])
18501 && ((REGNO (operands[0]) == REGNO (operands[3]))
18502 || peep2_reg_dead_p (2, operands[0]))
18503 && !reg_overlap_mentioned_p (operands[0], operands[1])
18504 && !reg_overlap_mentioned_p (operands[3], operands[1])
18505 && !reg_overlap_mentioned_p (operands[0], operands[2])
18506 && (<MODE>mode != QImode
18507 || immediate_operand (operands[2], QImode)
18508 || any_QIreg_operand (operands[2], QImode))
18509 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18510 [(parallel [(set (match_dup 6) (match_dup 8))
18511 (set (match_dup 1) (match_dup 7))])]
18512 {
18513 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
18514 operands[7]
18515 = gen_rtx_PLUS (<MODE>mode,
18516 copy_rtx (operands[1]),
18517 gen_lowpart (<MODE>mode, operands[2]));
18518 operands[8]
18519 = gen_rtx_COMPARE (GET_MODE (operands[6]),
18520 copy_rtx (operands[7]),
18521 const0_rtx);
18522 })
18523
18524 (define_peephole2
18525 [(parallel [(set (match_operand:SWI 0 "register_operand")
18526 (match_operator:SWI 2 "plusminuslogic_operator"
18527 [(match_dup 0)
18528 (match_operand:SWI 1 "memory_operand")]))
18529 (clobber (reg:CC FLAGS_REG))])
18530 (set (match_dup 1) (match_dup 0))
18531 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18532 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18533 && COMMUTATIVE_ARITH_P (operands[2])
18534 && peep2_reg_dead_p (3, operands[0])
18535 && !reg_overlap_mentioned_p (operands[0], operands[1])
18536 && ix86_match_ccmode (peep2_next_insn (2),
18537 GET_CODE (operands[2]) == PLUS
18538 ? CCGOCmode : CCNOmode)"
18539 [(parallel [(set (match_dup 3) (match_dup 5))
18540 (set (match_dup 1) (match_dup 4))])]
18541 {
18542 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18543 operands[4]
18544 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18545 copy_rtx (operands[1]),
18546 operands[0]);
18547 operands[5]
18548 = gen_rtx_COMPARE (GET_MODE (operands[3]),
18549 copy_rtx (operands[4]),
18550 const0_rtx);
18551 })
18552
18553 ;; Likewise for cmpelim optimized pattern.
18554 (define_peephole2
18555 [(parallel [(set (reg FLAGS_REG)
18556 (compare (match_operator:SWI 2 "plusminuslogic_operator"
18557 [(match_operand:SWI 0 "register_operand")
18558 (match_operand:SWI 1 "memory_operand")])
18559 (const_int 0)))
18560 (set (match_dup 0) (match_dup 2))])
18561 (set (match_dup 1) (match_dup 0))]
18562 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18563 && COMMUTATIVE_ARITH_P (operands[2])
18564 && peep2_reg_dead_p (2, operands[0])
18565 && !reg_overlap_mentioned_p (operands[0], operands[1])
18566 && ix86_match_ccmode (peep2_next_insn (0),
18567 GET_CODE (operands[2]) == PLUS
18568 ? CCGOCmode : CCNOmode)"
18569 [(parallel [(set (match_dup 3) (match_dup 5))
18570 (set (match_dup 1) (match_dup 4))])]
18571 {
18572 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
18573 operands[4]
18574 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18575 copy_rtx (operands[1]), operands[0]);
18576 operands[5]
18577 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
18578 const0_rtx);
18579 })
18580
18581 (define_peephole2
18582 [(set (match_operand:SWI12 0 "register_operand")
18583 (match_operand:SWI12 1 "memory_operand"))
18584 (parallel [(set (match_operand:SI 4 "register_operand")
18585 (match_operator:SI 3 "plusminuslogic_operator"
18586 [(match_dup 4)
18587 (match_operand:SI 2 "nonmemory_operand")]))
18588 (clobber (reg:CC FLAGS_REG))])
18589 (set (match_dup 1) (match_dup 0))
18590 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18591 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18592 && REGNO (operands[0]) == REGNO (operands[4])
18593 && peep2_reg_dead_p (4, operands[0])
18594 && (<MODE>mode != QImode
18595 || immediate_operand (operands[2], SImode)
18596 || any_QIreg_operand (operands[2], SImode))
18597 && !reg_overlap_mentioned_p (operands[0], operands[1])
18598 && !reg_overlap_mentioned_p (operands[0], operands[2])
18599 && ix86_match_ccmode (peep2_next_insn (3),
18600 (GET_CODE (operands[3]) == PLUS
18601 || GET_CODE (operands[3]) == MINUS)
18602 ? CCGOCmode : CCNOmode)"
18603 [(parallel [(set (match_dup 5) (match_dup 7))
18604 (set (match_dup 1) (match_dup 6))])]
18605 {
18606 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
18607 operands[6]
18608 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18609 copy_rtx (operands[1]),
18610 gen_lowpart (<MODE>mode, operands[2]));
18611 operands[7]
18612 = gen_rtx_COMPARE (GET_MODE (operands[5]),
18613 copy_rtx (operands[6]),
18614 const0_rtx);
18615 })
18616
18617 ;; peephole2 comes before regcprop, so deal also with a case that
18618 ;; would be cleaned up by regcprop.
18619 (define_peephole2
18620 [(set (match_operand:SWI 0 "register_operand")
18621 (match_operand:SWI 1 "memory_operand"))
18622 (parallel [(set (match_dup 0)
18623 (match_operator:SWI 3 "plusminuslogic_operator"
18624 [(match_dup 0)
18625 (match_operand:SWI 2 "<nonmemory_operand>")]))
18626 (clobber (reg:CC FLAGS_REG))])
18627 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
18628 (set (match_dup 1) (match_dup 4))
18629 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
18630 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18631 && peep2_reg_dead_p (3, operands[0])
18632 && peep2_reg_dead_p (5, operands[4])
18633 && !reg_overlap_mentioned_p (operands[0], operands[1])
18634 && !reg_overlap_mentioned_p (operands[0], operands[2])
18635 && !reg_overlap_mentioned_p (operands[4], operands[1])
18636 && (<MODE>mode != QImode
18637 || immediate_operand (operands[2], QImode)
18638 || any_QIreg_operand (operands[2], QImode))
18639 && ix86_match_ccmode (peep2_next_insn (4),
18640 (GET_CODE (operands[3]) == PLUS
18641 || GET_CODE (operands[3]) == MINUS)
18642 ? CCGOCmode : CCNOmode)"
18643 [(parallel [(set (match_dup 5) (match_dup 7))
18644 (set (match_dup 1) (match_dup 6))])]
18645 {
18646 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
18647 operands[6]
18648 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18649 copy_rtx (operands[1]),
18650 operands[2]);
18651 operands[7]
18652 = gen_rtx_COMPARE (GET_MODE (operands[5]),
18653 copy_rtx (operands[6]),
18654 const0_rtx);
18655 })
18656
18657 (define_peephole2
18658 [(set (match_operand:SWI12 0 "register_operand")
18659 (match_operand:SWI12 1 "memory_operand"))
18660 (parallel [(set (match_operand:SI 4 "register_operand")
18661 (match_operator:SI 3 "plusminuslogic_operator"
18662 [(match_dup 4)
18663 (match_operand:SI 2 "nonmemory_operand")]))
18664 (clobber (reg:CC FLAGS_REG))])
18665 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
18666 (set (match_dup 1) (match_dup 5))
18667 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
18668 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18669 && REGNO (operands[0]) == REGNO (operands[4])
18670 && peep2_reg_dead_p (3, operands[0])
18671 && peep2_reg_dead_p (5, operands[5])
18672 && (<MODE>mode != QImode
18673 || immediate_operand (operands[2], SImode)
18674 || any_QIreg_operand (operands[2], SImode))
18675 && !reg_overlap_mentioned_p (operands[0], operands[1])
18676 && !reg_overlap_mentioned_p (operands[0], operands[2])
18677 && !reg_overlap_mentioned_p (operands[5], operands[1])
18678 && ix86_match_ccmode (peep2_next_insn (4),
18679 (GET_CODE (operands[3]) == PLUS
18680 || GET_CODE (operands[3]) == MINUS)
18681 ? CCGOCmode : CCNOmode)"
18682 [(parallel [(set (match_dup 6) (match_dup 8))
18683 (set (match_dup 1) (match_dup 7))])]
18684 {
18685 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
18686 operands[7]
18687 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18688 copy_rtx (operands[1]),
18689 gen_lowpart (<MODE>mode, operands[2]));
18690 operands[8]
18691 = gen_rtx_COMPARE (GET_MODE (operands[6]),
18692 copy_rtx (operands[7]),
18693 const0_rtx);
18694 })
18695
18696 ;; Likewise for cmpelim optimized pattern.
18697 (define_peephole2
18698 [(set (match_operand:SWI 0 "register_operand")
18699 (match_operand:SWI 1 "memory_operand"))
18700 (parallel [(set (reg FLAGS_REG)
18701 (compare (match_operator:SWI 3 "plusminuslogic_operator"
18702 [(match_dup 0)
18703 (match_operand:SWI 2 "<nonmemory_operand>")])
18704 (const_int 0)))
18705 (set (match_dup 0) (match_dup 3))])
18706 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
18707 (set (match_dup 1) (match_dup 4))]
18708 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18709 && peep2_reg_dead_p (3, operands[0])
18710 && peep2_reg_dead_p (4, operands[4])
18711 && !reg_overlap_mentioned_p (operands[0], operands[1])
18712 && !reg_overlap_mentioned_p (operands[0], operands[2])
18713 && !reg_overlap_mentioned_p (operands[4], operands[1])
18714 && ix86_match_ccmode (peep2_next_insn (1),
18715 (GET_CODE (operands[3]) == PLUS
18716 || GET_CODE (operands[3]) == MINUS)
18717 ? CCGOCmode : CCNOmode)"
18718 [(parallel [(set (match_dup 5) (match_dup 7))
18719 (set (match_dup 1) (match_dup 6))])]
18720 {
18721 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
18722 operands[6]
18723 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18724 copy_rtx (operands[1]), operands[2]);
18725 operands[7]
18726 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
18727 const0_rtx);
18728 })
18729
18730 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
18731 ;; into x = z; x ^= y; x != z
18732 (define_peephole2
18733 [(set (match_operand:SWI 0 "register_operand")
18734 (match_operand:SWI 1 "memory_operand"))
18735 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
18736 (parallel [(set (match_operand:SWI 4 "register_operand")
18737 (xor:SWI (match_dup 4)
18738 (match_operand:SWI 2 "<nonmemory_operand>")))
18739 (clobber (reg:CC FLAGS_REG))])
18740 (set (match_dup 1) (match_dup 4))
18741 (set (reg:CCZ FLAGS_REG)
18742 (compare:CCZ (match_operand:SWI 5 "register_operand")
18743 (match_operand:SWI 6 "<nonmemory_operand>")))]
18744 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18745 && (REGNO (operands[4]) == REGNO (operands[0])
18746 || REGNO (operands[4]) == REGNO (operands[3]))
18747 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
18748 ? 3 : 0], operands[5])
18749 ? rtx_equal_p (operands[2], operands[6])
18750 : rtx_equal_p (operands[2], operands[5])
18751 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
18752 ? 3 : 0], operands[6]))
18753 && peep2_reg_dead_p (4, operands[4])
18754 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
18755 ? 3 : 0])
18756 && !reg_overlap_mentioned_p (operands[0], operands[1])
18757 && !reg_overlap_mentioned_p (operands[0], operands[2])
18758 && !reg_overlap_mentioned_p (operands[3], operands[0])
18759 && !reg_overlap_mentioned_p (operands[3], operands[1])
18760 && !reg_overlap_mentioned_p (operands[3], operands[2])
18761 && (<MODE>mode != QImode
18762 || immediate_operand (operands[2], QImode)
18763 || any_QIreg_operand (operands[2], QImode))"
18764 [(parallel [(set (match_dup 7) (match_dup 9))
18765 (set (match_dup 1) (match_dup 8))])]
18766 {
18767 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
18768 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
18769 operands[2]);
18770 operands[9]
18771 = gen_rtx_COMPARE (GET_MODE (operands[7]),
18772 copy_rtx (operands[8]),
18773 const0_rtx);
18774 })
18775
18776 (define_peephole2
18777 [(set (match_operand:SWI12 0 "register_operand")
18778 (match_operand:SWI12 1 "memory_operand"))
18779 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
18780 (parallel [(set (match_operand:SI 4 "register_operand")
18781 (xor:SI (match_dup 4)
18782 (match_operand:SI 2 "<nonmemory_operand>")))
18783 (clobber (reg:CC FLAGS_REG))])
18784 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
18785 (set (reg:CCZ FLAGS_REG)
18786 (compare:CCZ (match_operand:SWI12 6 "register_operand")
18787 (match_operand:SWI12 7 "<nonmemory_operand>")))]
18788 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18789 && (REGNO (operands[5]) == REGNO (operands[0])
18790 || REGNO (operands[5]) == REGNO (operands[3]))
18791 && REGNO (operands[5]) == REGNO (operands[4])
18792 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
18793 ? 3 : 0], operands[6])
18794 ? (REG_P (operands[2])
18795 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
18796 : rtx_equal_p (operands[2], operands[7]))
18797 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
18798 ? 3 : 0], operands[7])
18799 && REG_P (operands[2])
18800 && REGNO (operands[2]) == REGNO (operands[6])))
18801 && peep2_reg_dead_p (4, operands[5])
18802 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
18803 ? 3 : 0])
18804 && !reg_overlap_mentioned_p (operands[0], operands[1])
18805 && !reg_overlap_mentioned_p (operands[0], operands[2])
18806 && !reg_overlap_mentioned_p (operands[3], operands[0])
18807 && !reg_overlap_mentioned_p (operands[3], operands[1])
18808 && !reg_overlap_mentioned_p (operands[3], operands[2])
18809 && (<MODE>mode != QImode
18810 || immediate_operand (operands[2], SImode)
18811 || any_QIreg_operand (operands[2], SImode))"
18812 [(parallel [(set (match_dup 8) (match_dup 10))
18813 (set (match_dup 1) (match_dup 9))])]
18814 {
18815 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
18816 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
18817 gen_lowpart (<MODE>mode, operands[2]));
18818 operands[10]
18819 = gen_rtx_COMPARE (GET_MODE (operands[8]),
18820 copy_rtx (operands[9]),
18821 const0_rtx);
18822 })
18823
18824 ;; Attempt to optimize away memory stores of values the memory already
18825 ;; has. See PR79593.
18826 (define_peephole2
18827 [(set (match_operand 0 "register_operand")
18828 (match_operand 1 "memory_operand"))
18829 (set (match_operand 2 "memory_operand") (match_dup 0))]
18830 "!MEM_VOLATILE_P (operands[1])
18831 && !MEM_VOLATILE_P (operands[2])
18832 && rtx_equal_p (operands[1], operands[2])
18833 && !reg_overlap_mentioned_p (operands[0], operands[2])"
18834 [(set (match_dup 0) (match_dup 1))])
18835
18836 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18837 (define_peephole2
18838 [(set (match_operand 0 "general_reg_operand")
18839 (match_operand 1 "const0_operand"))]
18840 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18841 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18842 && peep2_regno_dead_p (0, FLAGS_REG)"
18843 [(parallel [(set (match_dup 0) (const_int 0))
18844 (clobber (reg:CC FLAGS_REG))])]
18845 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18846
18847 (define_peephole2
18848 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18849 (const_int 0))]
18850 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18851 && peep2_regno_dead_p (0, FLAGS_REG)"
18852 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18853 (clobber (reg:CC FLAGS_REG))])])
18854
18855 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18856 (define_peephole2
18857 [(set (match_operand:SWI248 0 "general_reg_operand")
18858 (const_int -1))]
18859 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18860 && peep2_regno_dead_p (0, FLAGS_REG)"
18861 [(parallel [(set (match_dup 0) (const_int -1))
18862 (clobber (reg:CC FLAGS_REG))])]
18863 {
18864 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18865 operands[0] = gen_lowpart (SImode, operands[0]);
18866 })
18867
18868 ;; Attempt to convert simple lea to add/shift.
18869 ;; These can be created by move expanders.
18870 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18871 ;; relevant lea instructions were already split.
18872
18873 (define_peephole2
18874 [(set (match_operand:SWI48 0 "register_operand")
18875 (plus:SWI48 (match_dup 0)
18876 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18877 "!TARGET_OPT_AGU
18878 && peep2_regno_dead_p (0, FLAGS_REG)"
18879 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18880 (clobber (reg:CC FLAGS_REG))])])
18881
18882 (define_peephole2
18883 [(set (match_operand:SWI48 0 "register_operand")
18884 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18885 (match_dup 0)))]
18886 "!TARGET_OPT_AGU
18887 && peep2_regno_dead_p (0, FLAGS_REG)"
18888 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18889 (clobber (reg:CC FLAGS_REG))])])
18890
18891 (define_peephole2
18892 [(set (match_operand:DI 0 "register_operand")
18893 (zero_extend:DI
18894 (plus:SI (match_operand:SI 1 "register_operand")
18895 (match_operand:SI 2 "nonmemory_operand"))))]
18896 "TARGET_64BIT && !TARGET_OPT_AGU
18897 && REGNO (operands[0]) == REGNO (operands[1])
18898 && peep2_regno_dead_p (0, FLAGS_REG)"
18899 [(parallel [(set (match_dup 0)
18900 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18901 (clobber (reg:CC FLAGS_REG))])])
18902
18903 (define_peephole2
18904 [(set (match_operand:DI 0 "register_operand")
18905 (zero_extend:DI
18906 (plus:SI (match_operand:SI 1 "nonmemory_operand")
18907 (match_operand:SI 2 "register_operand"))))]
18908 "TARGET_64BIT && !TARGET_OPT_AGU
18909 && REGNO (operands[0]) == REGNO (operands[2])
18910 && peep2_regno_dead_p (0, FLAGS_REG)"
18911 [(parallel [(set (match_dup 0)
18912 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18913 (clobber (reg:CC FLAGS_REG))])])
18914
18915 (define_peephole2
18916 [(set (match_operand:SWI48 0 "register_operand")
18917 (mult:SWI48 (match_dup 0)
18918 (match_operand:SWI48 1 "const_int_operand")))]
18919 "pow2p_hwi (INTVAL (operands[1]))
18920 && peep2_regno_dead_p (0, FLAGS_REG)"
18921 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18922 (clobber (reg:CC FLAGS_REG))])]
18923 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18924
18925 (define_peephole2
18926 [(set (match_operand:DI 0 "register_operand")
18927 (zero_extend:DI
18928 (mult:SI (match_operand:SI 1 "register_operand")
18929 (match_operand:SI 2 "const_int_operand"))))]
18930 "TARGET_64BIT
18931 && pow2p_hwi (INTVAL (operands[2]))
18932 && REGNO (operands[0]) == REGNO (operands[1])
18933 && peep2_regno_dead_p (0, FLAGS_REG)"
18934 [(parallel [(set (match_dup 0)
18935 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18936 (clobber (reg:CC FLAGS_REG))])]
18937 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18938
18939 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18940 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18941 ;; On many CPUs it is also faster, since special hardware to avoid esp
18942 ;; dependencies is present.
18943
18944 ;; While some of these conversions may be done using splitters, we use
18945 ;; peepholes in order to allow combine_stack_adjustments pass to see
18946 ;; nonobfuscated RTL.
18947
18948 ;; Convert prologue esp subtractions to push.
18949 ;; We need register to push. In order to keep verify_flow_info happy we have
18950 ;; two choices
18951 ;; - use scratch and clobber it in order to avoid dependencies
18952 ;; - use already live register
18953 ;; We can't use the second way right now, since there is no reliable way how to
18954 ;; verify that given register is live. First choice will also most likely in
18955 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18956 ;; call clobbered registers are dead. We may want to use base pointer as an
18957 ;; alternative when no register is available later.
18958
18959 (define_peephole2
18960 [(match_scratch:W 1 "r")
18961 (parallel [(set (reg:P SP_REG)
18962 (plus:P (reg:P SP_REG)
18963 (match_operand:P 0 "const_int_operand")))
18964 (clobber (reg:CC FLAGS_REG))
18965 (clobber (mem:BLK (scratch)))])]
18966 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18967 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18968 && ix86_red_zone_size == 0"
18969 [(clobber (match_dup 1))
18970 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18971 (clobber (mem:BLK (scratch)))])])
18972
18973 (define_peephole2
18974 [(match_scratch:W 1 "r")
18975 (parallel [(set (reg:P SP_REG)
18976 (plus:P (reg:P SP_REG)
18977 (match_operand:P 0 "const_int_operand")))
18978 (clobber (reg:CC FLAGS_REG))
18979 (clobber (mem:BLK (scratch)))])]
18980 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18981 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18982 && ix86_red_zone_size == 0"
18983 [(clobber (match_dup 1))
18984 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18985 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18986 (clobber (mem:BLK (scratch)))])])
18987
18988 ;; Convert esp subtractions to push.
18989 (define_peephole2
18990 [(match_scratch:W 1 "r")
18991 (parallel [(set (reg:P SP_REG)
18992 (plus:P (reg:P SP_REG)
18993 (match_operand:P 0 "const_int_operand")))
18994 (clobber (reg:CC FLAGS_REG))])]
18995 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18996 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18997 && ix86_red_zone_size == 0"
18998 [(clobber (match_dup 1))
18999 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19000
19001 (define_peephole2
19002 [(match_scratch:W 1 "r")
19003 (parallel [(set (reg:P SP_REG)
19004 (plus:P (reg:P SP_REG)
19005 (match_operand:P 0 "const_int_operand")))
19006 (clobber (reg:CC FLAGS_REG))])]
19007 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19008 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19009 && ix86_red_zone_size == 0"
19010 [(clobber (match_dup 1))
19011 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19012 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19013
19014 ;; Convert epilogue deallocator to pop.
19015 (define_peephole2
19016 [(match_scratch:W 1 "r")
19017 (parallel [(set (reg:P SP_REG)
19018 (plus:P (reg:P SP_REG)
19019 (match_operand:P 0 "const_int_operand")))
19020 (clobber (reg:CC FLAGS_REG))
19021 (clobber (mem:BLK (scratch)))])]
19022 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19023 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19024 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19025 (clobber (mem:BLK (scratch)))])])
19026
19027 ;; Two pops case is tricky, since pop causes dependency
19028 ;; on destination register. We use two registers if available.
19029 (define_peephole2
19030 [(match_scratch:W 1 "r")
19031 (match_scratch:W 2 "r")
19032 (parallel [(set (reg:P SP_REG)
19033 (plus:P (reg:P SP_REG)
19034 (match_operand:P 0 "const_int_operand")))
19035 (clobber (reg:CC FLAGS_REG))
19036 (clobber (mem:BLK (scratch)))])]
19037 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19038 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19039 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19040 (clobber (mem:BLK (scratch)))])
19041 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19042
19043 (define_peephole2
19044 [(match_scratch:W 1 "r")
19045 (parallel [(set (reg:P SP_REG)
19046 (plus:P (reg:P SP_REG)
19047 (match_operand:P 0 "const_int_operand")))
19048 (clobber (reg:CC FLAGS_REG))
19049 (clobber (mem:BLK (scratch)))])]
19050 "optimize_insn_for_size_p ()
19051 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19052 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19053 (clobber (mem:BLK (scratch)))])
19054 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19055
19056 ;; Convert esp additions to pop.
19057 (define_peephole2
19058 [(match_scratch:W 1 "r")
19059 (parallel [(set (reg:P SP_REG)
19060 (plus:P (reg:P SP_REG)
19061 (match_operand:P 0 "const_int_operand")))
19062 (clobber (reg:CC FLAGS_REG))])]
19063 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19064 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19065
19066 ;; Two pops case is tricky, since pop causes dependency
19067 ;; on destination register. We use two registers if available.
19068 (define_peephole2
19069 [(match_scratch:W 1 "r")
19070 (match_scratch:W 2 "r")
19071 (parallel [(set (reg:P SP_REG)
19072 (plus:P (reg:P SP_REG)
19073 (match_operand:P 0 "const_int_operand")))
19074 (clobber (reg:CC FLAGS_REG))])]
19075 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19076 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19077 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19078
19079 (define_peephole2
19080 [(match_scratch:W 1 "r")
19081 (parallel [(set (reg:P SP_REG)
19082 (plus:P (reg:P SP_REG)
19083 (match_operand:P 0 "const_int_operand")))
19084 (clobber (reg:CC FLAGS_REG))])]
19085 "optimize_insn_for_size_p ()
19086 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19087 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19088 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19089 \f
19090 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19091 ;; required and register dies. Similarly for 128 to -128.
19092 (define_peephole2
19093 [(set (match_operand 0 "flags_reg_operand")
19094 (match_operator 1 "compare_operator"
19095 [(match_operand 2 "register_operand")
19096 (match_operand 3 "const_int_operand")]))]
19097 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19098 && incdec_operand (operands[3], GET_MODE (operands[3])))
19099 || (!TARGET_FUSE_CMP_AND_BRANCH
19100 && INTVAL (operands[3]) == 128))
19101 && ix86_match_ccmode (insn, CCGCmode)
19102 && peep2_reg_dead_p (1, operands[2])"
19103 [(parallel [(set (match_dup 0)
19104 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19105 (clobber (match_dup 2))])])
19106 \f
19107 ;; Convert imul by three, five and nine into lea
19108 (define_peephole2
19109 [(parallel
19110 [(set (match_operand:SWI48 0 "register_operand")
19111 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19112 (match_operand:SWI48 2 "const359_operand")))
19113 (clobber (reg:CC FLAGS_REG))])]
19114 "!TARGET_PARTIAL_REG_STALL
19115 || <MODE>mode == SImode
19116 || optimize_function_for_size_p (cfun)"
19117 [(set (match_dup 0)
19118 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19119 (match_dup 1)))]
19120 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19121
19122 (define_peephole2
19123 [(parallel
19124 [(set (match_operand:SWI48 0 "register_operand")
19125 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19126 (match_operand:SWI48 2 "const359_operand")))
19127 (clobber (reg:CC FLAGS_REG))])]
19128 "optimize_insn_for_speed_p ()
19129 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19130 [(set (match_dup 0) (match_dup 1))
19131 (set (match_dup 0)
19132 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19133 (match_dup 0)))]
19134 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19135
19136 ;; imul $32bit_imm, mem, reg is vector decoded, while
19137 ;; imul $32bit_imm, reg, reg is direct decoded.
19138 (define_peephole2
19139 [(match_scratch:SWI48 3 "r")
19140 (parallel [(set (match_operand:SWI48 0 "register_operand")
19141 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19142 (match_operand:SWI48 2 "immediate_operand")))
19143 (clobber (reg:CC FLAGS_REG))])]
19144 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19145 && !satisfies_constraint_K (operands[2])"
19146 [(set (match_dup 3) (match_dup 1))
19147 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19148 (clobber (reg:CC FLAGS_REG))])])
19149
19150 (define_peephole2
19151 [(match_scratch:SI 3 "r")
19152 (parallel [(set (match_operand:DI 0 "register_operand")
19153 (zero_extend:DI
19154 (mult:SI (match_operand:SI 1 "memory_operand")
19155 (match_operand:SI 2 "immediate_operand"))))
19156 (clobber (reg:CC FLAGS_REG))])]
19157 "TARGET_64BIT
19158 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19159 && !satisfies_constraint_K (operands[2])"
19160 [(set (match_dup 3) (match_dup 1))
19161 (parallel [(set (match_dup 0)
19162 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19163 (clobber (reg:CC FLAGS_REG))])])
19164
19165 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19166 ;; Convert it into imul reg, reg
19167 ;; It would be better to force assembler to encode instruction using long
19168 ;; immediate, but there is apparently no way to do so.
19169 (define_peephole2
19170 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19171 (mult:SWI248
19172 (match_operand:SWI248 1 "nonimmediate_operand")
19173 (match_operand:SWI248 2 "const_int_operand")))
19174 (clobber (reg:CC FLAGS_REG))])
19175 (match_scratch:SWI248 3 "r")]
19176 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19177 && satisfies_constraint_K (operands[2])"
19178 [(set (match_dup 3) (match_dup 2))
19179 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19180 (clobber (reg:CC FLAGS_REG))])]
19181 {
19182 if (!rtx_equal_p (operands[0], operands[1]))
19183 emit_move_insn (operands[0], operands[1]);
19184 })
19185
19186 ;; After splitting up read-modify operations, array accesses with memory
19187 ;; operands might end up in form:
19188 ;; sall $2, %eax
19189 ;; movl 4(%esp), %edx
19190 ;; addl %edx, %eax
19191 ;; instead of pre-splitting:
19192 ;; sall $2, %eax
19193 ;; addl 4(%esp), %eax
19194 ;; Turn it into:
19195 ;; movl 4(%esp), %edx
19196 ;; leal (%edx,%eax,4), %eax
19197
19198 (define_peephole2
19199 [(match_scratch:W 5 "r")
19200 (parallel [(set (match_operand 0 "register_operand")
19201 (ashift (match_operand 1 "register_operand")
19202 (match_operand 2 "const_int_operand")))
19203 (clobber (reg:CC FLAGS_REG))])
19204 (parallel [(set (match_operand 3 "register_operand")
19205 (plus (match_dup 0)
19206 (match_operand 4 "x86_64_general_operand")))
19207 (clobber (reg:CC FLAGS_REG))])]
19208 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19209 /* Validate MODE for lea. */
19210 && ((!TARGET_PARTIAL_REG_STALL
19211 && (GET_MODE (operands[0]) == QImode
19212 || GET_MODE (operands[0]) == HImode))
19213 || GET_MODE (operands[0]) == SImode
19214 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19215 && (rtx_equal_p (operands[0], operands[3])
19216 || peep2_reg_dead_p (2, operands[0]))
19217 /* We reorder load and the shift. */
19218 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19219 [(set (match_dup 5) (match_dup 4))
19220 (set (match_dup 0) (match_dup 1))]
19221 {
19222 machine_mode op1mode = GET_MODE (operands[1]);
19223 machine_mode mode = op1mode == DImode ? DImode : SImode;
19224 int scale = 1 << INTVAL (operands[2]);
19225 rtx index = gen_lowpart (word_mode, operands[1]);
19226 rtx base = gen_lowpart (word_mode, operands[5]);
19227 rtx dest = gen_lowpart (mode, operands[3]);
19228
19229 operands[1] = gen_rtx_PLUS (word_mode, base,
19230 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19231 if (mode != word_mode)
19232 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19233
19234 operands[5] = base;
19235 if (op1mode != word_mode)
19236 operands[5] = gen_lowpart (op1mode, operands[5]);
19237
19238 operands[0] = dest;
19239 })
19240 \f
19241 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19242 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19243 ;; caught for use by garbage collectors and the like. Using an insn that
19244 ;; maps to SIGILL makes it more likely the program will rightfully die.
19245 ;; Keeping with tradition, "6" is in honor of #UD.
19246 (define_insn "trap"
19247 [(trap_if (const_int 1) (const_int 6))]
19248 ""
19249 {
19250 #ifdef HAVE_AS_IX86_UD2
19251 return "ud2";
19252 #else
19253 return ASM_SHORT "0x0b0f";
19254 #endif
19255 }
19256 [(set_attr "length" "2")])
19257
19258 (define_insn "ud2"
19259 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19260 ""
19261 {
19262 #ifdef HAVE_AS_IX86_UD2
19263 return "ud2";
19264 #else
19265 return ASM_SHORT "0x0b0f";
19266 #endif
19267 }
19268 [(set_attr "length" "2")])
19269
19270 (define_expand "prefetch"
19271 [(prefetch (match_operand 0 "address_operand")
19272 (match_operand:SI 1 "const_int_operand")
19273 (match_operand:SI 2 "const_int_operand"))]
19274 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19275 {
19276 bool write = INTVAL (operands[1]) != 0;
19277 int locality = INTVAL (operands[2]);
19278
19279 gcc_assert (IN_RANGE (locality, 0, 3));
19280
19281 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19282 supported by SSE counterpart (non-SSE2 athlon machines) or the
19283 SSE prefetch is not available (K6 machines). Otherwise use SSE
19284 prefetch as it allows specifying of locality. */
19285
19286 if (write)
19287 {
19288 if (TARGET_PREFETCHWT1)
19289 operands[2] = GEN_INT (MAX (locality, 2));
19290 else if (TARGET_PRFCHW)
19291 operands[2] = GEN_INT (3);
19292 else if (TARGET_3DNOW && !TARGET_SSE2)
19293 operands[2] = GEN_INT (3);
19294 else if (TARGET_PREFETCH_SSE)
19295 operands[1] = const0_rtx;
19296 else
19297 {
19298 gcc_assert (TARGET_3DNOW);
19299 operands[2] = GEN_INT (3);
19300 }
19301 }
19302 else
19303 {
19304 if (TARGET_PREFETCH_SSE)
19305 ;
19306 else
19307 {
19308 gcc_assert (TARGET_3DNOW);
19309 operands[2] = GEN_INT (3);
19310 }
19311 }
19312 })
19313
19314 (define_insn "*prefetch_sse"
19315 [(prefetch (match_operand 0 "address_operand" "p")
19316 (const_int 0)
19317 (match_operand:SI 1 "const_int_operand"))]
19318 "TARGET_PREFETCH_SSE"
19319 {
19320 static const char * const patterns[4] = {
19321 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19322 };
19323
19324 int locality = INTVAL (operands[1]);
19325 gcc_assert (IN_RANGE (locality, 0, 3));
19326
19327 return patterns[locality];
19328 }
19329 [(set_attr "type" "sse")
19330 (set_attr "atom_sse_attr" "prefetch")
19331 (set (attr "length_address")
19332 (symbol_ref "memory_address_length (operands[0], false)"))
19333 (set_attr "memory" "none")])
19334
19335 (define_insn "*prefetch_3dnow"
19336 [(prefetch (match_operand 0 "address_operand" "p")
19337 (match_operand:SI 1 "const_int_operand" "n")
19338 (const_int 3))]
19339 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19340 {
19341 if (INTVAL (operands[1]) == 0)
19342 return "prefetch\t%a0";
19343 else
19344 return "prefetchw\t%a0";
19345 }
19346 [(set_attr "type" "mmx")
19347 (set (attr "length_address")
19348 (symbol_ref "memory_address_length (operands[0], false)"))
19349 (set_attr "memory" "none")])
19350
19351 (define_insn "*prefetch_prefetchwt1"
19352 [(prefetch (match_operand 0 "address_operand" "p")
19353 (const_int 1)
19354 (const_int 2))]
19355 "TARGET_PREFETCHWT1"
19356 "prefetchwt1\t%a0";
19357 [(set_attr "type" "sse")
19358 (set (attr "length_address")
19359 (symbol_ref "memory_address_length (operands[0], false)"))
19360 (set_attr "memory" "none")])
19361
19362 (define_expand "stack_protect_set"
19363 [(match_operand 0 "memory_operand")
19364 (match_operand 1 "memory_operand")]
19365 ""
19366 {
19367 emit_insn (gen_stack_protect_set_1
19368 (ptr_mode, operands[0], operands[1]));
19369 DONE;
19370 })
19371
19372 (define_insn "@stack_protect_set_1_<mode>"
19373 [(set (match_operand:PTR 0 "memory_operand" "=m")
19374 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19375 UNSPEC_SP_SET))
19376 (set (match_scratch:PTR 2 "=&r") (const_int 0))
19377 (clobber (reg:CC FLAGS_REG))]
19378 ""
19379 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19380 [(set_attr "type" "multi")])
19381
19382 (define_expand "stack_protect_test"
19383 [(match_operand 0 "memory_operand")
19384 (match_operand 1 "memory_operand")
19385 (match_operand 2)]
19386 ""
19387 {
19388 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19389
19390 emit_insn (gen_stack_protect_test_1
19391 (ptr_mode, flags, operands[0], operands[1]));
19392
19393 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19394 flags, const0_rtx, operands[2]));
19395 DONE;
19396 })
19397
19398 (define_insn "@stack_protect_test_1_<mode>"
19399 [(set (match_operand:CCZ 0 "flags_reg_operand")
19400 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19401 (match_operand:PTR 2 "memory_operand" "m")]
19402 UNSPEC_SP_TEST))
19403 (clobber (match_scratch:PTR 3 "=&r"))]
19404 ""
19405 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;sub{<imodesuffix>}\t{%2, %3|%3, %2}"
19406 [(set_attr "type" "multi")])
19407
19408 (define_insn "sse4_2_crc32<mode>"
19409 [(set (match_operand:SI 0 "register_operand" "=r")
19410 (unspec:SI
19411 [(match_operand:SI 1 "register_operand" "0")
19412 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19413 UNSPEC_CRC32))]
19414 "TARGET_SSE4_2 || TARGET_CRC32"
19415 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19416 [(set_attr "type" "sselog1")
19417 (set_attr "prefix_rep" "1")
19418 (set_attr "prefix_extra" "1")
19419 (set (attr "prefix_data16")
19420 (if_then_else (match_operand:HI 2)
19421 (const_string "1")
19422 (const_string "*")))
19423 (set (attr "prefix_rex")
19424 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19425 (const_string "1")
19426 (const_string "*")))
19427 (set_attr "mode" "SI")])
19428
19429 (define_insn "sse4_2_crc32di"
19430 [(set (match_operand:DI 0 "register_operand" "=r")
19431 (unspec:DI
19432 [(match_operand:DI 1 "register_operand" "0")
19433 (match_operand:DI 2 "nonimmediate_operand" "rm")]
19434 UNSPEC_CRC32))]
19435 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19436 "crc32{q}\t{%2, %0|%0, %2}"
19437 [(set_attr "type" "sselog1")
19438 (set_attr "prefix_rep" "1")
19439 (set_attr "prefix_extra" "1")
19440 (set_attr "mode" "DI")])
19441
19442 (define_insn "rdpmc"
19443 [(set (match_operand:DI 0 "register_operand" "=A")
19444 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19445 UNSPECV_RDPMC))]
19446 "!TARGET_64BIT"
19447 "rdpmc"
19448 [(set_attr "type" "other")
19449 (set_attr "length" "2")])
19450
19451 (define_insn "rdpmc_rex64"
19452 [(set (match_operand:DI 0 "register_operand" "=a")
19453 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19454 UNSPECV_RDPMC))
19455 (set (match_operand:DI 1 "register_operand" "=d")
19456 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19457 "TARGET_64BIT"
19458 "rdpmc"
19459 [(set_attr "type" "other")
19460 (set_attr "length" "2")])
19461
19462 (define_insn "rdtsc"
19463 [(set (match_operand:DI 0 "register_operand" "=A")
19464 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19465 "!TARGET_64BIT"
19466 "rdtsc"
19467 [(set_attr "type" "other")
19468 (set_attr "length" "2")])
19469
19470 (define_insn "rdtsc_rex64"
19471 [(set (match_operand:DI 0 "register_operand" "=a")
19472 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19473 (set (match_operand:DI 1 "register_operand" "=d")
19474 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19475 "TARGET_64BIT"
19476 "rdtsc"
19477 [(set_attr "type" "other")
19478 (set_attr "length" "2")])
19479
19480 (define_insn "rdtscp"
19481 [(set (match_operand:DI 0 "register_operand" "=A")
19482 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19483 (set (match_operand:SI 1 "register_operand" "=c")
19484 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19485 "!TARGET_64BIT"
19486 "rdtscp"
19487 [(set_attr "type" "other")
19488 (set_attr "length" "3")])
19489
19490 (define_insn "rdtscp_rex64"
19491 [(set (match_operand:DI 0 "register_operand" "=a")
19492 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19493 (set (match_operand:DI 1 "register_operand" "=d")
19494 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19495 (set (match_operand:SI 2 "register_operand" "=c")
19496 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19497 "TARGET_64BIT"
19498 "rdtscp"
19499 [(set_attr "type" "other")
19500 (set_attr "length" "3")])
19501
19502 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19503 ;;
19504 ;; FXSR, XSAVE and XSAVEOPT instructions
19505 ;;
19506 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19507
19508 (define_insn "fxsave"
19509 [(set (match_operand:BLK 0 "memory_operand" "=m")
19510 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19511 "TARGET_FXSR"
19512 "fxsave\t%0"
19513 [(set_attr "type" "other")
19514 (set_attr "memory" "store")
19515 (set (attr "length")
19516 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19517
19518 (define_insn "fxsave64"
19519 [(set (match_operand:BLK 0 "memory_operand" "=m")
19520 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19521 "TARGET_64BIT && TARGET_FXSR"
19522 "fxsave64\t%0"
19523 [(set_attr "type" "other")
19524 (set_attr "memory" "store")
19525 (set (attr "length")
19526 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19527
19528 (define_insn "fxrstor"
19529 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19530 UNSPECV_FXRSTOR)]
19531 "TARGET_FXSR"
19532 "fxrstor\t%0"
19533 [(set_attr "type" "other")
19534 (set_attr "memory" "load")
19535 (set (attr "length")
19536 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19537
19538 (define_insn "fxrstor64"
19539 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19540 UNSPECV_FXRSTOR64)]
19541 "TARGET_64BIT && TARGET_FXSR"
19542 "fxrstor64\t%0"
19543 [(set_attr "type" "other")
19544 (set_attr "memory" "load")
19545 (set (attr "length")
19546 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19547
19548 (define_int_iterator ANY_XSAVE
19549 [UNSPECV_XSAVE
19550 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19551 (UNSPECV_XSAVEC "TARGET_XSAVEC")
19552 (UNSPECV_XSAVES "TARGET_XSAVES")])
19553
19554 (define_int_iterator ANY_XSAVE64
19555 [UNSPECV_XSAVE64
19556 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19557 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19558 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19559
19560 (define_int_attr xsave
19561 [(UNSPECV_XSAVE "xsave")
19562 (UNSPECV_XSAVE64 "xsave64")
19563 (UNSPECV_XSAVEOPT "xsaveopt")
19564 (UNSPECV_XSAVEOPT64 "xsaveopt64")
19565 (UNSPECV_XSAVEC "xsavec")
19566 (UNSPECV_XSAVEC64 "xsavec64")
19567 (UNSPECV_XSAVES "xsaves")
19568 (UNSPECV_XSAVES64 "xsaves64")])
19569
19570 (define_int_iterator ANY_XRSTOR
19571 [UNSPECV_XRSTOR
19572 (UNSPECV_XRSTORS "TARGET_XSAVES")])
19573
19574 (define_int_iterator ANY_XRSTOR64
19575 [UNSPECV_XRSTOR64
19576 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19577
19578 (define_int_attr xrstor
19579 [(UNSPECV_XRSTOR "xrstor")
19580 (UNSPECV_XRSTOR64 "xrstor")
19581 (UNSPECV_XRSTORS "xrstors")
19582 (UNSPECV_XRSTORS64 "xrstors")])
19583
19584 (define_insn "<xsave>"
19585 [(set (match_operand:BLK 0 "memory_operand" "=m")
19586 (unspec_volatile:BLK
19587 [(match_operand:DI 1 "register_operand" "A")]
19588 ANY_XSAVE))]
19589 "!TARGET_64BIT && TARGET_XSAVE"
19590 "<xsave>\t%0"
19591 [(set_attr "type" "other")
19592 (set_attr "memory" "store")
19593 (set (attr "length")
19594 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19595
19596 (define_insn "<xsave>_rex64"
19597 [(set (match_operand:BLK 0 "memory_operand" "=m")
19598 (unspec_volatile:BLK
19599 [(match_operand:SI 1 "register_operand" "a")
19600 (match_operand:SI 2 "register_operand" "d")]
19601 ANY_XSAVE))]
19602 "TARGET_64BIT && TARGET_XSAVE"
19603 "<xsave>\t%0"
19604 [(set_attr "type" "other")
19605 (set_attr "memory" "store")
19606 (set (attr "length")
19607 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19608
19609 (define_insn "<xsave>"
19610 [(set (match_operand:BLK 0 "memory_operand" "=m")
19611 (unspec_volatile:BLK
19612 [(match_operand:SI 1 "register_operand" "a")
19613 (match_operand:SI 2 "register_operand" "d")]
19614 ANY_XSAVE64))]
19615 "TARGET_64BIT && TARGET_XSAVE"
19616 "<xsave>\t%0"
19617 [(set_attr "type" "other")
19618 (set_attr "memory" "store")
19619 (set (attr "length")
19620 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19621
19622 (define_insn "<xrstor>"
19623 [(unspec_volatile:BLK
19624 [(match_operand:BLK 0 "memory_operand" "m")
19625 (match_operand:DI 1 "register_operand" "A")]
19626 ANY_XRSTOR)]
19627 "!TARGET_64BIT && TARGET_XSAVE"
19628 "<xrstor>\t%0"
19629 [(set_attr "type" "other")
19630 (set_attr "memory" "load")
19631 (set (attr "length")
19632 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19633
19634 (define_insn "<xrstor>_rex64"
19635 [(unspec_volatile:BLK
19636 [(match_operand:BLK 0 "memory_operand" "m")
19637 (match_operand:SI 1 "register_operand" "a")
19638 (match_operand:SI 2 "register_operand" "d")]
19639 ANY_XRSTOR)]
19640 "TARGET_64BIT && TARGET_XSAVE"
19641 "<xrstor>\t%0"
19642 [(set_attr "type" "other")
19643 (set_attr "memory" "load")
19644 (set (attr "length")
19645 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19646
19647 (define_insn "<xrstor>64"
19648 [(unspec_volatile:BLK
19649 [(match_operand:BLK 0 "memory_operand" "m")
19650 (match_operand:SI 1 "register_operand" "a")
19651 (match_operand:SI 2 "register_operand" "d")]
19652 ANY_XRSTOR64)]
19653 "TARGET_64BIT && TARGET_XSAVE"
19654 "<xrstor>64\t%0"
19655 [(set_attr "type" "other")
19656 (set_attr "memory" "load")
19657 (set (attr "length")
19658 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19659
19660 (define_insn "xsetbv"
19661 [(unspec_volatile:SI
19662 [(match_operand:SI 0 "register_operand" "c")
19663 (match_operand:DI 1 "register_operand" "A")]
19664 UNSPECV_XSETBV)]
19665 "!TARGET_64BIT && TARGET_XSAVE"
19666 "xsetbv"
19667 [(set_attr "type" "other")])
19668
19669 (define_insn "xsetbv_rex64"
19670 [(unspec_volatile:SI
19671 [(match_operand:SI 0 "register_operand" "c")
19672 (match_operand:SI 1 "register_operand" "a")
19673 (match_operand:SI 2 "register_operand" "d")]
19674 UNSPECV_XSETBV)]
19675 "TARGET_64BIT && TARGET_XSAVE"
19676 "xsetbv"
19677 [(set_attr "type" "other")])
19678
19679 (define_insn "xgetbv"
19680 [(set (match_operand:DI 0 "register_operand" "=A")
19681 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19682 UNSPECV_XGETBV))]
19683 "!TARGET_64BIT && TARGET_XSAVE"
19684 "xgetbv"
19685 [(set_attr "type" "other")])
19686
19687 (define_insn "xgetbv_rex64"
19688 [(set (match_operand:DI 0 "register_operand" "=a")
19689 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19690 UNSPECV_XGETBV))
19691 (set (match_operand:DI 1 "register_operand" "=d")
19692 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
19693 "TARGET_64BIT && TARGET_XSAVE"
19694 "xgetbv"
19695 [(set_attr "type" "other")])
19696
19697 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19698 ;;
19699 ;; Floating-point instructions for atomic compound assignments
19700 ;;
19701 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19702
19703 ; Clobber all floating-point registers on environment save and restore
19704 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19705 (define_insn "fnstenv"
19706 [(set (match_operand:BLK 0 "memory_operand" "=m")
19707 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19708 (clobber (reg:XF ST0_REG))
19709 (clobber (reg:XF ST1_REG))
19710 (clobber (reg:XF ST2_REG))
19711 (clobber (reg:XF ST3_REG))
19712 (clobber (reg:XF ST4_REG))
19713 (clobber (reg:XF ST5_REG))
19714 (clobber (reg:XF ST6_REG))
19715 (clobber (reg:XF ST7_REG))]
19716 "TARGET_80387"
19717 "fnstenv\t%0"
19718 [(set_attr "type" "other")
19719 (set_attr "memory" "store")
19720 (set (attr "length")
19721 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19722
19723 (define_insn "fldenv"
19724 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19725 UNSPECV_FLDENV)
19726 (clobber (reg:XF ST0_REG))
19727 (clobber (reg:XF ST1_REG))
19728 (clobber (reg:XF ST2_REG))
19729 (clobber (reg:XF ST3_REG))
19730 (clobber (reg:XF ST4_REG))
19731 (clobber (reg:XF ST5_REG))
19732 (clobber (reg:XF ST6_REG))
19733 (clobber (reg:XF ST7_REG))]
19734 "TARGET_80387"
19735 "fldenv\t%0"
19736 [(set_attr "type" "other")
19737 (set_attr "memory" "load")
19738 (set (attr "length")
19739 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19740
19741 (define_insn "fnstsw"
19742 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19743 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19744 "TARGET_80387"
19745 "fnstsw\t%0"
19746 [(set_attr "type" "other,other")
19747 (set_attr "memory" "none,store")
19748 (set (attr "length")
19749 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19750
19751 (define_insn "fnclex"
19752 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19753 "TARGET_80387"
19754 "fnclex"
19755 [(set_attr "type" "other")
19756 (set_attr "memory" "none")
19757 (set_attr "length" "2")])
19758
19759 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19760 ;;
19761 ;; LWP instructions
19762 ;;
19763 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19764
19765 (define_expand "lwp_llwpcb"
19766 [(unspec_volatile [(match_operand 0 "register_operand")]
19767 UNSPECV_LLWP_INTRINSIC)]
19768 "TARGET_LWP")
19769
19770 (define_insn "*lwp_llwpcb<mode>1"
19771 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19772 UNSPECV_LLWP_INTRINSIC)]
19773 "TARGET_LWP"
19774 "llwpcb\t%0"
19775 [(set_attr "type" "lwp")
19776 (set_attr "mode" "<MODE>")
19777 (set_attr "length" "5")])
19778
19779 (define_expand "lwp_slwpcb"
19780 [(set (match_operand 0 "register_operand")
19781 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19782 "TARGET_LWP"
19783 {
19784 rtx (*insn)(rtx);
19785
19786 insn = (Pmode == DImode
19787 ? gen_lwp_slwpcbdi
19788 : gen_lwp_slwpcbsi);
19789
19790 emit_insn (insn (operands[0]));
19791 DONE;
19792 })
19793
19794 (define_insn "lwp_slwpcb<mode>"
19795 [(set (match_operand:P 0 "register_operand" "=r")
19796 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19797 "TARGET_LWP"
19798 "slwpcb\t%0"
19799 [(set_attr "type" "lwp")
19800 (set_attr "mode" "<MODE>")
19801 (set_attr "length" "5")])
19802
19803 (define_expand "lwp_lwpval<mode>3"
19804 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19805 (match_operand:SI 2 "nonimmediate_operand")
19806 (match_operand:SI 3 "const_int_operand")]
19807 UNSPECV_LWPVAL_INTRINSIC)]
19808 "TARGET_LWP"
19809 ;; Avoid unused variable warning.
19810 "(void) operands[0];")
19811
19812 (define_insn "*lwp_lwpval<mode>3_1"
19813 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19814 (match_operand:SI 1 "nonimmediate_operand" "rm")
19815 (match_operand:SI 2 "const_int_operand" "i")]
19816 UNSPECV_LWPVAL_INTRINSIC)]
19817 "TARGET_LWP"
19818 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19819 [(set_attr "type" "lwp")
19820 (set_attr "mode" "<MODE>")
19821 (set (attr "length")
19822 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19823
19824 (define_expand "lwp_lwpins<mode>3"
19825 [(set (reg:CCC FLAGS_REG)
19826 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19827 (match_operand:SI 2 "nonimmediate_operand")
19828 (match_operand:SI 3 "const_int_operand")]
19829 UNSPECV_LWPINS_INTRINSIC))
19830 (set (match_operand:QI 0 "nonimmediate_operand")
19831 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19832 "TARGET_LWP")
19833
19834 (define_insn "*lwp_lwpins<mode>3_1"
19835 [(set (reg:CCC FLAGS_REG)
19836 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19837 (match_operand:SI 1 "nonimmediate_operand" "rm")
19838 (match_operand:SI 2 "const_int_operand" "i")]
19839 UNSPECV_LWPINS_INTRINSIC))]
19840 "TARGET_LWP"
19841 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19842 [(set_attr "type" "lwp")
19843 (set_attr "mode" "<MODE>")
19844 (set (attr "length")
19845 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19846
19847 (define_int_iterator RDFSGSBASE
19848 [UNSPECV_RDFSBASE
19849 UNSPECV_RDGSBASE])
19850
19851 (define_int_iterator WRFSGSBASE
19852 [UNSPECV_WRFSBASE
19853 UNSPECV_WRGSBASE])
19854
19855 (define_int_attr fsgs
19856 [(UNSPECV_RDFSBASE "fs")
19857 (UNSPECV_RDGSBASE "gs")
19858 (UNSPECV_WRFSBASE "fs")
19859 (UNSPECV_WRGSBASE "gs")])
19860
19861 (define_insn "rd<fsgs>base<mode>"
19862 [(set (match_operand:SWI48 0 "register_operand" "=r")
19863 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19864 "TARGET_64BIT && TARGET_FSGSBASE"
19865 "rd<fsgs>base\t%0"
19866 [(set_attr "type" "other")
19867 (set_attr "prefix_extra" "2")])
19868
19869 (define_insn "wr<fsgs>base<mode>"
19870 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19871 WRFSGSBASE)]
19872 "TARGET_64BIT && TARGET_FSGSBASE"
19873 "wr<fsgs>base\t%0"
19874 [(set_attr "type" "other")
19875 (set_attr "prefix_extra" "2")])
19876
19877 (define_insn "ptwrite<mode>"
19878 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
19879 UNSPECV_PTWRITE)]
19880 "TARGET_PTWRITE"
19881 "ptwrite\t%0"
19882 [(set_attr "type" "other")
19883 (set_attr "prefix_extra" "2")])
19884
19885 (define_insn "rdrand<mode>_1"
19886 [(set (match_operand:SWI248 0 "register_operand" "=r")
19887 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19888 (set (reg:CCC FLAGS_REG)
19889 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19890 "TARGET_RDRND"
19891 "rdrand\t%0"
19892 [(set_attr "type" "other")
19893 (set_attr "prefix_extra" "1")])
19894
19895 (define_insn "rdseed<mode>_1"
19896 [(set (match_operand:SWI248 0 "register_operand" "=r")
19897 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19898 (set (reg:CCC FLAGS_REG)
19899 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19900 "TARGET_RDSEED"
19901 "rdseed\t%0"
19902 [(set_attr "type" "other")
19903 (set_attr "prefix_extra" "1")])
19904
19905 (define_expand "pause"
19906 [(set (match_dup 0)
19907 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19908 ""
19909 {
19910 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19911 MEM_VOLATILE_P (operands[0]) = 1;
19912 })
19913
19914 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19915 ;; They have the same encoding.
19916 (define_insn "*pause"
19917 [(set (match_operand:BLK 0)
19918 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19919 ""
19920 "rep%; nop"
19921 [(set_attr "length" "2")
19922 (set_attr "memory" "unknown")])
19923
19924 ;; CET instructions
19925 (define_insn "rdssp<mode>"
19926 [(set (match_operand:SWI48x 0 "register_operand" "=r")
19927 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
19928 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
19929 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
19930 [(set_attr "length" "6")
19931 (set_attr "type" "other")])
19932
19933 (define_insn "incssp<mode>"
19934 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
19935 UNSPECV_INCSSP)]
19936 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
19937 "incssp<mskmodesuffix>\t%0"
19938 [(set_attr "length" "4")
19939 (set_attr "type" "other")])
19940
19941 (define_insn "saveprevssp"
19942 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
19943 "TARGET_SHSTK"
19944 "saveprevssp"
19945 [(set_attr "length" "5")
19946 (set_attr "type" "other")])
19947
19948 (define_expand "rstorssp"
19949 [(unspec_volatile [(match_operand 0 "memory_operand")]
19950 UNSPECV_RSTORSSP)]
19951 "TARGET_SHSTK")
19952
19953 (define_insn "*rstorssp<mode>"
19954 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
19955 UNSPECV_RSTORSSP)]
19956 "TARGET_SHSTK"
19957 "rstorssp\t%0"
19958 [(set_attr "length" "5")
19959 (set_attr "type" "other")])
19960
19961 (define_insn "wrss<mode>"
19962 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
19963 (match_operand:SWI48x 1 "memory_operand" "m")]
19964 UNSPECV_WRSS)]
19965 "TARGET_SHSTK"
19966 "wrss<mskmodesuffix>\t%0, %1"
19967 [(set_attr "length" "3")
19968 (set_attr "type" "other")])
19969
19970 (define_insn "wruss<mode>"
19971 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
19972 (match_operand:SWI48x 1 "memory_operand" "m")]
19973 UNSPECV_WRUSS)]
19974 "TARGET_SHSTK"
19975 "wruss<mskmodesuffix>\t%0, %1"
19976 [(set_attr "length" "4")
19977 (set_attr "type" "other")])
19978
19979 (define_insn "setssbsy"
19980 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
19981 "TARGET_SHSTK"
19982 "setssbsy"
19983 [(set_attr "length" "4")
19984 (set_attr "type" "other")])
19985
19986 (define_expand "clrssbsy"
19987 [(unspec_volatile [(match_operand 0 "memory_operand")]
19988 UNSPECV_CLRSSBSY)]
19989 "TARGET_SHSTK")
19990
19991 (define_insn "*clrssbsy<mode>"
19992 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
19993 UNSPECV_CLRSSBSY)]
19994 "TARGET_SHSTK"
19995 "clrssbsy\t%0"
19996 [(set_attr "length" "4")
19997 (set_attr "type" "other")])
19998
19999 (define_insn "nop_endbr"
20000 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20001 "(flag_cf_protection & CF_BRANCH)"
20002 {
20003 return TARGET_64BIT ? "endbr64" : "endbr32";
20004 }
20005 [(set_attr "length" "4")
20006 (set_attr "length_immediate" "0")
20007 (set_attr "modrm" "0")])
20008
20009 ;; For RTM support
20010 (define_expand "xbegin"
20011 [(set (match_operand:SI 0 "register_operand")
20012 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20013 "TARGET_RTM"
20014 {
20015 rtx_code_label *label = gen_label_rtx ();
20016
20017 /* xbegin is emitted as jump_insn, so reload won't be able
20018 to reload its operand. Force the value into AX hard register. */
20019 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20020 emit_move_insn (ax_reg, constm1_rtx);
20021
20022 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20023
20024 emit_label (label);
20025 LABEL_NUSES (label) = 1;
20026
20027 emit_move_insn (operands[0], ax_reg);
20028
20029 DONE;
20030 })
20031
20032 (define_insn "xbegin_1"
20033 [(set (pc)
20034 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20035 (const_int 0))
20036 (label_ref (match_operand 1))
20037 (pc)))
20038 (set (match_operand:SI 0 "register_operand" "+a")
20039 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20040 "TARGET_RTM"
20041 "xbegin\t%l1"
20042 [(set_attr "type" "other")
20043 (set_attr "length" "6")])
20044
20045 (define_insn "xend"
20046 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20047 "TARGET_RTM"
20048 "xend"
20049 [(set_attr "type" "other")
20050 (set_attr "length" "3")])
20051
20052 (define_insn "xabort"
20053 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20054 UNSPECV_XABORT)]
20055 "TARGET_RTM"
20056 "xabort\t%0"
20057 [(set_attr "type" "other")
20058 (set_attr "length" "3")])
20059
20060 (define_expand "xtest"
20061 [(set (match_operand:QI 0 "register_operand")
20062 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20063 "TARGET_RTM"
20064 {
20065 emit_insn (gen_xtest_1 ());
20066
20067 ix86_expand_setcc (operands[0], NE,
20068 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20069 DONE;
20070 })
20071
20072 (define_insn "xtest_1"
20073 [(set (reg:CCZ FLAGS_REG)
20074 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20075 "TARGET_RTM"
20076 "xtest"
20077 [(set_attr "type" "other")
20078 (set_attr "length" "3")])
20079
20080 (define_insn "clwb"
20081 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20082 UNSPECV_CLWB)]
20083 "TARGET_CLWB"
20084 "clwb\t%a0"
20085 [(set_attr "type" "sse")
20086 (set_attr "atom_sse_attr" "fence")
20087 (set_attr "memory" "unknown")])
20088
20089 (define_insn "clflushopt"
20090 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20091 UNSPECV_CLFLUSHOPT)]
20092 "TARGET_CLFLUSHOPT"
20093 "clflushopt\t%a0"
20094 [(set_attr "type" "sse")
20095 (set_attr "atom_sse_attr" "fence")
20096 (set_attr "memory" "unknown")])
20097
20098 ;; MONITORX and MWAITX
20099 (define_insn "mwaitx"
20100 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20101 (match_operand:SI 1 "register_operand" "a")
20102 (match_operand:SI 2 "register_operand" "b")]
20103 UNSPECV_MWAITX)]
20104 "TARGET_MWAITX"
20105 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20106 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20107 ;; we only need to set up 32bit registers.
20108 "mwaitx"
20109 [(set_attr "length" "3")])
20110
20111 (define_insn "@monitorx_<mode>"
20112 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20113 (match_operand:SI 1 "register_operand" "c")
20114 (match_operand:SI 2 "register_operand" "d")]
20115 UNSPECV_MONITORX)]
20116 "TARGET_MWAITX"
20117 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20118 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20119 ;; zero extended to 64bit, we only need to set up 32bit registers.
20120 "%^monitorx"
20121 [(set (attr "length")
20122 (symbol_ref ("(Pmode != word_mode) + 3")))])
20123
20124 ;; CLZERO
20125 (define_insn "@clzero_<mode>"
20126 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20127 UNSPECV_CLZERO)]
20128 "TARGET_CLZERO"
20129 "clzero"
20130 [(set_attr "length" "3")
20131 (set_attr "memory" "unknown")])
20132
20133 ;; RDPKRU and WRPKRU
20134
20135 (define_expand "rdpkru"
20136 [(parallel
20137 [(set (match_operand:SI 0 "register_operand")
20138 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20139 (set (match_dup 2) (const_int 0))])]
20140 "TARGET_PKU"
20141 {
20142 operands[1] = force_reg (SImode, const0_rtx);
20143 operands[2] = gen_reg_rtx (SImode);
20144 })
20145
20146 (define_insn "*rdpkru"
20147 [(set (match_operand:SI 0 "register_operand" "=a")
20148 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20149 UNSPECV_PKU))
20150 (set (match_operand:SI 1 "register_operand" "=d")
20151 (const_int 0))]
20152 "TARGET_PKU"
20153 "rdpkru"
20154 [(set_attr "type" "other")])
20155
20156 (define_expand "wrpkru"
20157 [(unspec_volatile:SI
20158 [(match_operand:SI 0 "register_operand")
20159 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20160 "TARGET_PKU"
20161 {
20162 operands[1] = force_reg (SImode, const0_rtx);
20163 operands[2] = force_reg (SImode, const0_rtx);
20164 })
20165
20166 (define_insn "*wrpkru"
20167 [(unspec_volatile:SI
20168 [(match_operand:SI 0 "register_operand" "a")
20169 (match_operand:SI 1 "register_operand" "d")
20170 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20171 "TARGET_PKU"
20172 "wrpkru"
20173 [(set_attr "type" "other")])
20174
20175 (define_insn "rdpid"
20176 [(set (match_operand:SI 0 "register_operand" "=r")
20177 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20178 "!TARGET_64BIT && TARGET_RDPID"
20179 "rdpid\t%0"
20180 [(set_attr "type" "other")])
20181
20182 (define_insn "rdpid_rex64"
20183 [(set (match_operand:DI 0 "register_operand" "=r")
20184 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20185 "TARGET_64BIT && TARGET_RDPID"
20186 "rdpid\t%0"
20187 [(set_attr "type" "other")])
20188
20189 ;; Intirinsics for > i486
20190
20191 (define_insn "wbinvd"
20192 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20193 ""
20194 "wbinvd"
20195 [(set_attr "type" "other")])
20196
20197 (define_insn "wbnoinvd"
20198 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20199 "TARGET_WBNOINVD"
20200 "wbnoinvd"
20201 [(set_attr "type" "other")])
20202
20203 ;; MOVDIRI and MOVDIR64B
20204
20205 (define_insn "movdiri<mode>"
20206 [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
20207 (match_operand:SWI48 1 "register_operand" "r")]
20208 UNSPECV_MOVDIRI)]
20209 "TARGET_MOVDIRI"
20210 "movdiri\t{%1, %0|%0, %1}"
20211 [(set_attr "type" "other")])
20212
20213 (define_insn "@movdir64b_<mode>"
20214 [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
20215 (match_operand:XI 1 "memory_operand")]
20216 UNSPECV_MOVDIR64B)]
20217 "TARGET_MOVDIR64B"
20218 "movdir64b\t{%1, %0|%0, %1}"
20219 [(set_attr "type" "other")])
20220
20221 ;; ENQCMD and ENQCMDS
20222
20223 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
20224 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
20225
20226 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
20227 [(set (reg:CCZ FLAGS_REG)
20228 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
20229 (match_operand:XI 1 "memory_operand" "m")]
20230 ENQCMD))]
20231 "TARGET_ENQCMD"
20232 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
20233 [(set_attr "type" "other")])
20234
20235 ;; WAITPKG
20236
20237 (define_insn "umwait"
20238 [(set (reg:CCC FLAGS_REG)
20239 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20240 (match_operand:DI 1 "register_operand" "A")]
20241 UNSPECV_UMWAIT))]
20242 "!TARGET_64BIT && TARGET_WAITPKG"
20243 "umwait\t%0"
20244 [(set_attr "length" "3")])
20245
20246 (define_insn "umwait_rex64"
20247 [(set (reg:CCC FLAGS_REG)
20248 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20249 (match_operand:SI 1 "register_operand" "a")
20250 (match_operand:SI 2 "register_operand" "d")]
20251 UNSPECV_UMWAIT))]
20252 "TARGET_64BIT && TARGET_WAITPKG"
20253 "umwait\t%0"
20254 [(set_attr "length" "3")])
20255
20256 (define_insn "umonitor_<mode>"
20257 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20258 UNSPECV_UMONITOR)]
20259 "TARGET_WAITPKG"
20260 "umonitor\t%0"
20261 [(set (attr "length")
20262 (symbol_ref ("(Pmode != word_mode) + 3")))])
20263
20264 (define_insn "tpause"
20265 [(set (reg:CCC FLAGS_REG)
20266 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20267 (match_operand:DI 1 "register_operand" "A")]
20268 UNSPECV_TPAUSE))]
20269 "!TARGET_64BIT && TARGET_WAITPKG"
20270 "tpause\t%0"
20271 [(set_attr "length" "3")])
20272
20273 (define_insn "tpause_rex64"
20274 [(set (reg:CCC FLAGS_REG)
20275 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20276 (match_operand:SI 1 "register_operand" "a")
20277 (match_operand:SI 2 "register_operand" "d")]
20278 UNSPECV_TPAUSE))]
20279 "TARGET_64BIT && TARGET_WAITPKG"
20280 "tpause\t%0"
20281 [(set_attr "length" "3")])
20282
20283 (define_insn "cldemote"
20284 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
20285 UNSPECV_CLDEMOTE)]
20286 "TARGET_CLDEMOTE"
20287 "cldemote\t%a0"
20288 [(set_attr "type" "other")
20289 (set_attr "memory" "unknown")])
20290
20291 (define_insn "speculation_barrier"
20292 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
20293 ""
20294 "lfence"
20295 [(set_attr "type" "other")
20296 (set_attr "length" "3")])
20297
20298 (include "mmx.md")
20299 (include "sse.md")
20300 (include "sync.md")