]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/i386.md
83619b1a2edfac3a551c4fdaa4df4fd4fcfb77d5
[thirdparty/gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2014 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 a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
67
68 (define_c_enum "unspec" [
69 ;; Relocation specifiers
70 UNSPEC_GOT
71 UNSPEC_GOTOFF
72 UNSPEC_GOTPCREL
73 UNSPEC_GOTTPOFF
74 UNSPEC_TPOFF
75 UNSPEC_NTPOFF
76 UNSPEC_DTPOFF
77 UNSPEC_GOTNTPOFF
78 UNSPEC_INDNTPOFF
79 UNSPEC_PLTOFF
80 UNSPEC_MACHOPIC_OFFSET
81 UNSPEC_PCREL
82 UNSPEC_SIZEOF
83
84 ;; Prologue support
85 UNSPEC_STACK_ALLOC
86 UNSPEC_SET_GOT
87 UNSPEC_SET_RIP
88 UNSPEC_SET_GOT_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
90 UNSPEC_STACK_CHECK
91
92 ;; TLS support
93 UNSPEC_TP
94 UNSPEC_TLS_GD
95 UNSPEC_TLS_LD_BASE
96 UNSPEC_TLSDESC
97 UNSPEC_TLS_IE_SUN
98
99 ;; Other random patterns
100 UNSPEC_SCAS
101 UNSPEC_FNSTSW
102 UNSPEC_SAHF
103 UNSPEC_PARITY
104 UNSPEC_FSTCW
105 UNSPEC_ADD_CARRY
106 UNSPEC_FLDCW
107 UNSPEC_REP
108 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_TRUNC_NOOP
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_PAUSE
112 UNSPEC_LEA_ADDR
113 UNSPEC_XBEGIN_ABORT
114 UNSPEC_STOS
115 UNSPEC_PEEPSIB
116 UNSPEC_INSN_FALSE_DEP
117
118 ;; For SSE/MMX support:
119 UNSPEC_FIX_NOTRUNC
120 UNSPEC_MASKMOV
121 UNSPEC_MOVMSK
122 UNSPEC_RCP
123 UNSPEC_RSQRT
124 UNSPEC_PSADBW
125
126 ;; Generic math support
127 UNSPEC_COPYSIGN
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_FRNDINT_MASK_PM
148 UNSPEC_FIST_FLOOR
149 UNSPEC_FIST_CEIL
150
151 ;; x87 Double output FP
152 UNSPEC_SINCOS_COS
153 UNSPEC_SINCOS_SIN
154 UNSPEC_XTRACT_FRACT
155 UNSPEC_XTRACT_EXP
156 UNSPEC_FSCALE_FRACT
157 UNSPEC_FSCALE_EXP
158 UNSPEC_FPREM_F
159 UNSPEC_FPREM_U
160 UNSPEC_FPREM1_F
161 UNSPEC_FPREM1_U
162
163 UNSPEC_C2_FLAG
164 UNSPEC_FXAM_MEM
165
166 ;; SSP patterns
167 UNSPEC_SP_SET
168 UNSPEC_SP_TEST
169 UNSPEC_SP_TLS_SET
170 UNSPEC_SP_TLS_TEST
171
172 ;; For ROUND support
173 UNSPEC_ROUND
174
175 ;; For CRC32 support
176 UNSPEC_CRC32
177
178 ;; For BMI support
179 UNSPEC_BEXTR
180
181 ;; For BMI2 support
182 UNSPEC_PDEP
183 UNSPEC_PEXT
184
185 ;; For AVX512F support
186 UNSPEC_KMOV
187
188 UNSPEC_BNDMK
189 UNSPEC_BNDMK_ADDR
190 UNSPEC_BNDSTX
191 UNSPEC_BNDLDX
192 UNSPEC_BNDLDX_ADDR
193 UNSPEC_BNDCL
194 UNSPEC_BNDCU
195 UNSPEC_BNDCN
196 UNSPEC_MPX_FENCE
197 ])
198
199 (define_c_enum "unspecv" [
200 UNSPECV_BLOCKAGE
201 UNSPECV_STACK_PROBE
202 UNSPECV_PROBE_STACK_RANGE
203 UNSPECV_ALIGN
204 UNSPECV_PROLOGUE_USE
205 UNSPECV_SPLIT_STACK_RETURN
206 UNSPECV_CLD
207 UNSPECV_NOPS
208 UNSPECV_RDTSC
209 UNSPECV_RDTSCP
210 UNSPECV_RDPMC
211 UNSPECV_LLWP_INTRINSIC
212 UNSPECV_SLWP_INTRINSIC
213 UNSPECV_LWPVAL_INTRINSIC
214 UNSPECV_LWPINS_INTRINSIC
215 UNSPECV_RDFSBASE
216 UNSPECV_RDGSBASE
217 UNSPECV_WRFSBASE
218 UNSPECV_WRGSBASE
219 UNSPECV_FXSAVE
220 UNSPECV_FXRSTOR
221 UNSPECV_FXSAVE64
222 UNSPECV_FXRSTOR64
223 UNSPECV_XSAVE
224 UNSPECV_XRSTOR
225 UNSPECV_XSAVE64
226 UNSPECV_XRSTOR64
227 UNSPECV_XSAVEOPT
228 UNSPECV_XSAVEOPT64
229 UNSPECV_XSAVES
230 UNSPECV_XRSTORS
231 UNSPECV_XSAVES64
232 UNSPECV_XRSTORS64
233 UNSPECV_XSAVEC
234 UNSPECV_XSAVEC64
235
236 ;; For atomic compound assignments.
237 UNSPECV_FNSTENV
238 UNSPECV_FLDENV
239 UNSPECV_FNSTSW
240 UNSPECV_FNCLEX
241
242 ;; For RDRAND support
243 UNSPECV_RDRAND
244
245 ;; For RDSEED support
246 UNSPECV_RDSEED
247
248 ;; For RTM support
249 UNSPECV_XBEGIN
250 UNSPECV_XEND
251 UNSPECV_XABORT
252 UNSPECV_XTEST
253
254 UNSPECV_NLGR
255
256 ;; For CLFLUSHOPT support
257 UNSPECV_CLFLUSHOPT
258 ])
259
260 ;; Constants to represent rounding modes in the ROUND instruction
261 (define_constants
262 [(ROUND_FLOOR 0x1)
263 (ROUND_CEIL 0x2)
264 (ROUND_TRUNC 0x3)
265 (ROUND_MXCSR 0x4)
266 (ROUND_NO_EXC 0x8)
267 ])
268
269 ;; Constants to represent AVX512F embeded rounding
270 (define_constants
271 [(ROUND_NEAREST_INT 0)
272 (ROUND_NEG_INF 1)
273 (ROUND_POS_INF 2)
274 (ROUND_ZERO 3)
275 (NO_ROUND 4)
276 (ROUND_SAE 8)
277 ])
278
279 ;; Constants to represent pcomtrue/pcomfalse variants
280 (define_constants
281 [(PCOM_FALSE 0)
282 (PCOM_TRUE 1)
283 (COM_FALSE_S 2)
284 (COM_FALSE_P 3)
285 (COM_TRUE_S 4)
286 (COM_TRUE_P 5)
287 ])
288
289 ;; Constants used in the XOP pperm instruction
290 (define_constants
291 [(PPERM_SRC 0x00) /* copy source */
292 (PPERM_INVERT 0x20) /* invert source */
293 (PPERM_REVERSE 0x40) /* bit reverse source */
294 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
295 (PPERM_ZERO 0x80) /* all 0's */
296 (PPERM_ONES 0xa0) /* all 1's */
297 (PPERM_SIGN 0xc0) /* propagate sign bit */
298 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
299 (PPERM_SRC1 0x00) /* use first source byte */
300 (PPERM_SRC2 0x10) /* use second source byte */
301 ])
302
303 ;; Registers by name.
304 (define_constants
305 [(AX_REG 0)
306 (DX_REG 1)
307 (CX_REG 2)
308 (BX_REG 3)
309 (SI_REG 4)
310 (DI_REG 5)
311 (BP_REG 6)
312 (SP_REG 7)
313 (ST0_REG 8)
314 (ST1_REG 9)
315 (ST2_REG 10)
316 (ST3_REG 11)
317 (ST4_REG 12)
318 (ST5_REG 13)
319 (ST6_REG 14)
320 (ST7_REG 15)
321 (FLAGS_REG 17)
322 (FPSR_REG 18)
323 (FPCR_REG 19)
324 (XMM0_REG 21)
325 (XMM1_REG 22)
326 (XMM2_REG 23)
327 (XMM3_REG 24)
328 (XMM4_REG 25)
329 (XMM5_REG 26)
330 (XMM6_REG 27)
331 (XMM7_REG 28)
332 (MM0_REG 29)
333 (MM1_REG 30)
334 (MM2_REG 31)
335 (MM3_REG 32)
336 (MM4_REG 33)
337 (MM5_REG 34)
338 (MM6_REG 35)
339 (MM7_REG 36)
340 (R8_REG 37)
341 (R9_REG 38)
342 (R10_REG 39)
343 (R11_REG 40)
344 (R12_REG 41)
345 (R13_REG 42)
346 (R14_REG 43)
347 (R15_REG 44)
348 (XMM8_REG 45)
349 (XMM9_REG 46)
350 (XMM10_REG 47)
351 (XMM11_REG 48)
352 (XMM12_REG 49)
353 (XMM13_REG 50)
354 (XMM14_REG 51)
355 (XMM15_REG 52)
356 (XMM16_REG 53)
357 (XMM17_REG 54)
358 (XMM18_REG 55)
359 (XMM19_REG 56)
360 (XMM20_REG 57)
361 (XMM21_REG 58)
362 (XMM22_REG 59)
363 (XMM23_REG 60)
364 (XMM24_REG 61)
365 (XMM25_REG 62)
366 (XMM26_REG 63)
367 (XMM27_REG 64)
368 (XMM28_REG 65)
369 (XMM29_REG 66)
370 (XMM30_REG 67)
371 (XMM31_REG 68)
372 (MASK0_REG 69)
373 (MASK1_REG 70)
374 (MASK2_REG 71)
375 (MASK3_REG 72)
376 (MASK4_REG 73)
377 (MASK5_REG 74)
378 (MASK6_REG 75)
379 (MASK7_REG 76)
380 (BND0_REG 77)
381 (BND1_REG 78)
382 ])
383
384 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
385 ;; from i386.c.
386
387 ;; In C guard expressions, put expressions which may be compile-time
388 ;; constants first. This allows for better optimization. For
389 ;; example, write "TARGET_64BIT && reload_completed", not
390 ;; "reload_completed && TARGET_64BIT".
391
392 \f
393 ;; Processor type.
394 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
395 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
396 btver2"
397 (const (symbol_ref "ix86_schedule")))
398
399 ;; A basic instruction type. Refinements due to arguments to be
400 ;; provided in other attributes.
401 (define_attr "type"
402 "other,multi,
403 alu,alu1,negnot,imov,imovx,lea,
404 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
405 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
406 push,pop,call,callv,leave,
407 str,bitmanip,
408 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
409 fxch,fistp,fisttp,frndint,
410 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
411 ssemul,sseimul,ssediv,sselog,sselog1,
412 sseishft,sseishft1,ssecmp,ssecomi,
413 ssecvt,ssecvt1,sseicvt,sseins,
414 sseshuf,sseshuf1,ssemuladd,sse4arg,
415 lwp,mskmov,msklog,
416 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
417 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
418 (const_string "other"))
419
420 ;; Main data type used by the insn
421 (define_attr "mode"
422 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
423 V2DF,V2SF,V1DF,V8DF"
424 (const_string "unknown"))
425
426 ;; The CPU unit operations uses.
427 (define_attr "unit" "integer,i387,sse,mmx,unknown"
428 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
429 fxch,fistp,fisttp,frndint")
430 (const_string "i387")
431 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
432 ssemul,sseimul,ssediv,sselog,sselog1,
433 sseishft,sseishft1,ssecmp,ssecomi,
434 ssecvt,ssecvt1,sseicvt,sseins,
435 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
436 (const_string "sse")
437 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
438 (const_string "mmx")
439 (eq_attr "type" "other")
440 (const_string "unknown")]
441 (const_string "integer")))
442
443 ;; The minimum required alignment of vector mode memory operands of the SSE
444 ;; (non-VEX/EVEX) instruction in bits, if it is different from
445 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
446 ;; multiple alternatives, this should be conservative maximum of those minimum
447 ;; required alignments.
448 (define_attr "ssememalign" "" (const_int 0))
449
450 ;; The (bounding maximum) length of an instruction immediate.
451 (define_attr "length_immediate" ""
452 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
453 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
454 mpxld,mpxst")
455 (const_int 0)
456 (eq_attr "unit" "i387,sse,mmx")
457 (const_int 0)
458 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
459 rotate,rotatex,rotate1,imul,icmp,push,pop")
460 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
461 (eq_attr "type" "imov,test")
462 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
463 (eq_attr "type" "call")
464 (if_then_else (match_operand 0 "constant_call_address_operand")
465 (const_int 4)
466 (const_int 0))
467 (eq_attr "type" "callv")
468 (if_then_else (match_operand 1 "constant_call_address_operand")
469 (const_int 4)
470 (const_int 0))
471 ;; We don't know the size before shorten_branches. Expect
472 ;; the instruction to fit for better scheduling.
473 (eq_attr "type" "ibr")
474 (const_int 1)
475 ]
476 (symbol_ref "/* Update immediate_length and other attributes! */
477 gcc_unreachable (),1")))
478
479 ;; The (bounding maximum) length of an instruction address.
480 (define_attr "length_address" ""
481 (cond [(eq_attr "type" "str,other,multi,fxch")
482 (const_int 0)
483 (and (eq_attr "type" "call")
484 (match_operand 0 "constant_call_address_operand"))
485 (const_int 0)
486 (and (eq_attr "type" "callv")
487 (match_operand 1 "constant_call_address_operand"))
488 (const_int 0)
489 ]
490 (symbol_ref "ix86_attr_length_address_default (insn)")))
491
492 ;; Set when length prefix is used.
493 (define_attr "prefix_data16" ""
494 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
495 (const_int 0)
496 (eq_attr "mode" "HI")
497 (const_int 1)
498 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
499 (const_int 1)
500 ]
501 (const_int 0)))
502
503 ;; Set when string REP prefix is used.
504 (define_attr "prefix_rep" ""
505 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
506 (const_int 0)
507 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
508 (const_int 1)
509 (and (eq_attr "type" "ibr,call,callv")
510 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
511 (const_int 1)
512 ]
513 (const_int 0)))
514
515 ;; Set when 0f opcode prefix is used.
516 (define_attr "prefix_0f" ""
517 (if_then_else
518 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
519 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
520 (eq_attr "unit" "sse,mmx"))
521 (const_int 1)
522 (const_int 0)))
523
524 ;; Set when REX opcode prefix is used.
525 (define_attr "prefix_rex" ""
526 (cond [(not (match_test "TARGET_64BIT"))
527 (const_int 0)
528 (and (eq_attr "mode" "DI")
529 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
530 (eq_attr "unit" "!mmx")))
531 (const_int 1)
532 (and (eq_attr "mode" "QI")
533 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
534 (const_int 1)
535 (match_test "x86_extended_reg_mentioned_p (insn)")
536 (const_int 1)
537 (and (eq_attr "type" "imovx")
538 (match_operand:QI 1 "ext_QIreg_operand"))
539 (const_int 1)
540 ]
541 (const_int 0)))
542
543 ;; There are also additional prefixes in 3DNOW, SSSE3.
544 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
545 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
546 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
547 (define_attr "prefix_extra" ""
548 (cond [(eq_attr "type" "ssemuladd,sse4arg")
549 (const_int 2)
550 (eq_attr "type" "sseiadd1,ssecvt1")
551 (const_int 1)
552 ]
553 (const_int 0)))
554
555 ;; Prefix used: original, VEX or maybe VEX.
556 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
557 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
558 (const_string "vex")
559 (eq_attr "mode" "XI,V16SF,V8DF")
560 (const_string "evex")
561 ]
562 (const_string "orig")))
563
564 ;; VEX W bit is used.
565 (define_attr "prefix_vex_w" "" (const_int 0))
566
567 ;; The length of VEX prefix
568 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
569 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
570 ;; still prefix_0f 1, with prefix_extra 1.
571 (define_attr "length_vex" ""
572 (if_then_else (and (eq_attr "prefix_0f" "1")
573 (eq_attr "prefix_extra" "0"))
574 (if_then_else (eq_attr "prefix_vex_w" "1")
575 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
576 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
577 (if_then_else (eq_attr "prefix_vex_w" "1")
578 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
579 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
580
581 ;; 4-bytes evex prefix and 1 byte opcode.
582 (define_attr "length_evex" "" (const_int 5))
583
584 ;; Set when modrm byte is used.
585 (define_attr "modrm" ""
586 (cond [(eq_attr "type" "str,leave")
587 (const_int 0)
588 (eq_attr "unit" "i387")
589 (const_int 0)
590 (and (eq_attr "type" "incdec")
591 (and (not (match_test "TARGET_64BIT"))
592 (ior (match_operand:SI 1 "register_operand")
593 (match_operand:HI 1 "register_operand"))))
594 (const_int 0)
595 (and (eq_attr "type" "push")
596 (not (match_operand 1 "memory_operand")))
597 (const_int 0)
598 (and (eq_attr "type" "pop")
599 (not (match_operand 0 "memory_operand")))
600 (const_int 0)
601 (and (eq_attr "type" "imov")
602 (and (not (eq_attr "mode" "DI"))
603 (ior (and (match_operand 0 "register_operand")
604 (match_operand 1 "immediate_operand"))
605 (ior (and (match_operand 0 "ax_reg_operand")
606 (match_operand 1 "memory_displacement_only_operand"))
607 (and (match_operand 0 "memory_displacement_only_operand")
608 (match_operand 1 "ax_reg_operand"))))))
609 (const_int 0)
610 (and (eq_attr "type" "call")
611 (match_operand 0 "constant_call_address_operand"))
612 (const_int 0)
613 (and (eq_attr "type" "callv")
614 (match_operand 1 "constant_call_address_operand"))
615 (const_int 0)
616 (and (eq_attr "type" "alu,alu1,icmp,test")
617 (match_operand 0 "ax_reg_operand"))
618 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
619 ]
620 (const_int 1)))
621
622 ;; When this attribute is set, calculate total insn length from
623 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
624 (define_attr "length_nobnd" "" (const_int 0))
625
626 ;; The (bounding maximum) length of an instruction in bytes.
627 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
628 ;; Later we may want to split them and compute proper length as for
629 ;; other insns.
630 (define_attr "length" ""
631 (cond [(eq_attr "length_nobnd" "!0")
632 (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
633 (attr "length_nobnd"))
634 (eq_attr "type" "other,multi,fistp,frndint")
635 (const_int 16)
636 (eq_attr "type" "fcmp")
637 (const_int 4)
638 (eq_attr "unit" "i387")
639 (plus (const_int 2)
640 (plus (attr "prefix_data16")
641 (attr "length_address")))
642 (ior (eq_attr "prefix" "evex")
643 (and (ior (eq_attr "prefix" "maybe_evex")
644 (eq_attr "prefix" "maybe_vex"))
645 (match_test "TARGET_AVX512F")))
646 (plus (attr "length_evex")
647 (plus (attr "length_immediate")
648 (plus (attr "modrm")
649 (attr "length_address"))))
650 (ior (eq_attr "prefix" "vex")
651 (and (ior (eq_attr "prefix" "maybe_vex")
652 (eq_attr "prefix" "maybe_evex"))
653 (match_test "TARGET_AVX")))
654 (plus (attr "length_vex")
655 (plus (attr "length_immediate")
656 (plus (attr "modrm")
657 (attr "length_address"))))]
658 (plus (plus (attr "modrm")
659 (plus (attr "prefix_0f")
660 (plus (attr "prefix_rex")
661 (plus (attr "prefix_extra")
662 (const_int 1)))))
663 (plus (attr "prefix_rep")
664 (plus (attr "prefix_data16")
665 (plus (attr "length_immediate")
666 (attr "length_address")))))))
667
668 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
669 ;; `store' if there is a simple memory reference therein, or `unknown'
670 ;; if the instruction is complex.
671
672 (define_attr "memory" "none,load,store,both,unknown"
673 (cond [(eq_attr "type" "other,multi,str,lwp")
674 (const_string "unknown")
675 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
676 (const_string "none")
677 (eq_attr "type" "fistp,leave")
678 (const_string "both")
679 (eq_attr "type" "frndint")
680 (const_string "load")
681 (eq_attr "type" "mpxld")
682 (const_string "load")
683 (eq_attr "type" "mpxst")
684 (const_string "store")
685 (eq_attr "type" "push")
686 (if_then_else (match_operand 1 "memory_operand")
687 (const_string "both")
688 (const_string "store"))
689 (eq_attr "type" "pop")
690 (if_then_else (match_operand 0 "memory_operand")
691 (const_string "both")
692 (const_string "load"))
693 (eq_attr "type" "setcc")
694 (if_then_else (match_operand 0 "memory_operand")
695 (const_string "store")
696 (const_string "none"))
697 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
698 (if_then_else (ior (match_operand 0 "memory_operand")
699 (match_operand 1 "memory_operand"))
700 (const_string "load")
701 (const_string "none"))
702 (eq_attr "type" "ibr")
703 (if_then_else (match_operand 0 "memory_operand")
704 (const_string "load")
705 (const_string "none"))
706 (eq_attr "type" "call")
707 (if_then_else (match_operand 0 "constant_call_address_operand")
708 (const_string "none")
709 (const_string "load"))
710 (eq_attr "type" "callv")
711 (if_then_else (match_operand 1 "constant_call_address_operand")
712 (const_string "none")
713 (const_string "load"))
714 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
715 (match_operand 1 "memory_operand"))
716 (const_string "both")
717 (and (match_operand 0 "memory_operand")
718 (match_operand 1 "memory_operand"))
719 (const_string "both")
720 (match_operand 0 "memory_operand")
721 (const_string "store")
722 (match_operand 1 "memory_operand")
723 (const_string "load")
724 (and (eq_attr "type"
725 "!alu1,negnot,ishift1,
726 imov,imovx,icmp,test,bitmanip,
727 fmov,fcmp,fsgn,
728 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
729 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
730 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
731 (match_operand 2 "memory_operand"))
732 (const_string "load")
733 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
734 (match_operand 3 "memory_operand"))
735 (const_string "load")
736 ]
737 (const_string "none")))
738
739 ;; Indicates if an instruction has both an immediate and a displacement.
740
741 (define_attr "imm_disp" "false,true,unknown"
742 (cond [(eq_attr "type" "other,multi")
743 (const_string "unknown")
744 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
745 (and (match_operand 0 "memory_displacement_operand")
746 (match_operand 1 "immediate_operand")))
747 (const_string "true")
748 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
749 (and (match_operand 0 "memory_displacement_operand")
750 (match_operand 2 "immediate_operand")))
751 (const_string "true")
752 ]
753 (const_string "false")))
754
755 ;; Indicates if an FP operation has an integer source.
756
757 (define_attr "fp_int_src" "false,true"
758 (const_string "false"))
759
760 ;; Defines rounding mode of an FP operation.
761
762 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
763 (const_string "any"))
764
765 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
766 (define_attr "use_carry" "0,1" (const_string "0"))
767
768 ;; Define attribute to indicate unaligned ssemov insns
769 (define_attr "movu" "0,1" (const_string "0"))
770
771 ;; Used to control the "enabled" attribute on a per-instruction basis.
772 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
773 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
774 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
775 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
776 (const_string "base"))
777
778 (define_attr "enabled" ""
779 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
780 (eq_attr "isa" "x64_sse4")
781 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
782 (eq_attr "isa" "x64_sse4_noavx")
783 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
784 (eq_attr "isa" "x64_avx")
785 (symbol_ref "TARGET_64BIT && TARGET_AVX")
786 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
787 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
788 (eq_attr "isa" "sse2_noavx")
789 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
790 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
791 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
792 (eq_attr "isa" "sse4_noavx")
793 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
794 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
795 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
796 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
797 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
798 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
799 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
800 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
801 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
802 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
803 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
804 (eq_attr "isa" "fma_avx512f")
805 (symbol_ref "TARGET_FMA || TARGET_AVX512F")
806 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
807 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
808 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
809 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
810 ]
811 (const_int 1)))
812
813 (define_attr "preferred_for_speed" "" (const_int 1))
814
815 ;; Describe a user's asm statement.
816 (define_asm_attributes
817 [(set_attr "length" "128")
818 (set_attr "type" "multi")])
819
820 (define_code_iterator plusminus [plus minus])
821
822 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
823
824 (define_code_iterator multdiv [mult div])
825
826 ;; Base name for define_insn
827 (define_code_attr plusminus_insn
828 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
829 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
830
831 ;; Base name for insn mnemonic.
832 (define_code_attr plusminus_mnemonic
833 [(plus "add") (ss_plus "adds") (us_plus "addus")
834 (minus "sub") (ss_minus "subs") (us_minus "subus")])
835 (define_code_attr plusminus_carry_mnemonic
836 [(plus "adc") (minus "sbb")])
837 (define_code_attr multdiv_mnemonic
838 [(mult "mul") (div "div")])
839
840 ;; Mark commutative operators as such in constraints.
841 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
842 (minus "") (ss_minus "") (us_minus "")])
843
844 ;; Mapping of max and min
845 (define_code_iterator maxmin [smax smin umax umin])
846
847 ;; Mapping of signed max and min
848 (define_code_iterator smaxmin [smax smin])
849
850 ;; Mapping of unsigned max and min
851 (define_code_iterator umaxmin [umax umin])
852
853 ;; Base name for integer and FP insn mnemonic
854 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
855 (umax "maxu") (umin "minu")])
856 (define_code_attr maxmin_float [(smax "max") (smin "min")])
857
858 ;; Mapping of logic operators
859 (define_code_iterator any_logic [and ior xor])
860 (define_code_iterator any_or [ior xor])
861 (define_code_iterator fpint_logic [and xor])
862
863 ;; Base name for insn mnemonic.
864 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
865
866 ;; Mapping of logic-shift operators
867 (define_code_iterator any_lshift [ashift lshiftrt])
868
869 ;; Mapping of shift-right operators
870 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
871
872 ;; Mapping of all shift operators
873 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
874
875 ;; Base name for define_insn
876 (define_code_attr shift_insn
877 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
878
879 ;; Base name for insn mnemonic.
880 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
881 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
882
883 ;; Mapping of rotate operators
884 (define_code_iterator any_rotate [rotate rotatert])
885
886 ;; Base name for define_insn
887 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
888
889 ;; Base name for insn mnemonic.
890 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
891
892 ;; Mapping of abs neg operators
893 (define_code_iterator absneg [abs neg])
894
895 ;; Base name for x87 insn mnemonic.
896 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
897
898 ;; Used in signed and unsigned widening multiplications.
899 (define_code_iterator any_extend [sign_extend zero_extend])
900
901 ;; Prefix for insn menmonic.
902 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
903
904 ;; Prefix for define_insn
905 (define_code_attr u [(sign_extend "") (zero_extend "u")])
906 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
907 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
908
909 ;; Used in signed and unsigned truncations.
910 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
911 ;; Instruction suffix for truncations.
912 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
913
914 ;; Used in signed and unsigned fix.
915 (define_code_iterator any_fix [fix unsigned_fix])
916 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
917
918 ;; Used in signed and unsigned float.
919 (define_code_iterator any_float [float unsigned_float])
920 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
921
922 ;; All integer modes.
923 (define_mode_iterator SWI1248x [QI HI SI DI])
924
925 ;; All integer modes with AVX512BW.
926 (define_mode_iterator SWI1248_AVX512BW
927 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
928
929 ;; All integer modes without QImode.
930 (define_mode_iterator SWI248x [HI SI DI])
931
932 ;; All integer modes without QImode and HImode.
933 (define_mode_iterator SWI48x [SI DI])
934
935 ;; All integer modes without SImode and DImode.
936 (define_mode_iterator SWI12 [QI HI])
937
938 ;; All integer modes without DImode.
939 (define_mode_iterator SWI124 [QI HI SI])
940
941 ;; All integer modes without QImode and DImode.
942 (define_mode_iterator SWI24 [HI SI])
943
944 ;; Single word integer modes.
945 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
946
947 ;; Single word integer modes without QImode.
948 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
949
950 ;; Single word integer modes without QImode and HImode.
951 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
952
953 ;; All math-dependant single and double word integer modes.
954 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
955 (HI "TARGET_HIMODE_MATH")
956 SI DI (TI "TARGET_64BIT")])
957
958 ;; Math-dependant single word integer modes.
959 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
960 (HI "TARGET_HIMODE_MATH")
961 SI (DI "TARGET_64BIT")])
962
963 ;; Math-dependant integer modes without DImode.
964 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
965 (HI "TARGET_HIMODE_MATH")
966 SI])
967
968 ;; Math-dependant single word integer modes without QImode.
969 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
970 SI (DI "TARGET_64BIT")])
971
972 ;; Double word integer modes.
973 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
974 (TI "TARGET_64BIT")])
975
976 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
977 ;; compile time constant, it is faster to use <MODE_SIZE> than
978 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
979 ;; command line options just use GET_MODE_SIZE macro.
980 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
981 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
982 (V16QI "16") (V32QI "32") (V64QI "64")
983 (V8HI "16") (V16HI "32") (V32HI "64")
984 (V4SI "16") (V8SI "32") (V16SI "64")
985 (V2DI "16") (V4DI "32") (V8DI "64")
986 (V1TI "16") (V2TI "32") (V4TI "64")
987 (V2DF "16") (V4DF "32") (V8DF "64")
988 (V4SF "16") (V8SF "32") (V16SF "64")])
989
990 ;; Double word integer modes as mode attribute.
991 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
992 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
993
994 ;; Half mode for double word integer modes.
995 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
996 (DI "TARGET_64BIT")])
997
998 ;; Bound modes.
999 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1000 (BND64 "TARGET_LP64")])
1001
1002 ;; Pointer mode corresponding to bound mode.
1003 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1004
1005 ;; MPX check types
1006 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1007
1008 ;; Check name
1009 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1010 (UNSPEC_BNDCU "cu")
1011 (UNSPEC_BNDCN "cn")])
1012
1013 ;; Instruction suffix for integer modes.
1014 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1015
1016 ;; Instruction suffix for masks.
1017 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1018
1019 ;; Pointer size prefix for integer modes (Intel asm dialect)
1020 (define_mode_attr iptrsize [(QI "BYTE")
1021 (HI "WORD")
1022 (SI "DWORD")
1023 (DI "QWORD")])
1024
1025 ;; Register class for integer modes.
1026 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1027
1028 ;; Immediate operand constraint for integer modes.
1029 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1030
1031 ;; General operand constraint for word modes.
1032 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1033
1034 ;; Immediate operand constraint for double integer modes.
1035 (define_mode_attr di [(SI "nF") (DI "e")])
1036
1037 ;; Immediate operand constraint for shifts.
1038 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1039
1040 ;; General operand predicate for integer modes.
1041 (define_mode_attr general_operand
1042 [(QI "general_operand")
1043 (HI "general_operand")
1044 (SI "x86_64_general_operand")
1045 (DI "x86_64_general_operand")
1046 (TI "x86_64_general_operand")])
1047
1048 ;; General sign extend operand predicate for integer modes,
1049 ;; which disallows VOIDmode operands and thus it is suitable
1050 ;; for use inside sign_extend.
1051 (define_mode_attr general_sext_operand
1052 [(QI "sext_operand")
1053 (HI "sext_operand")
1054 (SI "x86_64_sext_operand")
1055 (DI "x86_64_sext_operand")])
1056
1057 ;; General sign/zero extend operand predicate for integer modes.
1058 (define_mode_attr general_szext_operand
1059 [(QI "general_operand")
1060 (HI "general_operand")
1061 (SI "x86_64_szext_general_operand")
1062 (DI "x86_64_szext_general_operand")])
1063
1064 ;; Immediate operand predicate for integer modes.
1065 (define_mode_attr immediate_operand
1066 [(QI "immediate_operand")
1067 (HI "immediate_operand")
1068 (SI "x86_64_immediate_operand")
1069 (DI "x86_64_immediate_operand")])
1070
1071 ;; Nonmemory operand predicate for integer modes.
1072 (define_mode_attr nonmemory_operand
1073 [(QI "nonmemory_operand")
1074 (HI "nonmemory_operand")
1075 (SI "x86_64_nonmemory_operand")
1076 (DI "x86_64_nonmemory_operand")])
1077
1078 ;; Operand predicate for shifts.
1079 (define_mode_attr shift_operand
1080 [(QI "nonimmediate_operand")
1081 (HI "nonimmediate_operand")
1082 (SI "nonimmediate_operand")
1083 (DI "shiftdi_operand")
1084 (TI "register_operand")])
1085
1086 ;; Operand predicate for shift argument.
1087 (define_mode_attr shift_immediate_operand
1088 [(QI "const_1_to_31_operand")
1089 (HI "const_1_to_31_operand")
1090 (SI "const_1_to_31_operand")
1091 (DI "const_1_to_63_operand")])
1092
1093 ;; Input operand predicate for arithmetic left shifts.
1094 (define_mode_attr ashl_input_operand
1095 [(QI "nonimmediate_operand")
1096 (HI "nonimmediate_operand")
1097 (SI "nonimmediate_operand")
1098 (DI "ashldi_input_operand")
1099 (TI "reg_or_pm1_operand")])
1100
1101 ;; SSE and x87 SFmode and DFmode floating point modes
1102 (define_mode_iterator MODEF [SF DF])
1103
1104 ;; All x87 floating point modes
1105 (define_mode_iterator X87MODEF [SF DF XF])
1106
1107 ;; SSE instruction suffix for various modes
1108 (define_mode_attr ssemodesuffix
1109 [(SF "ss") (DF "sd")
1110 (V16SF "ps") (V8DF "pd")
1111 (V8SF "ps") (V4DF "pd")
1112 (V4SF "ps") (V2DF "pd")
1113 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1114 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1115 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1116
1117 ;; SSE vector suffix for floating point modes
1118 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1119
1120 ;; SSE vector mode corresponding to a scalar mode
1121 (define_mode_attr ssevecmode
1122 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1123 (define_mode_attr ssevecmodelower
1124 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1125
1126 ;; Instruction suffix for REX 64bit operators.
1127 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1128
1129 ;; This mode iterator allows :P to be used for patterns that operate on
1130 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1131 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1132
1133 ;; This mode iterator allows :W to be used for patterns that operate on
1134 ;; word_mode sized quantities.
1135 (define_mode_iterator W
1136 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1137
1138 ;; This mode iterator allows :PTR to be used for patterns that operate on
1139 ;; ptr_mode sized quantities.
1140 (define_mode_iterator PTR
1141 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1142 \f
1143 ;; Scheduling descriptions
1144
1145 (include "pentium.md")
1146 (include "ppro.md")
1147 (include "k6.md")
1148 (include "athlon.md")
1149 (include "bdver1.md")
1150 (include "bdver3.md")
1151 (include "btver2.md")
1152 (include "geode.md")
1153 (include "atom.md")
1154 (include "slm.md")
1155 (include "core2.md")
1156
1157 \f
1158 ;; Operand and operator predicates and constraints
1159
1160 (include "predicates.md")
1161 (include "constraints.md")
1162
1163 \f
1164 ;; Compare and branch/compare and store instructions.
1165
1166 (define_expand "cbranch<mode>4"
1167 [(set (reg:CC FLAGS_REG)
1168 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1169 (match_operand:SDWIM 2 "<general_operand>")))
1170 (set (pc) (if_then_else
1171 (match_operator 0 "ordered_comparison_operator"
1172 [(reg:CC FLAGS_REG) (const_int 0)])
1173 (label_ref (match_operand 3))
1174 (pc)))]
1175 ""
1176 {
1177 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1178 operands[1] = force_reg (<MODE>mode, operands[1]);
1179 ix86_expand_branch (GET_CODE (operands[0]),
1180 operands[1], operands[2], operands[3]);
1181 DONE;
1182 })
1183
1184 (define_expand "cstore<mode>4"
1185 [(set (reg:CC FLAGS_REG)
1186 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1187 (match_operand:SWIM 3 "<general_operand>")))
1188 (set (match_operand:QI 0 "register_operand")
1189 (match_operator 1 "ordered_comparison_operator"
1190 [(reg:CC FLAGS_REG) (const_int 0)]))]
1191 ""
1192 {
1193 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1194 operands[2] = force_reg (<MODE>mode, operands[2]);
1195 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1196 operands[2], operands[3]);
1197 DONE;
1198 })
1199
1200 (define_expand "cmp<mode>_1"
1201 [(set (reg:CC FLAGS_REG)
1202 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1203 (match_operand:SWI48 1 "<general_operand>")))])
1204
1205 (define_insn "*cmp<mode>_ccno_1"
1206 [(set (reg FLAGS_REG)
1207 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1208 (match_operand:SWI 1 "const0_operand")))]
1209 "ix86_match_ccmode (insn, CCNOmode)"
1210 "@
1211 test{<imodesuffix>}\t%0, %0
1212 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1213 [(set_attr "type" "test,icmp")
1214 (set_attr "length_immediate" "0,1")
1215 (set_attr "mode" "<MODE>")])
1216
1217 (define_insn "*cmp<mode>_1"
1218 [(set (reg FLAGS_REG)
1219 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1220 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1221 "ix86_match_ccmode (insn, CCmode)"
1222 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1223 [(set_attr "type" "icmp")
1224 (set_attr "mode" "<MODE>")])
1225
1226 (define_insn "*cmp<mode>_minus_1"
1227 [(set (reg FLAGS_REG)
1228 (compare
1229 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1230 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1231 (const_int 0)))]
1232 "ix86_match_ccmode (insn, CCGOCmode)"
1233 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1234 [(set_attr "type" "icmp")
1235 (set_attr "mode" "<MODE>")])
1236
1237 (define_insn "*cmpqi_ext_1"
1238 [(set (reg FLAGS_REG)
1239 (compare
1240 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1241 (subreg:QI
1242 (zero_extract:SI
1243 (match_operand 1 "ext_register_operand" "Q,Q")
1244 (const_int 8)
1245 (const_int 8)) 0)))]
1246 "ix86_match_ccmode (insn, CCmode)"
1247 "cmp{b}\t{%h1, %0|%0, %h1}"
1248 [(set_attr "isa" "*,nox64")
1249 (set_attr "type" "icmp")
1250 (set_attr "mode" "QI")])
1251
1252 (define_insn "*cmpqi_ext_2"
1253 [(set (reg FLAGS_REG)
1254 (compare
1255 (subreg:QI
1256 (zero_extract:SI
1257 (match_operand 0 "ext_register_operand" "Q")
1258 (const_int 8)
1259 (const_int 8)) 0)
1260 (match_operand:QI 1 "const0_operand")))]
1261 "ix86_match_ccmode (insn, CCNOmode)"
1262 "test{b}\t%h0, %h0"
1263 [(set_attr "type" "test")
1264 (set_attr "length_immediate" "0")
1265 (set_attr "mode" "QI")])
1266
1267 (define_expand "cmpqi_ext_3"
1268 [(set (reg:CC FLAGS_REG)
1269 (compare:CC
1270 (subreg:QI
1271 (zero_extract:SI
1272 (match_operand 0 "ext_register_operand")
1273 (const_int 8)
1274 (const_int 8)) 0)
1275 (match_operand:QI 1 "const_int_operand")))])
1276
1277 (define_insn "*cmpqi_ext_3"
1278 [(set (reg FLAGS_REG)
1279 (compare
1280 (subreg:QI
1281 (zero_extract:SI
1282 (match_operand 0 "ext_register_operand" "Q,Q")
1283 (const_int 8)
1284 (const_int 8)) 0)
1285 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1286 "ix86_match_ccmode (insn, CCmode)"
1287 "cmp{b}\t{%1, %h0|%h0, %1}"
1288 [(set_attr "isa" "*,nox64")
1289 (set_attr "type" "icmp")
1290 (set_attr "modrm" "1")
1291 (set_attr "mode" "QI")])
1292
1293 (define_insn "*cmpqi_ext_4"
1294 [(set (reg FLAGS_REG)
1295 (compare
1296 (subreg:QI
1297 (zero_extract:SI
1298 (match_operand 0 "ext_register_operand" "Q")
1299 (const_int 8)
1300 (const_int 8)) 0)
1301 (subreg:QI
1302 (zero_extract:SI
1303 (match_operand 1 "ext_register_operand" "Q")
1304 (const_int 8)
1305 (const_int 8)) 0)))]
1306 "ix86_match_ccmode (insn, CCmode)"
1307 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1308 [(set_attr "type" "icmp")
1309 (set_attr "mode" "QI")])
1310
1311 ;; These implement float point compares.
1312 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1313 ;; which would allow mix and match FP modes on the compares. Which is what
1314 ;; the old patterns did, but with many more of them.
1315
1316 (define_expand "cbranchxf4"
1317 [(set (reg:CC FLAGS_REG)
1318 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1319 (match_operand:XF 2 "nonmemory_operand")))
1320 (set (pc) (if_then_else
1321 (match_operator 0 "ix86_fp_comparison_operator"
1322 [(reg:CC FLAGS_REG)
1323 (const_int 0)])
1324 (label_ref (match_operand 3))
1325 (pc)))]
1326 "TARGET_80387"
1327 {
1328 ix86_expand_branch (GET_CODE (operands[0]),
1329 operands[1], operands[2], operands[3]);
1330 DONE;
1331 })
1332
1333 (define_expand "cstorexf4"
1334 [(set (reg:CC FLAGS_REG)
1335 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1336 (match_operand:XF 3 "nonmemory_operand")))
1337 (set (match_operand:QI 0 "register_operand")
1338 (match_operator 1 "ix86_fp_comparison_operator"
1339 [(reg:CC FLAGS_REG)
1340 (const_int 0)]))]
1341 "TARGET_80387"
1342 {
1343 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1344 operands[2], operands[3]);
1345 DONE;
1346 })
1347
1348 (define_expand "cbranch<mode>4"
1349 [(set (reg:CC FLAGS_REG)
1350 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1351 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1352 (set (pc) (if_then_else
1353 (match_operator 0 "ix86_fp_comparison_operator"
1354 [(reg:CC FLAGS_REG)
1355 (const_int 0)])
1356 (label_ref (match_operand 3))
1357 (pc)))]
1358 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1359 {
1360 ix86_expand_branch (GET_CODE (operands[0]),
1361 operands[1], operands[2], operands[3]);
1362 DONE;
1363 })
1364
1365 (define_expand "cstore<mode>4"
1366 [(set (reg:CC FLAGS_REG)
1367 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1368 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1369 (set (match_operand:QI 0 "register_operand")
1370 (match_operator 1 "ix86_fp_comparison_operator"
1371 [(reg:CC FLAGS_REG)
1372 (const_int 0)]))]
1373 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1374 {
1375 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1376 operands[2], operands[3]);
1377 DONE;
1378 })
1379
1380 (define_expand "cbranchcc4"
1381 [(set (pc) (if_then_else
1382 (match_operator 0 "comparison_operator"
1383 [(match_operand 1 "flags_reg_operand")
1384 (match_operand 2 "const0_operand")])
1385 (label_ref (match_operand 3))
1386 (pc)))]
1387 ""
1388 {
1389 ix86_expand_branch (GET_CODE (operands[0]),
1390 operands[1], operands[2], operands[3]);
1391 DONE;
1392 })
1393
1394 (define_expand "cstorecc4"
1395 [(set (match_operand:QI 0 "register_operand")
1396 (match_operator 1 "comparison_operator"
1397 [(match_operand 2 "flags_reg_operand")
1398 (match_operand 3 "const0_operand")]))]
1399 ""
1400 {
1401 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1402 operands[2], operands[3]);
1403 DONE;
1404 })
1405
1406
1407 ;; FP compares, step 1:
1408 ;; Set the FP condition codes.
1409 ;;
1410 ;; CCFPmode compare with exceptions
1411 ;; CCFPUmode compare with no exceptions
1412
1413 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1414 ;; used to manage the reg stack popping would not be preserved.
1415
1416 (define_insn "*cmp<mode>_0_i387"
1417 [(set (match_operand:HI 0 "register_operand" "=a")
1418 (unspec:HI
1419 [(compare:CCFP
1420 (match_operand:X87MODEF 1 "register_operand" "f")
1421 (match_operand:X87MODEF 2 "const0_operand"))]
1422 UNSPEC_FNSTSW))]
1423 "TARGET_80387"
1424 "* return output_fp_compare (insn, operands, false, false);"
1425 [(set_attr "type" "multi")
1426 (set_attr "unit" "i387")
1427 (set_attr "mode" "<MODE>")])
1428
1429 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1430 [(set (reg:CCFP FLAGS_REG)
1431 (compare:CCFP
1432 (match_operand:X87MODEF 1 "register_operand" "f")
1433 (match_operand:X87MODEF 2 "const0_operand")))
1434 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1435 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1436 "#"
1437 "&& reload_completed"
1438 [(set (match_dup 0)
1439 (unspec:HI
1440 [(compare:CCFP (match_dup 1)(match_dup 2))]
1441 UNSPEC_FNSTSW))
1442 (set (reg:CC FLAGS_REG)
1443 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1444 ""
1445 [(set_attr "type" "multi")
1446 (set_attr "unit" "i387")
1447 (set_attr "mode" "<MODE>")])
1448
1449 (define_insn "*cmpxf_i387"
1450 [(set (match_operand:HI 0 "register_operand" "=a")
1451 (unspec:HI
1452 [(compare:CCFP
1453 (match_operand:XF 1 "register_operand" "f")
1454 (match_operand:XF 2 "register_operand" "f"))]
1455 UNSPEC_FNSTSW))]
1456 "TARGET_80387"
1457 "* return output_fp_compare (insn, operands, false, false);"
1458 [(set_attr "type" "multi")
1459 (set_attr "unit" "i387")
1460 (set_attr "mode" "XF")])
1461
1462 (define_insn_and_split "*cmpxf_cc_i387"
1463 [(set (reg:CCFP FLAGS_REG)
1464 (compare:CCFP
1465 (match_operand:XF 1 "register_operand" "f")
1466 (match_operand:XF 2 "register_operand" "f")))
1467 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1468 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1469 "#"
1470 "&& reload_completed"
1471 [(set (match_dup 0)
1472 (unspec:HI
1473 [(compare:CCFP (match_dup 1)(match_dup 2))]
1474 UNSPEC_FNSTSW))
1475 (set (reg:CC FLAGS_REG)
1476 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1477 ""
1478 [(set_attr "type" "multi")
1479 (set_attr "unit" "i387")
1480 (set_attr "mode" "XF")])
1481
1482 (define_insn "*cmp<mode>_i387"
1483 [(set (match_operand:HI 0 "register_operand" "=a")
1484 (unspec:HI
1485 [(compare:CCFP
1486 (match_operand:MODEF 1 "register_operand" "f")
1487 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1488 UNSPEC_FNSTSW))]
1489 "TARGET_80387"
1490 "* return output_fp_compare (insn, operands, false, false);"
1491 [(set_attr "type" "multi")
1492 (set_attr "unit" "i387")
1493 (set_attr "mode" "<MODE>")])
1494
1495 (define_insn_and_split "*cmp<mode>_cc_i387"
1496 [(set (reg:CCFP FLAGS_REG)
1497 (compare:CCFP
1498 (match_operand:MODEF 1 "register_operand" "f")
1499 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1500 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1501 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1502 "#"
1503 "&& reload_completed"
1504 [(set (match_dup 0)
1505 (unspec:HI
1506 [(compare:CCFP (match_dup 1)(match_dup 2))]
1507 UNSPEC_FNSTSW))
1508 (set (reg:CC FLAGS_REG)
1509 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1510 ""
1511 [(set_attr "type" "multi")
1512 (set_attr "unit" "i387")
1513 (set_attr "mode" "<MODE>")])
1514
1515 (define_insn "*cmpu<mode>_i387"
1516 [(set (match_operand:HI 0 "register_operand" "=a")
1517 (unspec:HI
1518 [(compare:CCFPU
1519 (match_operand:X87MODEF 1 "register_operand" "f")
1520 (match_operand:X87MODEF 2 "register_operand" "f"))]
1521 UNSPEC_FNSTSW))]
1522 "TARGET_80387"
1523 "* return output_fp_compare (insn, operands, false, true);"
1524 [(set_attr "type" "multi")
1525 (set_attr "unit" "i387")
1526 (set_attr "mode" "<MODE>")])
1527
1528 (define_insn_and_split "*cmpu<mode>_cc_i387"
1529 [(set (reg:CCFPU FLAGS_REG)
1530 (compare:CCFPU
1531 (match_operand:X87MODEF 1 "register_operand" "f")
1532 (match_operand:X87MODEF 2 "register_operand" "f")))
1533 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1534 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1535 "#"
1536 "&& reload_completed"
1537 [(set (match_dup 0)
1538 (unspec:HI
1539 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1540 UNSPEC_FNSTSW))
1541 (set (reg:CC FLAGS_REG)
1542 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1543 ""
1544 [(set_attr "type" "multi")
1545 (set_attr "unit" "i387")
1546 (set_attr "mode" "<MODE>")])
1547
1548 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1549 [(set (match_operand:HI 0 "register_operand" "=a")
1550 (unspec:HI
1551 [(compare:CCFP
1552 (match_operand:X87MODEF 1 "register_operand" "f")
1553 (match_operator:X87MODEF 3 "float_operator"
1554 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1555 UNSPEC_FNSTSW))]
1556 "TARGET_80387
1557 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1558 || optimize_function_for_size_p (cfun))"
1559 "* return output_fp_compare (insn, operands, false, false);"
1560 [(set_attr "type" "multi")
1561 (set_attr "unit" "i387")
1562 (set_attr "fp_int_src" "true")
1563 (set_attr "mode" "<SWI24:MODE>")])
1564
1565 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1566 [(set (reg:CCFP FLAGS_REG)
1567 (compare:CCFP
1568 (match_operand:X87MODEF 1 "register_operand" "f")
1569 (match_operator:X87MODEF 3 "float_operator"
1570 [(match_operand:SWI24 2 "memory_operand" "m")])))
1571 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1572 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1573 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1574 || optimize_function_for_size_p (cfun))"
1575 "#"
1576 "&& reload_completed"
1577 [(set (match_dup 0)
1578 (unspec:HI
1579 [(compare:CCFP
1580 (match_dup 1)
1581 (match_op_dup 3 [(match_dup 2)]))]
1582 UNSPEC_FNSTSW))
1583 (set (reg:CC FLAGS_REG)
1584 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1585 ""
1586 [(set_attr "type" "multi")
1587 (set_attr "unit" "i387")
1588 (set_attr "fp_int_src" "true")
1589 (set_attr "mode" "<SWI24:MODE>")])
1590
1591 ;; FP compares, step 2
1592 ;; Move the fpsw to ax.
1593
1594 (define_insn "x86_fnstsw_1"
1595 [(set (match_operand:HI 0 "register_operand" "=a")
1596 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1597 "TARGET_80387"
1598 "fnstsw\t%0"
1599 [(set_attr "length" "2")
1600 (set_attr "mode" "SI")
1601 (set_attr "unit" "i387")])
1602
1603 ;; FP compares, step 3
1604 ;; Get ax into flags, general case.
1605
1606 (define_insn "x86_sahf_1"
1607 [(set (reg:CC FLAGS_REG)
1608 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1609 UNSPEC_SAHF))]
1610 "TARGET_SAHF"
1611 {
1612 #ifndef HAVE_AS_IX86_SAHF
1613 if (TARGET_64BIT)
1614 return ASM_BYTE "0x9e";
1615 else
1616 #endif
1617 return "sahf";
1618 }
1619 [(set_attr "length" "1")
1620 (set_attr "athlon_decode" "vector")
1621 (set_attr "amdfam10_decode" "direct")
1622 (set_attr "bdver1_decode" "direct")
1623 (set_attr "mode" "SI")])
1624
1625 ;; Pentium Pro can do steps 1 through 3 in one go.
1626 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1627 ;; (these i387 instructions set flags directly)
1628
1629 (define_mode_iterator FPCMP [CCFP CCFPU])
1630 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1631
1632 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1633 [(set (reg:FPCMP FLAGS_REG)
1634 (compare:FPCMP
1635 (match_operand:MODEF 0 "register_operand" "f,x")
1636 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1637 "TARGET_MIX_SSE_I387
1638 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1639 "* return output_fp_compare (insn, operands, true,
1640 <FPCMP:MODE>mode == CCFPUmode);"
1641 [(set_attr "type" "fcmp,ssecomi")
1642 (set_attr "prefix" "orig,maybe_vex")
1643 (set_attr "mode" "<MODEF:MODE>")
1644 (set (attr "prefix_rep")
1645 (if_then_else (eq_attr "type" "ssecomi")
1646 (const_string "0")
1647 (const_string "*")))
1648 (set (attr "prefix_data16")
1649 (cond [(eq_attr "type" "fcmp")
1650 (const_string "*")
1651 (eq_attr "mode" "DF")
1652 (const_string "1")
1653 ]
1654 (const_string "0")))
1655 (set_attr "athlon_decode" "vector")
1656 (set_attr "amdfam10_decode" "direct")
1657 (set_attr "bdver1_decode" "double")])
1658
1659 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1660 [(set (reg:FPCMP FLAGS_REG)
1661 (compare:FPCMP
1662 (match_operand:MODEF 0 "register_operand" "x")
1663 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1664 "TARGET_SSE_MATH
1665 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1666 "* return output_fp_compare (insn, operands, true,
1667 <FPCMP:MODE>mode == CCFPUmode);"
1668 [(set_attr "type" "ssecomi")
1669 (set_attr "prefix" "maybe_vex")
1670 (set_attr "mode" "<MODEF:MODE>")
1671 (set_attr "prefix_rep" "0")
1672 (set (attr "prefix_data16")
1673 (if_then_else (eq_attr "mode" "DF")
1674 (const_string "1")
1675 (const_string "0")))
1676 (set_attr "athlon_decode" "vector")
1677 (set_attr "amdfam10_decode" "direct")
1678 (set_attr "bdver1_decode" "double")])
1679
1680 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1681 [(set (reg:FPCMP FLAGS_REG)
1682 (compare:FPCMP
1683 (match_operand:X87MODEF 0 "register_operand" "f")
1684 (match_operand:X87MODEF 1 "register_operand" "f")))]
1685 "TARGET_80387 && TARGET_CMOVE
1686 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1687 "* return output_fp_compare (insn, operands, true,
1688 <FPCMP:MODE>mode == CCFPUmode);"
1689 [(set_attr "type" "fcmp")
1690 (set_attr "mode" "<X87MODEF:MODE>")
1691 (set_attr "athlon_decode" "vector")
1692 (set_attr "amdfam10_decode" "direct")
1693 (set_attr "bdver1_decode" "double")])
1694 \f
1695 ;; Push/pop instructions.
1696
1697 (define_insn "*push<mode>2"
1698 [(set (match_operand:DWI 0 "push_operand" "=<")
1699 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1700 ""
1701 "#"
1702 [(set_attr "type" "multi")
1703 (set_attr "mode" "<MODE>")])
1704
1705 (define_split
1706 [(set (match_operand:TI 0 "push_operand")
1707 (match_operand:TI 1 "general_operand"))]
1708 "TARGET_64BIT && reload_completed
1709 && !SSE_REG_P (operands[1])"
1710 [(const_int 0)]
1711 "ix86_split_long_move (operands); DONE;")
1712
1713 (define_insn "*pushdi2_rex64"
1714 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1715 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1716 "TARGET_64BIT"
1717 "@
1718 push{q}\t%1
1719 #"
1720 [(set_attr "type" "push,multi")
1721 (set_attr "mode" "DI")])
1722
1723 ;; Convert impossible pushes of immediate to existing instructions.
1724 ;; First try to get scratch register and go through it. In case this
1725 ;; fails, push sign extended lower part first and then overwrite
1726 ;; upper part by 32bit move.
1727 (define_peephole2
1728 [(match_scratch:DI 2 "r")
1729 (set (match_operand:DI 0 "push_operand")
1730 (match_operand:DI 1 "immediate_operand"))]
1731 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1732 && !x86_64_immediate_operand (operands[1], DImode)"
1733 [(set (match_dup 2) (match_dup 1))
1734 (set (match_dup 0) (match_dup 2))])
1735
1736 ;; We need to define this as both peepholer and splitter for case
1737 ;; peephole2 pass is not run.
1738 ;; "&& 1" is needed to keep it from matching the previous pattern.
1739 (define_peephole2
1740 [(set (match_operand:DI 0 "push_operand")
1741 (match_operand:DI 1 "immediate_operand"))]
1742 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1743 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1744 [(set (match_dup 0) (match_dup 1))
1745 (set (match_dup 2) (match_dup 3))]
1746 {
1747 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1748
1749 operands[1] = gen_lowpart (DImode, operands[2]);
1750 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1751 GEN_INT (4)));
1752 })
1753
1754 (define_split
1755 [(set (match_operand:DI 0 "push_operand")
1756 (match_operand:DI 1 "immediate_operand"))]
1757 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1758 ? epilogue_completed : reload_completed)
1759 && !symbolic_operand (operands[1], DImode)
1760 && !x86_64_immediate_operand (operands[1], DImode)"
1761 [(set (match_dup 0) (match_dup 1))
1762 (set (match_dup 2) (match_dup 3))]
1763 {
1764 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1765
1766 operands[1] = gen_lowpart (DImode, operands[2]);
1767 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1768 GEN_INT (4)));
1769 })
1770
1771 (define_split
1772 [(set (match_operand:DI 0 "push_operand")
1773 (match_operand:DI 1 "general_operand"))]
1774 "!TARGET_64BIT && reload_completed
1775 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1776 [(const_int 0)]
1777 "ix86_split_long_move (operands); DONE;")
1778
1779 (define_insn "*pushsi2"
1780 [(set (match_operand:SI 0 "push_operand" "=<")
1781 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1782 "!TARGET_64BIT"
1783 "push{l}\t%1"
1784 [(set_attr "type" "push")
1785 (set_attr "mode" "SI")])
1786
1787 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1788 ;; "push a byte/word". But actually we use pushl, which has the effect
1789 ;; of rounding the amount pushed up to a word.
1790
1791 ;; For TARGET_64BIT we always round up to 8 bytes.
1792 (define_insn "*push<mode>2_rex64"
1793 [(set (match_operand:SWI124 0 "push_operand" "=X")
1794 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1795 "TARGET_64BIT"
1796 "push{q}\t%q1"
1797 [(set_attr "type" "push")
1798 (set_attr "mode" "DI")])
1799
1800 (define_insn "*push<mode>2"
1801 [(set (match_operand:SWI12 0 "push_operand" "=X")
1802 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1803 "!TARGET_64BIT"
1804 "push{l}\t%k1"
1805 [(set_attr "type" "push")
1806 (set_attr "mode" "SI")])
1807
1808 (define_insn "*push<mode>2_prologue"
1809 [(set (match_operand:W 0 "push_operand" "=<")
1810 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1811 (clobber (mem:BLK (scratch)))]
1812 ""
1813 "push{<imodesuffix>}\t%1"
1814 [(set_attr "type" "push")
1815 (set_attr "mode" "<MODE>")])
1816
1817 (define_insn "*pop<mode>1"
1818 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1819 (match_operand:W 1 "pop_operand" ">"))]
1820 ""
1821 "pop{<imodesuffix>}\t%0"
1822 [(set_attr "type" "pop")
1823 (set_attr "mode" "<MODE>")])
1824
1825 (define_insn "*pop<mode>1_epilogue"
1826 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1827 (match_operand:W 1 "pop_operand" ">"))
1828 (clobber (mem:BLK (scratch)))]
1829 ""
1830 "pop{<imodesuffix>}\t%0"
1831 [(set_attr "type" "pop")
1832 (set_attr "mode" "<MODE>")])
1833
1834 (define_insn "*pushfl<mode>2"
1835 [(set (match_operand:W 0 "push_operand" "=<")
1836 (match_operand:W 1 "flags_reg_operand"))]
1837 ""
1838 "pushf{<imodesuffix>}"
1839 [(set_attr "type" "push")
1840 (set_attr "mode" "<MODE>")])
1841
1842 (define_insn "*popfl<mode>1"
1843 [(set (match_operand:W 0 "flags_reg_operand")
1844 (match_operand:W 1 "pop_operand" ">"))]
1845 ""
1846 "popf{<imodesuffix>}"
1847 [(set_attr "type" "pop")
1848 (set_attr "mode" "<MODE>")])
1849
1850 \f
1851 ;; Move instructions.
1852
1853 (define_expand "movxi"
1854 [(set (match_operand:XI 0 "nonimmediate_operand")
1855 (match_operand:XI 1 "general_operand"))]
1856 "TARGET_AVX512F"
1857 "ix86_expand_move (XImode, operands); DONE;")
1858
1859 ;; Reload patterns to support multi-word load/store
1860 ;; with non-offsetable address.
1861 (define_expand "reload_noff_store"
1862 [(parallel [(match_operand 0 "memory_operand" "=m")
1863 (match_operand 1 "register_operand" "r")
1864 (match_operand:DI 2 "register_operand" "=&r")])]
1865 "TARGET_64BIT"
1866 {
1867 rtx mem = operands[0];
1868 rtx addr = XEXP (mem, 0);
1869
1870 emit_move_insn (operands[2], addr);
1871 mem = replace_equiv_address_nv (mem, operands[2]);
1872
1873 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1874 DONE;
1875 })
1876
1877 (define_expand "reload_noff_load"
1878 [(parallel [(match_operand 0 "register_operand" "=r")
1879 (match_operand 1 "memory_operand" "m")
1880 (match_operand:DI 2 "register_operand" "=r")])]
1881 "TARGET_64BIT"
1882 {
1883 rtx mem = operands[1];
1884 rtx addr = XEXP (mem, 0);
1885
1886 emit_move_insn (operands[2], addr);
1887 mem = replace_equiv_address_nv (mem, operands[2]);
1888
1889 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1890 DONE;
1891 })
1892
1893 (define_expand "movoi"
1894 [(set (match_operand:OI 0 "nonimmediate_operand")
1895 (match_operand:OI 1 "general_operand"))]
1896 "TARGET_AVX"
1897 "ix86_expand_move (OImode, operands); DONE;")
1898
1899 (define_expand "movti"
1900 [(set (match_operand:TI 0 "nonimmediate_operand")
1901 (match_operand:TI 1 "nonimmediate_operand"))]
1902 "TARGET_64BIT || TARGET_SSE"
1903 {
1904 if (TARGET_64BIT)
1905 ix86_expand_move (TImode, operands);
1906 else
1907 ix86_expand_vector_move (TImode, operands);
1908 DONE;
1909 })
1910
1911 ;; This expands to what emit_move_complex would generate if we didn't
1912 ;; have a movti pattern. Having this avoids problems with reload on
1913 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1914 ;; to have around all the time.
1915 (define_expand "movcdi"
1916 [(set (match_operand:CDI 0 "nonimmediate_operand")
1917 (match_operand:CDI 1 "general_operand"))]
1918 ""
1919 {
1920 if (push_operand (operands[0], CDImode))
1921 emit_move_complex_push (CDImode, operands[0], operands[1]);
1922 else
1923 emit_move_complex_parts (operands[0], operands[1]);
1924 DONE;
1925 })
1926
1927 (define_expand "mov<mode>"
1928 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1929 (match_operand:SWI1248x 1 "general_operand"))]
1930 ""
1931 "ix86_expand_move (<MODE>mode, operands); DONE;")
1932
1933 (define_insn "*mov<mode>_xor"
1934 [(set (match_operand:SWI48 0 "register_operand" "=r")
1935 (match_operand:SWI48 1 "const0_operand"))
1936 (clobber (reg:CC FLAGS_REG))]
1937 "reload_completed"
1938 "xor{l}\t%k0, %k0"
1939 [(set_attr "type" "alu1")
1940 (set_attr "mode" "SI")
1941 (set_attr "length_immediate" "0")])
1942
1943 (define_insn "*mov<mode>_or"
1944 [(set (match_operand:SWI48 0 "register_operand" "=r")
1945 (match_operand:SWI48 1 "const_int_operand"))
1946 (clobber (reg:CC FLAGS_REG))]
1947 "reload_completed
1948 && operands[1] == constm1_rtx"
1949 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1950 [(set_attr "type" "alu1")
1951 (set_attr "mode" "<MODE>")
1952 (set_attr "length_immediate" "1")])
1953
1954 (define_insn "*movxi_internal_avx512f"
1955 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1956 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
1957 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1958 {
1959 switch (which_alternative)
1960 {
1961 case 0:
1962 return standard_sse_constant_opcode (insn, operands[1]);
1963 case 1:
1964 case 2:
1965 if (misaligned_operand (operands[0], XImode)
1966 || misaligned_operand (operands[1], XImode))
1967 return "vmovdqu32\t{%1, %0|%0, %1}";
1968 else
1969 return "vmovdqa32\t{%1, %0|%0, %1}";
1970 default:
1971 gcc_unreachable ();
1972 }
1973 }
1974 [(set_attr "type" "sselog1,ssemov,ssemov")
1975 (set_attr "prefix" "evex")
1976 (set_attr "mode" "XI")])
1977
1978 (define_insn "*movoi_internal_avx"
1979 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1980 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))]
1981 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1982 {
1983 switch (get_attr_type (insn))
1984 {
1985 case TYPE_SSELOG1:
1986 return standard_sse_constant_opcode (insn, operands[1]);
1987
1988 case TYPE_SSEMOV:
1989 if (misaligned_operand (operands[0], OImode)
1990 || misaligned_operand (operands[1], OImode))
1991 {
1992 if (get_attr_mode (insn) == MODE_V8SF)
1993 return "vmovups\t{%1, %0|%0, %1}";
1994 else if (get_attr_mode (insn) == MODE_XI)
1995 return "vmovdqu32\t{%1, %0|%0, %1}";
1996 else
1997 return "vmovdqu\t{%1, %0|%0, %1}";
1998 }
1999 else
2000 {
2001 if (get_attr_mode (insn) == MODE_V8SF)
2002 return "vmovaps\t{%1, %0|%0, %1}";
2003 else if (get_attr_mode (insn) == MODE_XI)
2004 return "vmovdqa32\t{%1, %0|%0, %1}";
2005 else
2006 return "vmovdqa\t{%1, %0|%0, %1}";
2007 }
2008
2009 default:
2010 gcc_unreachable ();
2011 }
2012 }
2013 [(set_attr "type" "sselog1,ssemov,ssemov")
2014 (set_attr "prefix" "vex")
2015 (set (attr "mode")
2016 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2017 (match_operand 1 "ext_sse_reg_operand"))
2018 (const_string "XI")
2019 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2020 (const_string "V8SF")
2021 (and (eq_attr "alternative" "2")
2022 (match_test "TARGET_SSE_TYPELESS_STORES"))
2023 (const_string "V8SF")
2024 ]
2025 (const_string "OI")))])
2026
2027 (define_insn "*movti_internal"
2028 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2029 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))]
2030 "(TARGET_64BIT || TARGET_SSE)
2031 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2032 {
2033 switch (get_attr_type (insn))
2034 {
2035 case TYPE_MULTI:
2036 return "#";
2037
2038 case TYPE_SSELOG1:
2039 return standard_sse_constant_opcode (insn, operands[1]);
2040
2041 case TYPE_SSEMOV:
2042 /* TDmode values are passed as TImode on the stack. Moving them
2043 to stack may result in unaligned memory access. */
2044 if (misaligned_operand (operands[0], TImode)
2045 || misaligned_operand (operands[1], TImode))
2046 {
2047 if (get_attr_mode (insn) == MODE_V4SF)
2048 return "%vmovups\t{%1, %0|%0, %1}";
2049 else if (get_attr_mode (insn) == MODE_XI)
2050 return "vmovdqu32\t{%1, %0|%0, %1}";
2051 else
2052 return "%vmovdqu\t{%1, %0|%0, %1}";
2053 }
2054 else
2055 {
2056 if (get_attr_mode (insn) == MODE_V4SF)
2057 return "%vmovaps\t{%1, %0|%0, %1}";
2058 else if (get_attr_mode (insn) == MODE_XI)
2059 return "vmovdqa32\t{%1, %0|%0, %1}";
2060 else
2061 return "%vmovdqa\t{%1, %0|%0, %1}";
2062 }
2063
2064 default:
2065 gcc_unreachable ();
2066 }
2067 }
2068 [(set_attr "isa" "x64,x64,*,*,*")
2069 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2070 (set (attr "prefix")
2071 (if_then_else (eq_attr "type" "sselog1,ssemov")
2072 (const_string "maybe_vex")
2073 (const_string "orig")))
2074 (set (attr "mode")
2075 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2076 (match_operand 1 "ext_sse_reg_operand"))
2077 (const_string "XI")
2078 (eq_attr "alternative" "0,1")
2079 (const_string "DI")
2080 (ior (not (match_test "TARGET_SSE2"))
2081 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2082 (const_string "V4SF")
2083 (and (eq_attr "alternative" "4")
2084 (match_test "TARGET_SSE_TYPELESS_STORES"))
2085 (const_string "V4SF")
2086 (match_test "TARGET_AVX")
2087 (const_string "TI")
2088 (match_test "optimize_function_for_size_p (cfun)")
2089 (const_string "V4SF")
2090 ]
2091 (const_string "TI")))])
2092
2093 (define_split
2094 [(set (match_operand:TI 0 "nonimmediate_operand")
2095 (match_operand:TI 1 "general_operand"))]
2096 "reload_completed
2097 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2098 [(const_int 0)]
2099 "ix86_split_long_move (operands); DONE;")
2100
2101 (define_insn "*movdi_internal"
2102 [(set (match_operand:DI 0 "nonimmediate_operand"
2103 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2104 (match_operand:DI 1 "general_operand"
2105 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2106 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2107 {
2108 switch (get_attr_type (insn))
2109 {
2110 case TYPE_MSKMOV:
2111 return "kmovq\t{%1, %0|%0, %1}";
2112
2113 case TYPE_MULTI:
2114 return "#";
2115
2116 case TYPE_MMX:
2117 return "pxor\t%0, %0";
2118
2119 case TYPE_MMXMOV:
2120 /* Handle broken assemblers that require movd instead of movq. */
2121 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2122 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2123 return "movd\t{%1, %0|%0, %1}";
2124 return "movq\t{%1, %0|%0, %1}";
2125
2126 case TYPE_SSELOG1:
2127 if (GENERAL_REG_P (operands[0]))
2128 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2129
2130 return standard_sse_constant_opcode (insn, operands[1]);
2131
2132 case TYPE_SSEMOV:
2133 switch (get_attr_mode (insn))
2134 {
2135 case MODE_DI:
2136 /* Handle broken assemblers that require movd instead of movq. */
2137 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2138 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2139 return "%vmovd\t{%1, %0|%0, %1}";
2140 return "%vmovq\t{%1, %0|%0, %1}";
2141 case MODE_TI:
2142 return "%vmovdqa\t{%1, %0|%0, %1}";
2143 case MODE_XI:
2144 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2145
2146 case MODE_V2SF:
2147 gcc_assert (!TARGET_AVX);
2148 return "movlps\t{%1, %0|%0, %1}";
2149 case MODE_V4SF:
2150 return "%vmovaps\t{%1, %0|%0, %1}";
2151
2152 default:
2153 gcc_unreachable ();
2154 }
2155
2156 case TYPE_SSECVT:
2157 if (SSE_REG_P (operands[0]))
2158 return "movq2dq\t{%1, %0|%0, %1}";
2159 else
2160 return "movdq2q\t{%1, %0|%0, %1}";
2161
2162 case TYPE_LEA:
2163 return "lea{q}\t{%E1, %0|%0, %E1}";
2164
2165 case TYPE_IMOV:
2166 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2167 if (get_attr_mode (insn) == MODE_SI)
2168 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2169 else if (which_alternative == 4)
2170 return "movabs{q}\t{%1, %0|%0, %1}";
2171 else if (ix86_use_lea_for_mov (insn, operands))
2172 return "lea{q}\t{%E1, %0|%0, %E1}";
2173 else
2174 return "mov{q}\t{%1, %0|%0, %1}";
2175
2176 default:
2177 gcc_unreachable ();
2178 }
2179 }
2180 [(set (attr "isa")
2181 (cond [(eq_attr "alternative" "0,1")
2182 (const_string "nox64")
2183 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2184 (const_string "x64")
2185 (eq_attr "alternative" "17")
2186 (const_string "x64_sse4")
2187 ]
2188 (const_string "*")))
2189 (set (attr "type")
2190 (cond [(eq_attr "alternative" "0,1")
2191 (const_string "multi")
2192 (eq_attr "alternative" "6")
2193 (const_string "mmx")
2194 (eq_attr "alternative" "7,8,9,10,11")
2195 (const_string "mmxmov")
2196 (eq_attr "alternative" "12,17")
2197 (const_string "sselog1")
2198 (eq_attr "alternative" "13,14,15,16,18")
2199 (const_string "ssemov")
2200 (eq_attr "alternative" "19,20")
2201 (const_string "ssecvt")
2202 (eq_attr "alternative" "21,22,23,24")
2203 (const_string "mskmov")
2204 (match_operand 1 "pic_32bit_operand")
2205 (const_string "lea")
2206 ]
2207 (const_string "imov")))
2208 (set (attr "modrm")
2209 (if_then_else
2210 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2211 (const_string "0")
2212 (const_string "*")))
2213 (set (attr "length_immediate")
2214 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2215 (const_string "8")
2216 (eq_attr "alternative" "17")
2217 (const_string "1")
2218 ]
2219 (const_string "*")))
2220 (set (attr "prefix_rex")
2221 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2222 (const_string "1")
2223 (const_string "*")))
2224 (set (attr "prefix_extra")
2225 (if_then_else (eq_attr "alternative" "17")
2226 (const_string "1")
2227 (const_string "*")))
2228 (set (attr "prefix")
2229 (if_then_else (eq_attr "type" "sselog1,ssemov")
2230 (const_string "maybe_vex")
2231 (const_string "orig")))
2232 (set (attr "prefix_data16")
2233 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2234 (const_string "1")
2235 (const_string "*")))
2236 (set (attr "mode")
2237 (cond [(eq_attr "alternative" "2")
2238 (const_string "SI")
2239 (eq_attr "alternative" "12,13")
2240 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2241 (match_operand 1 "ext_sse_reg_operand"))
2242 (const_string "XI")
2243 (ior (not (match_test "TARGET_SSE2"))
2244 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2245 (const_string "V4SF")
2246 (match_test "TARGET_AVX")
2247 (const_string "TI")
2248 (match_test "optimize_function_for_size_p (cfun)")
2249 (const_string "V4SF")
2250 ]
2251 (const_string "TI"))
2252
2253 (and (eq_attr "alternative" "14,15")
2254 (not (match_test "TARGET_SSE2")))
2255 (const_string "V2SF")
2256 (eq_attr "alternative" "17")
2257 (const_string "TI")
2258 ]
2259 (const_string "DI")))])
2260
2261 (define_split
2262 [(set (match_operand:DI 0 "nonimmediate_operand")
2263 (match_operand:DI 1 "general_operand"))]
2264 "!TARGET_64BIT && reload_completed
2265 && !(MMX_REG_P (operands[0])
2266 || SSE_REG_P (operands[0])
2267 || MASK_REG_P (operands[0]))
2268 && !(MMX_REG_P (operands[1])
2269 || SSE_REG_P (operands[1])
2270 || MASK_REG_P (operands[1]))"
2271 [(const_int 0)]
2272 "ix86_split_long_move (operands); DONE;")
2273
2274 (define_insn "*movsi_internal"
2275 [(set (match_operand:SI 0 "nonimmediate_operand"
2276 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm")
2277 (match_operand:SI 1 "general_operand"
2278 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))]
2279 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2280 {
2281 switch (get_attr_type (insn))
2282 {
2283 case TYPE_SSELOG1:
2284 if (GENERAL_REG_P (operands[0]))
2285 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2286
2287 return standard_sse_constant_opcode (insn, operands[1]);
2288
2289 case TYPE_MSKMOV:
2290 return "kmovd\t{%1, %0|%0, %1}";
2291
2292 case TYPE_SSEMOV:
2293 switch (get_attr_mode (insn))
2294 {
2295 case MODE_SI:
2296 return "%vmovd\t{%1, %0|%0, %1}";
2297 case MODE_TI:
2298 return "%vmovdqa\t{%1, %0|%0, %1}";
2299 case MODE_XI:
2300 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2301
2302 case MODE_V4SF:
2303 return "%vmovaps\t{%1, %0|%0, %1}";
2304
2305 case MODE_SF:
2306 gcc_assert (!TARGET_AVX);
2307 return "movss\t{%1, %0|%0, %1}";
2308
2309 default:
2310 gcc_unreachable ();
2311 }
2312
2313 case TYPE_MMX:
2314 return "pxor\t%0, %0";
2315
2316 case TYPE_MMXMOV:
2317 switch (get_attr_mode (insn))
2318 {
2319 case MODE_DI:
2320 return "movq\t{%1, %0|%0, %1}";
2321 case MODE_SI:
2322 return "movd\t{%1, %0|%0, %1}";
2323
2324 default:
2325 gcc_unreachable ();
2326 }
2327
2328 case TYPE_LEA:
2329 return "lea{l}\t{%E1, %0|%0, %E1}";
2330
2331 case TYPE_IMOV:
2332 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2333 if (ix86_use_lea_for_mov (insn, operands))
2334 return "lea{l}\t{%E1, %0|%0, %E1}";
2335 else
2336 return "mov{l}\t{%1, %0|%0, %1}";
2337
2338 default:
2339 gcc_unreachable ();
2340 }
2341 }
2342 [(set (attr "isa")
2343 (if_then_else (eq_attr "alternative" "11")
2344 (const_string "sse4")
2345 (const_string "*")))
2346 (set (attr "type")
2347 (cond [(eq_attr "alternative" "2")
2348 (const_string "mmx")
2349 (eq_attr "alternative" "3,4,5")
2350 (const_string "mmxmov")
2351 (eq_attr "alternative" "6,11")
2352 (const_string "sselog1")
2353 (eq_attr "alternative" "7,8,9,10,12")
2354 (const_string "ssemov")
2355 (eq_attr "alternative" "13,14")
2356 (const_string "mskmov")
2357 (match_operand 1 "pic_32bit_operand")
2358 (const_string "lea")
2359 ]
2360 (const_string "imov")))
2361 (set (attr "length_immediate")
2362 (if_then_else (eq_attr "alternative" "11")
2363 (const_string "1")
2364 (const_string "*")))
2365 (set (attr "prefix_extra")
2366 (if_then_else (eq_attr "alternative" "11")
2367 (const_string "1")
2368 (const_string "*")))
2369 (set (attr "prefix")
2370 (if_then_else (eq_attr "type" "sselog1,ssemov")
2371 (const_string "maybe_vex")
2372 (const_string "orig")))
2373 (set (attr "prefix_data16")
2374 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2375 (const_string "1")
2376 (const_string "*")))
2377 (set (attr "mode")
2378 (cond [(eq_attr "alternative" "2,3")
2379 (const_string "DI")
2380 (eq_attr "alternative" "6,7")
2381 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2382 (match_operand 1 "ext_sse_reg_operand"))
2383 (const_string "XI")
2384 (ior (not (match_test "TARGET_SSE2"))
2385 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2386 (const_string "V4SF")
2387 (match_test "TARGET_AVX")
2388 (const_string "TI")
2389 (match_test "optimize_function_for_size_p (cfun)")
2390 (const_string "V4SF")
2391 ]
2392 (const_string "TI"))
2393
2394 (and (eq_attr "alternative" "8,9")
2395 (not (match_test "TARGET_SSE2")))
2396 (const_string "SF")
2397 (eq_attr "alternative" "11")
2398 (const_string "TI")
2399 ]
2400 (const_string "SI")))])
2401
2402 (define_insn "kmovw"
2403 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2404 (unspec:HI
2405 [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2406 UNSPEC_KMOV))]
2407 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2408 "@
2409 kmovw\t{%k1, %0|%0, %k1}
2410 kmovw\t{%1, %0|%0, %1}";
2411 [(set_attr "mode" "HI")
2412 (set_attr "type" "mskmov")
2413 (set_attr "prefix" "vex")])
2414
2415
2416 (define_insn "*movhi_internal"
2417 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2418 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,rm,k,k"))]
2419 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2420 {
2421 switch (get_attr_type (insn))
2422 {
2423 case TYPE_IMOVX:
2424 /* movzwl is faster than movw on p2 due to partial word stalls,
2425 though not as fast as an aligned movl. */
2426 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2427
2428 case TYPE_MSKMOV:
2429 switch (which_alternative)
2430 {
2431 case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2432 case 5: return "kmovw\t{%1, %0|%0, %1}";
2433 case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2434 default: gcc_unreachable ();
2435 }
2436
2437 default:
2438 if (get_attr_mode (insn) == MODE_SI)
2439 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2440 else
2441 return "mov{w}\t{%1, %0|%0, %1}";
2442 }
2443 }
2444 [(set (attr "type")
2445 (cond [(eq_attr "alternative" "4,5,6")
2446 (const_string "mskmov")
2447 (match_test "optimize_function_for_size_p (cfun)")
2448 (const_string "imov")
2449 (and (eq_attr "alternative" "0")
2450 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2451 (not (match_test "TARGET_HIMODE_MATH"))))
2452 (const_string "imov")
2453 (and (eq_attr "alternative" "1,2")
2454 (match_operand:HI 1 "aligned_operand"))
2455 (const_string "imov")
2456 (and (match_test "TARGET_MOVX")
2457 (eq_attr "alternative" "0,2"))
2458 (const_string "imovx")
2459 ]
2460 (const_string "imov")))
2461 (set (attr "prefix")
2462 (if_then_else (eq_attr "alternative" "4,5,6")
2463 (const_string "vex")
2464 (const_string "orig")))
2465 (set (attr "mode")
2466 (cond [(eq_attr "type" "imovx")
2467 (const_string "SI")
2468 (and (eq_attr "alternative" "1,2")
2469 (match_operand:HI 1 "aligned_operand"))
2470 (const_string "SI")
2471 (and (eq_attr "alternative" "0")
2472 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2473 (not (match_test "TARGET_HIMODE_MATH"))))
2474 (const_string "SI")
2475 ]
2476 (const_string "HI")))])
2477
2478 ;; Situation is quite tricky about when to choose full sized (SImode) move
2479 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2480 ;; partial register dependency machines (such as AMD Athlon), where QImode
2481 ;; moves issue extra dependency and for partial register stalls machines
2482 ;; that don't use QImode patterns (and QImode move cause stall on the next
2483 ;; instruction).
2484 ;;
2485 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2486 ;; register stall machines with, where we use QImode instructions, since
2487 ;; partial register stall can be caused there. Then we use movzx.
2488
2489 (define_insn "*movqi_internal"
2490 [(set (match_operand:QI 0 "nonimmediate_operand"
2491 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2492 (match_operand:QI 1 "general_operand"
2493 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2494 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2495 {
2496 switch (get_attr_type (insn))
2497 {
2498 case TYPE_IMOVX:
2499 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2500 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2501
2502 case TYPE_MSKMOV:
2503 switch (which_alternative)
2504 {
2505 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2506 : "kmovw\t{%k1, %0|%0, %k1}";
2507 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2508 : "kmovw\t{%1, %0|%0, %1}";
2509 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2510 : "kmovw\t{%1, %k0|%k0, %1}";
2511 case 10:
2512 case 11:
2513 gcc_assert (TARGET_AVX512DQ);
2514 return "kmovb\t{%1, %0|%0, %1}";
2515 default: gcc_unreachable ();
2516 }
2517
2518 default:
2519 if (get_attr_mode (insn) == MODE_SI)
2520 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2521 else
2522 return "mov{b}\t{%1, %0|%0, %1}";
2523 }
2524 }
2525 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2526 (set (attr "type")
2527 (cond [(eq_attr "alternative" "3,5")
2528 (const_string "imovx")
2529 (eq_attr "alternative" "7,8,9,10,11")
2530 (const_string "mskmov")
2531 (and (eq_attr "alternative" "5")
2532 (not (match_operand:QI 1 "aligned_operand")))
2533 (const_string "imovx")
2534 (match_test "optimize_function_for_size_p (cfun)")
2535 (const_string "imov")
2536 (and (eq_attr "alternative" "3")
2537 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2538 (not (match_test "TARGET_QIMODE_MATH"))))
2539 (const_string "imov")
2540 (and (match_test "TARGET_MOVX")
2541 (eq_attr "alternative" "2"))
2542 (const_string "imovx")
2543 ]
2544 (const_string "imov")))
2545 (set (attr "prefix")
2546 (if_then_else (eq_attr "alternative" "7,8,9")
2547 (const_string "vex")
2548 (const_string "orig")))
2549 (set (attr "mode")
2550 (cond [(eq_attr "alternative" "3,4,5")
2551 (const_string "SI")
2552 (eq_attr "alternative" "6")
2553 (const_string "QI")
2554 (eq_attr "type" "imovx")
2555 (const_string "SI")
2556 (and (eq_attr "type" "imov")
2557 (and (eq_attr "alternative" "0,1")
2558 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2559 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2560 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2561 (const_string "SI")
2562 ;; Avoid partial register stalls when not using QImode arithmetic
2563 (and (eq_attr "type" "imov")
2564 (and (eq_attr "alternative" "0,1")
2565 (and (match_test "TARGET_PARTIAL_REG_STALL")
2566 (not (match_test "TARGET_QIMODE_MATH")))))
2567 (const_string "SI")
2568 ]
2569 (const_string "QI")))])
2570
2571 ;; Stores and loads of ax to arbitrary constant address.
2572 ;; We fake an second form of instruction to force reload to load address
2573 ;; into register when rax is not available
2574 (define_insn "*movabs<mode>_1"
2575 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2576 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2577 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2578 "@
2579 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2580 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2581 [(set_attr "type" "imov")
2582 (set_attr "modrm" "0,*")
2583 (set_attr "length_address" "8,0")
2584 (set_attr "length_immediate" "0,*")
2585 (set_attr "memory" "store")
2586 (set_attr "mode" "<MODE>")])
2587
2588 (define_insn "*movabs<mode>_2"
2589 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2590 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2591 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2592 "@
2593 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2594 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2595 [(set_attr "type" "imov")
2596 (set_attr "modrm" "0,*")
2597 (set_attr "length_address" "8,0")
2598 (set_attr "length_immediate" "0")
2599 (set_attr "memory" "load")
2600 (set_attr "mode" "<MODE>")])
2601
2602 (define_insn "*swap<mode>"
2603 [(set (match_operand:SWI48 0 "register_operand" "+r")
2604 (match_operand:SWI48 1 "register_operand" "+r"))
2605 (set (match_dup 1)
2606 (match_dup 0))]
2607 ""
2608 "xchg{<imodesuffix>}\t%1, %0"
2609 [(set_attr "type" "imov")
2610 (set_attr "mode" "<MODE>")
2611 (set_attr "pent_pair" "np")
2612 (set_attr "athlon_decode" "vector")
2613 (set_attr "amdfam10_decode" "double")
2614 (set_attr "bdver1_decode" "double")])
2615
2616 (define_insn "*swap<mode>_1"
2617 [(set (match_operand:SWI12 0 "register_operand" "+r")
2618 (match_operand:SWI12 1 "register_operand" "+r"))
2619 (set (match_dup 1)
2620 (match_dup 0))]
2621 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2622 "xchg{l}\t%k1, %k0"
2623 [(set_attr "type" "imov")
2624 (set_attr "mode" "SI")
2625 (set_attr "pent_pair" "np")
2626 (set_attr "athlon_decode" "vector")
2627 (set_attr "amdfam10_decode" "double")
2628 (set_attr "bdver1_decode" "double")])
2629
2630 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2631 ;; is disabled for AMDFAM10
2632 (define_insn "*swap<mode>_2"
2633 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2634 (match_operand:SWI12 1 "register_operand" "+<r>"))
2635 (set (match_dup 1)
2636 (match_dup 0))]
2637 "TARGET_PARTIAL_REG_STALL"
2638 "xchg{<imodesuffix>}\t%1, %0"
2639 [(set_attr "type" "imov")
2640 (set_attr "mode" "<MODE>")
2641 (set_attr "pent_pair" "np")
2642 (set_attr "athlon_decode" "vector")])
2643
2644 (define_expand "movstrict<mode>"
2645 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2646 (match_operand:SWI12 1 "general_operand"))]
2647 ""
2648 {
2649 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2650 FAIL;
2651 if (GET_CODE (operands[0]) == SUBREG
2652 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2653 FAIL;
2654 /* Don't generate memory->memory moves, go through a register */
2655 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2656 operands[1] = force_reg (<MODE>mode, operands[1]);
2657 })
2658
2659 (define_insn "*movstrict<mode>_1"
2660 [(set (strict_low_part
2661 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2662 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2663 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2664 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2665 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2666 [(set_attr "type" "imov")
2667 (set_attr "mode" "<MODE>")])
2668
2669 (define_insn "*movstrict<mode>_xor"
2670 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2671 (match_operand:SWI12 1 "const0_operand"))
2672 (clobber (reg:CC FLAGS_REG))]
2673 "reload_completed"
2674 "xor{<imodesuffix>}\t%0, %0"
2675 [(set_attr "type" "alu1")
2676 (set_attr "mode" "<MODE>")
2677 (set_attr "length_immediate" "0")])
2678
2679 (define_insn "*mov<mode>_extv_1"
2680 [(set (match_operand:SWI24 0 "register_operand" "=R")
2681 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2682 (const_int 8)
2683 (const_int 8)))]
2684 ""
2685 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2686 [(set_attr "type" "imovx")
2687 (set_attr "mode" "SI")])
2688
2689 (define_insn "*movqi_extv_1"
2690 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2691 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2692 (const_int 8)
2693 (const_int 8)))]
2694 ""
2695 {
2696 switch (get_attr_type (insn))
2697 {
2698 case TYPE_IMOVX:
2699 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2700 default:
2701 return "mov{b}\t{%h1, %0|%0, %h1}";
2702 }
2703 }
2704 [(set_attr "isa" "*,*,nox64")
2705 (set (attr "type")
2706 (if_then_else (and (match_operand:QI 0 "register_operand")
2707 (ior (not (match_operand:QI 0 "QIreg_operand"))
2708 (match_test "TARGET_MOVX")))
2709 (const_string "imovx")
2710 (const_string "imov")))
2711 (set (attr "mode")
2712 (if_then_else (eq_attr "type" "imovx")
2713 (const_string "SI")
2714 (const_string "QI")))])
2715
2716 (define_insn "*mov<mode>_extzv_1"
2717 [(set (match_operand:SWI48 0 "register_operand" "=R")
2718 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2719 (const_int 8)
2720 (const_int 8)))]
2721 ""
2722 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2723 [(set_attr "type" "imovx")
2724 (set_attr "mode" "SI")])
2725
2726 (define_insn "*movqi_extzv_2"
2727 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2728 (subreg:QI
2729 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2730 (const_int 8)
2731 (const_int 8)) 0))]
2732 ""
2733 {
2734 switch (get_attr_type (insn))
2735 {
2736 case TYPE_IMOVX:
2737 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2738 default:
2739 return "mov{b}\t{%h1, %0|%0, %h1}";
2740 }
2741 }
2742 [(set_attr "isa" "*,*,nox64")
2743 (set (attr "type")
2744 (if_then_else (and (match_operand:QI 0 "register_operand")
2745 (ior (not (match_operand:QI 0 "QIreg_operand"))
2746 (match_test "TARGET_MOVX")))
2747 (const_string "imovx")
2748 (const_string "imov")))
2749 (set (attr "mode")
2750 (if_then_else (eq_attr "type" "imovx")
2751 (const_string "SI")
2752 (const_string "QI")))])
2753
2754 (define_insn "mov<mode>_insv_1"
2755 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2756 (const_int 8)
2757 (const_int 8))
2758 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2759 ""
2760 {
2761 if (CONST_INT_P (operands[1]))
2762 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2763 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2764 }
2765 [(set_attr "isa" "*,nox64")
2766 (set_attr "type" "imov")
2767 (set_attr "mode" "QI")])
2768
2769 (define_insn "*movqi_insv_2"
2770 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2771 (const_int 8)
2772 (const_int 8))
2773 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2774 (const_int 8)))]
2775 ""
2776 "mov{b}\t{%h1, %h0|%h0, %h1}"
2777 [(set_attr "type" "imov")
2778 (set_attr "mode" "QI")])
2779 \f
2780 ;; Floating point push instructions.
2781
2782 (define_insn "*pushtf"
2783 [(set (match_operand:TF 0 "push_operand" "=<,<")
2784 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2785 "TARGET_64BIT || TARGET_SSE"
2786 {
2787 /* This insn should be already split before reg-stack. */
2788 gcc_unreachable ();
2789 }
2790 [(set_attr "isa" "*,x64")
2791 (set_attr "type" "multi")
2792 (set_attr "unit" "sse,*")
2793 (set_attr "mode" "TF,DI")])
2794
2795 ;; %%% Kill this when call knows how to work this out.
2796 (define_split
2797 [(set (match_operand:TF 0 "push_operand")
2798 (match_operand:TF 1 "sse_reg_operand"))]
2799 "TARGET_SSE && reload_completed"
2800 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2801 (set (match_dup 0) (match_dup 1))]
2802 {
2803 /* Preserve memory attributes. */
2804 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2805 })
2806
2807 (define_insn "*pushxf"
2808 [(set (match_operand:XF 0 "push_operand" "=<,<")
2809 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2810 ""
2811 {
2812 /* This insn should be already split before reg-stack. */
2813 gcc_unreachable ();
2814 }
2815 [(set_attr "type" "multi")
2816 (set_attr "unit" "i387,*")
2817 (set (attr "mode")
2818 (cond [(eq_attr "alternative" "1")
2819 (if_then_else (match_test "TARGET_64BIT")
2820 (const_string "DI")
2821 (const_string "SI"))
2822 ]
2823 (const_string "XF")))])
2824
2825 ;; %%% Kill this when call knows how to work this out.
2826 (define_split
2827 [(set (match_operand:XF 0 "push_operand")
2828 (match_operand:XF 1 "fp_register_operand"))]
2829 "reload_completed"
2830 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2831 (set (match_dup 0) (match_dup 1))]
2832 {
2833 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2834 /* Preserve memory attributes. */
2835 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2836 })
2837
2838 (define_insn "*pushdf"
2839 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2840 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2841 ""
2842 {
2843 /* This insn should be already split before reg-stack. */
2844 gcc_unreachable ();
2845 }
2846 [(set_attr "isa" "*,nox64,x64,sse2")
2847 (set_attr "type" "multi")
2848 (set_attr "unit" "i387,*,*,sse")
2849 (set_attr "mode" "DF,SI,DI,DF")])
2850
2851 ;; %%% Kill this when call knows how to work this out.
2852 (define_split
2853 [(set (match_operand:DF 0 "push_operand")
2854 (match_operand:DF 1 "any_fp_register_operand"))]
2855 "reload_completed"
2856 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2857 (set (match_dup 0) (match_dup 1))]
2858 {
2859 /* Preserve memory attributes. */
2860 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2861 })
2862
2863 (define_insn "*pushsf_rex64"
2864 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2865 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2866 "TARGET_64BIT"
2867 {
2868 /* Anything else should be already split before reg-stack. */
2869 gcc_assert (which_alternative == 1);
2870 return "push{q}\t%q1";
2871 }
2872 [(set_attr "type" "multi,push,multi")
2873 (set_attr "unit" "i387,*,*")
2874 (set_attr "mode" "SF,DI,SF")])
2875
2876 (define_insn "*pushsf"
2877 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2878 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2879 "!TARGET_64BIT"
2880 {
2881 /* Anything else should be already split before reg-stack. */
2882 gcc_assert (which_alternative == 1);
2883 return "push{l}\t%1";
2884 }
2885 [(set_attr "type" "multi,push,multi")
2886 (set_attr "unit" "i387,*,*")
2887 (set_attr "mode" "SF,SI,SF")])
2888
2889 ;; %%% Kill this when call knows how to work this out.
2890 (define_split
2891 [(set (match_operand:SF 0 "push_operand")
2892 (match_operand:SF 1 "any_fp_register_operand"))]
2893 "reload_completed"
2894 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2895 (set (match_dup 0) (match_dup 1))]
2896 {
2897 rtx op = XEXP (operands[0], 0);
2898 if (GET_CODE (op) == PRE_DEC)
2899 {
2900 gcc_assert (!TARGET_64BIT);
2901 op = GEN_INT (-4);
2902 }
2903 else
2904 {
2905 op = XEXP (XEXP (op, 1), 1);
2906 gcc_assert (CONST_INT_P (op));
2907 }
2908 operands[2] = op;
2909 /* Preserve memory attributes. */
2910 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2911 })
2912
2913 (define_split
2914 [(set (match_operand:SF 0 "push_operand")
2915 (match_operand:SF 1 "memory_operand"))]
2916 "reload_completed
2917 && (operands[2] = find_constant_src (insn))"
2918 [(set (match_dup 0) (match_dup 2))])
2919
2920 (define_split
2921 [(set (match_operand 0 "push_operand")
2922 (match_operand 1 "general_operand"))]
2923 "reload_completed
2924 && (GET_MODE (operands[0]) == TFmode
2925 || GET_MODE (operands[0]) == XFmode
2926 || GET_MODE (operands[0]) == DFmode)
2927 && !ANY_FP_REG_P (operands[1])"
2928 [(const_int 0)]
2929 "ix86_split_long_move (operands); DONE;")
2930 \f
2931 ;; Floating point move instructions.
2932
2933 (define_expand "movtf"
2934 [(set (match_operand:TF 0 "nonimmediate_operand")
2935 (match_operand:TF 1 "nonimmediate_operand"))]
2936 "TARGET_64BIT || TARGET_SSE"
2937 "ix86_expand_move (TFmode, operands); DONE;")
2938
2939 (define_expand "mov<mode>"
2940 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2941 (match_operand:X87MODEF 1 "general_operand"))]
2942 ""
2943 "ix86_expand_move (<MODE>mode, operands); DONE;")
2944
2945 (define_insn "*movtf_internal"
2946 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2947 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2948 "(TARGET_64BIT || TARGET_SSE)
2949 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2950 && (!can_create_pseudo_p ()
2951 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2952 || GET_CODE (operands[1]) != CONST_DOUBLE
2953 || (optimize_function_for_size_p (cfun)
2954 && standard_sse_constant_p (operands[1])
2955 && !memory_operand (operands[0], TFmode))
2956 || (!TARGET_MEMORY_MISMATCH_STALL
2957 && memory_operand (operands[0], TFmode)))"
2958 {
2959 switch (get_attr_type (insn))
2960 {
2961 case TYPE_SSELOG1:
2962 return standard_sse_constant_opcode (insn, operands[1]);
2963
2964 case TYPE_SSEMOV:
2965 /* Handle misaligned load/store since we
2966 don't have movmisaligntf pattern. */
2967 if (misaligned_operand (operands[0], TFmode)
2968 || misaligned_operand (operands[1], TFmode))
2969 {
2970 if (get_attr_mode (insn) == MODE_V4SF)
2971 return "%vmovups\t{%1, %0|%0, %1}";
2972 else
2973 return "%vmovdqu\t{%1, %0|%0, %1}";
2974 }
2975 else
2976 {
2977 if (get_attr_mode (insn) == MODE_V4SF)
2978 return "%vmovaps\t{%1, %0|%0, %1}";
2979 else
2980 return "%vmovdqa\t{%1, %0|%0, %1}";
2981 }
2982
2983 case TYPE_MULTI:
2984 return "#";
2985
2986 default:
2987 gcc_unreachable ();
2988 }
2989 }
2990 [(set_attr "isa" "*,*,*,x64,x64")
2991 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2992 (set (attr "prefix")
2993 (if_then_else (eq_attr "type" "sselog1,ssemov")
2994 (const_string "maybe_vex")
2995 (const_string "orig")))
2996 (set (attr "mode")
2997 (cond [(eq_attr "alternative" "3,4")
2998 (const_string "DI")
2999 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3000 (const_string "V4SF")
3001 (and (eq_attr "alternative" "2")
3002 (match_test "TARGET_SSE_TYPELESS_STORES"))
3003 (const_string "V4SF")
3004 (match_test "TARGET_AVX")
3005 (const_string "TI")
3006 (ior (not (match_test "TARGET_SSE2"))
3007 (match_test "optimize_function_for_size_p (cfun)"))
3008 (const_string "V4SF")
3009 ]
3010 (const_string "TI")))])
3011
3012 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
3013 (define_insn "*movxf_internal"
3014 [(set (match_operand:XF 0 "nonimmediate_operand"
3015 "=f,m,f,?Yx*r ,!o ,!o")
3016 (match_operand:XF 1 "general_operand"
3017 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
3018 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3019 && (!can_create_pseudo_p ()
3020 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3021 || GET_CODE (operands[1]) != CONST_DOUBLE
3022 || (optimize_function_for_size_p (cfun)
3023 && standard_80387_constant_p (operands[1]) > 0
3024 && !memory_operand (operands[0], XFmode))
3025 || (!TARGET_MEMORY_MISMATCH_STALL
3026 && memory_operand (operands[0], XFmode)))"
3027 {
3028 switch (get_attr_type (insn))
3029 {
3030 case TYPE_FMOV:
3031 if (which_alternative == 2)
3032 return standard_80387_constant_opcode (operands[1]);
3033 return output_387_reg_move (insn, operands);
3034
3035 case TYPE_MULTI:
3036 return "#";
3037
3038 default:
3039 gcc_unreachable ();
3040 }
3041 }
3042 [(set_attr "isa" "*,*,*,*,nox64,x64")
3043 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
3044 (set (attr "mode")
3045 (cond [(eq_attr "alternative" "3,4,5")
3046 (if_then_else (match_test "TARGET_64BIT")
3047 (const_string "DI")
3048 (const_string "SI"))
3049 ]
3050 (const_string "XF")))])
3051
3052 ;; Possible store forwarding (partial memory) stall in alternative 4.
3053 (define_insn "*movdf_internal"
3054 [(set (match_operand:DF 0 "nonimmediate_operand"
3055 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3056 (match_operand:DF 1 "general_operand"
3057 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3058 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3059 && (!can_create_pseudo_p ()
3060 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3061 || GET_CODE (operands[1]) != CONST_DOUBLE
3062 || (optimize_function_for_size_p (cfun)
3063 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3064 && standard_80387_constant_p (operands[1]) > 0)
3065 || (TARGET_SSE2 && TARGET_SSE_MATH
3066 && standard_sse_constant_p (operands[1])))
3067 && !memory_operand (operands[0], DFmode))
3068 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3069 && memory_operand (operands[0], DFmode)))"
3070 {
3071 switch (get_attr_type (insn))
3072 {
3073 case TYPE_FMOV:
3074 if (which_alternative == 2)
3075 return standard_80387_constant_opcode (operands[1]);
3076 return output_387_reg_move (insn, operands);
3077
3078 case TYPE_MULTI:
3079 return "#";
3080
3081 case TYPE_IMOV:
3082 if (get_attr_mode (insn) == MODE_SI)
3083 return "mov{l}\t{%1, %k0|%k0, %1}";
3084 else if (which_alternative == 8)
3085 return "movabs{q}\t{%1, %0|%0, %1}";
3086 else
3087 return "mov{q}\t{%1, %0|%0, %1}";
3088
3089 case TYPE_SSELOG1:
3090 return standard_sse_constant_opcode (insn, operands[1]);
3091
3092 case TYPE_SSEMOV:
3093 switch (get_attr_mode (insn))
3094 {
3095 case MODE_DF:
3096 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3097 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3098 return "%vmovsd\t{%1, %0|%0, %1}";
3099
3100 case MODE_V4SF:
3101 return "%vmovaps\t{%1, %0|%0, %1}";
3102 case MODE_V8DF:
3103 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3104 case MODE_V2DF:
3105 return "%vmovapd\t{%1, %0|%0, %1}";
3106
3107 case MODE_V2SF:
3108 gcc_assert (!TARGET_AVX);
3109 return "movlps\t{%1, %0|%0, %1}";
3110 case MODE_V1DF:
3111 gcc_assert (!TARGET_AVX);
3112 return "movlpd\t{%1, %0|%0, %1}";
3113
3114 case MODE_DI:
3115 /* Handle broken assemblers that require movd instead of movq. */
3116 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3117 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3118 return "%vmovd\t{%1, %0|%0, %1}";
3119 return "%vmovq\t{%1, %0|%0, %1}";
3120
3121 default:
3122 gcc_unreachable ();
3123 }
3124
3125 default:
3126 gcc_unreachable ();
3127 }
3128 }
3129 [(set (attr "isa")
3130 (cond [(eq_attr "alternative" "3,4")
3131 (const_string "nox64")
3132 (eq_attr "alternative" "5,6,7,8,17,18")
3133 (const_string "x64")
3134 (eq_attr "alternative" "9,10,11,12")
3135 (const_string "sse2")
3136 ]
3137 (const_string "*")))
3138 (set (attr "type")
3139 (cond [(eq_attr "alternative" "0,1,2")
3140 (const_string "fmov")
3141 (eq_attr "alternative" "3,4")
3142 (const_string "multi")
3143 (eq_attr "alternative" "5,6,7,8")
3144 (const_string "imov")
3145 (eq_attr "alternative" "9,13")
3146 (const_string "sselog1")
3147 ]
3148 (const_string "ssemov")))
3149 (set (attr "modrm")
3150 (if_then_else (eq_attr "alternative" "8")
3151 (const_string "0")
3152 (const_string "*")))
3153 (set (attr "length_immediate")
3154 (if_then_else (eq_attr "alternative" "8")
3155 (const_string "8")
3156 (const_string "*")))
3157 (set (attr "prefix")
3158 (if_then_else (eq_attr "type" "sselog1,ssemov")
3159 (const_string "maybe_vex")
3160 (const_string "orig")))
3161 (set (attr "prefix_data16")
3162 (if_then_else
3163 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3164 (eq_attr "mode" "V1DF"))
3165 (const_string "1")
3166 (const_string "*")))
3167 (set (attr "mode")
3168 (cond [(eq_attr "alternative" "3,4,7")
3169 (const_string "SI")
3170 (eq_attr "alternative" "5,6,8,17,18")
3171 (const_string "DI")
3172
3173 /* xorps is one byte shorter for non-AVX targets. */
3174 (eq_attr "alternative" "9,13")
3175 (cond [(not (match_test "TARGET_SSE2"))
3176 (const_string "V4SF")
3177 (match_test "TARGET_AVX512F")
3178 (const_string "XI")
3179 (match_test "TARGET_AVX")
3180 (const_string "V2DF")
3181 (match_test "optimize_function_for_size_p (cfun)")
3182 (const_string "V4SF")
3183 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3184 (const_string "TI")
3185 ]
3186 (const_string "V2DF"))
3187
3188 /* For architectures resolving dependencies on
3189 whole SSE registers use movapd to break dependency
3190 chains, otherwise use short move to avoid extra work. */
3191
3192 /* movaps is one byte shorter for non-AVX targets. */
3193 (eq_attr "alternative" "10,14")
3194 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3195 (match_operand 1 "ext_sse_reg_operand"))
3196 (const_string "V8DF")
3197 (ior (not (match_test "TARGET_SSE2"))
3198 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3199 (const_string "V4SF")
3200 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3201 (const_string "V2DF")
3202 (match_test "TARGET_AVX")
3203 (const_string "DF")
3204 (match_test "optimize_function_for_size_p (cfun)")
3205 (const_string "V4SF")
3206 ]
3207 (const_string "DF"))
3208
3209 /* For architectures resolving dependencies on register
3210 parts we may avoid extra work to zero out upper part
3211 of register. */
3212 (eq_attr "alternative" "11,15")
3213 (cond [(not (match_test "TARGET_SSE2"))
3214 (const_string "V2SF")
3215 (match_test "TARGET_AVX")
3216 (const_string "DF")
3217 (match_test "TARGET_SSE_SPLIT_REGS")
3218 (const_string "V1DF")
3219 ]
3220 (const_string "DF"))
3221
3222 (and (eq_attr "alternative" "12,16")
3223 (not (match_test "TARGET_SSE2")))
3224 (const_string "V2SF")
3225 ]
3226 (const_string "DF")))])
3227
3228 (define_insn "*movsf_internal"
3229 [(set (match_operand:SF 0 "nonimmediate_operand"
3230 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3231 (match_operand:SF 1 "general_operand"
3232 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
3233 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3234 && (!can_create_pseudo_p ()
3235 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3236 || GET_CODE (operands[1]) != CONST_DOUBLE
3237 || (optimize_function_for_size_p (cfun)
3238 && ((!TARGET_SSE_MATH
3239 && standard_80387_constant_p (operands[1]) > 0)
3240 || (TARGET_SSE_MATH
3241 && standard_sse_constant_p (operands[1]))))
3242 || memory_operand (operands[0], SFmode))"
3243 {
3244 switch (get_attr_type (insn))
3245 {
3246 case TYPE_FMOV:
3247 if (which_alternative == 2)
3248 return standard_80387_constant_opcode (operands[1]);
3249 return output_387_reg_move (insn, operands);
3250
3251 case TYPE_IMOV:
3252 return "mov{l}\t{%1, %0|%0, %1}";
3253
3254 case TYPE_SSELOG1:
3255 return standard_sse_constant_opcode (insn, operands[1]);
3256
3257 case TYPE_SSEMOV:
3258 switch (get_attr_mode (insn))
3259 {
3260 case MODE_SF:
3261 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3262 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3263 return "%vmovss\t{%1, %0|%0, %1}";
3264
3265 case MODE_V16SF:
3266 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3267 case MODE_V4SF:
3268 return "%vmovaps\t{%1, %0|%0, %1}";
3269
3270 case MODE_SI:
3271 return "%vmovd\t{%1, %0|%0, %1}";
3272
3273 default:
3274 gcc_unreachable ();
3275 }
3276
3277 case TYPE_MMXMOV:
3278 switch (get_attr_mode (insn))
3279 {
3280 case MODE_DI:
3281 return "movq\t{%1, %0|%0, %1}";
3282 case MODE_SI:
3283 return "movd\t{%1, %0|%0, %1}";
3284
3285 default:
3286 gcc_unreachable ();
3287 }
3288
3289 default:
3290 gcc_unreachable ();
3291 }
3292 }
3293 [(set (attr "type")
3294 (cond [(eq_attr "alternative" "0,1,2")
3295 (const_string "fmov")
3296 (eq_attr "alternative" "3,4")
3297 (const_string "imov")
3298 (eq_attr "alternative" "5")
3299 (const_string "sselog1")
3300 (eq_attr "alternative" "11,12,13,14,15")
3301 (const_string "mmxmov")
3302 ]
3303 (const_string "ssemov")))
3304 (set (attr "prefix")
3305 (if_then_else (eq_attr "type" "sselog1,ssemov")
3306 (const_string "maybe_vex")
3307 (const_string "orig")))
3308 (set (attr "prefix_data16")
3309 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3310 (const_string "1")
3311 (const_string "*")))
3312 (set (attr "mode")
3313 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3314 (const_string "SI")
3315 (eq_attr "alternative" "11")
3316 (const_string "DI")
3317 (eq_attr "alternative" "5")
3318 (cond [(not (match_test "TARGET_SSE2"))
3319 (const_string "V4SF")
3320 (match_test "TARGET_AVX512F")
3321 (const_string "V16SF")
3322 (match_test "TARGET_AVX")
3323 (const_string "V4SF")
3324 (match_test "optimize_function_for_size_p (cfun)")
3325 (const_string "V4SF")
3326 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3327 (const_string "TI")
3328 ]
3329 (const_string "V4SF"))
3330
3331 /* For architectures resolving dependencies on
3332 whole SSE registers use APS move to break dependency
3333 chains, otherwise use short move to avoid extra work.
3334
3335 Do the same for architectures resolving dependencies on
3336 the parts. While in DF mode it is better to always handle
3337 just register parts, the SF mode is different due to lack
3338 of instructions to load just part of the register. It is
3339 better to maintain the whole registers in single format
3340 to avoid problems on using packed logical operations. */
3341 (eq_attr "alternative" "6")
3342 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3343 (match_operand 1 "ext_sse_reg_operand"))
3344 (const_string "V16SF")
3345 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3346 (match_test "TARGET_SSE_SPLIT_REGS"))
3347 (const_string "V4SF")
3348 ]
3349 (const_string "SF"))
3350 ]
3351 (const_string "SF")))])
3352
3353 (define_split
3354 [(set (match_operand 0 "any_fp_register_operand")
3355 (match_operand 1 "memory_operand"))]
3356 "reload_completed
3357 && (GET_MODE (operands[0]) == TFmode
3358 || GET_MODE (operands[0]) == XFmode
3359 || GET_MODE (operands[0]) == DFmode
3360 || GET_MODE (operands[0]) == SFmode)
3361 && (operands[2] = find_constant_src (insn))"
3362 [(set (match_dup 0) (match_dup 2))]
3363 {
3364 rtx c = operands[2];
3365 int r = REGNO (operands[0]);
3366
3367 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3368 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3369 FAIL;
3370 })
3371
3372 (define_split
3373 [(set (match_operand 0 "any_fp_register_operand")
3374 (float_extend (match_operand 1 "memory_operand")))]
3375 "reload_completed
3376 && (GET_MODE (operands[0]) == TFmode
3377 || GET_MODE (operands[0]) == XFmode
3378 || GET_MODE (operands[0]) == DFmode)
3379 && (operands[2] = find_constant_src (insn))"
3380 [(set (match_dup 0) (match_dup 2))]
3381 {
3382 rtx c = operands[2];
3383 int r = REGNO (operands[0]);
3384
3385 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3386 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3387 FAIL;
3388 })
3389
3390 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3391 (define_split
3392 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3393 (match_operand:X87MODEF 1 "immediate_operand"))]
3394 "reload_completed
3395 && (standard_80387_constant_p (operands[1]) == 8
3396 || standard_80387_constant_p (operands[1]) == 9)"
3397 [(set (match_dup 0)(match_dup 1))
3398 (set (match_dup 0)
3399 (neg:X87MODEF (match_dup 0)))]
3400 {
3401 REAL_VALUE_TYPE r;
3402
3403 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3404 if (real_isnegzero (&r))
3405 operands[1] = CONST0_RTX (<MODE>mode);
3406 else
3407 operands[1] = CONST1_RTX (<MODE>mode);
3408 })
3409
3410 (define_split
3411 [(set (match_operand 0 "nonimmediate_operand")
3412 (match_operand 1 "general_operand"))]
3413 "reload_completed
3414 && (GET_MODE (operands[0]) == TFmode
3415 || GET_MODE (operands[0]) == XFmode
3416 || GET_MODE (operands[0]) == DFmode)
3417 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3418 [(const_int 0)]
3419 "ix86_split_long_move (operands); DONE;")
3420
3421 (define_insn "swapxf"
3422 [(set (match_operand:XF 0 "register_operand" "+f")
3423 (match_operand:XF 1 "register_operand" "+f"))
3424 (set (match_dup 1)
3425 (match_dup 0))]
3426 "TARGET_80387"
3427 {
3428 if (STACK_TOP_P (operands[0]))
3429 return "fxch\t%1";
3430 else
3431 return "fxch\t%0";
3432 }
3433 [(set_attr "type" "fxch")
3434 (set_attr "mode" "XF")])
3435
3436 (define_insn "*swap<mode>"
3437 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3438 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3439 (set (match_dup 1)
3440 (match_dup 0))]
3441 "TARGET_80387 || reload_completed"
3442 {
3443 if (STACK_TOP_P (operands[0]))
3444 return "fxch\t%1";
3445 else
3446 return "fxch\t%0";
3447 }
3448 [(set_attr "type" "fxch")
3449 (set_attr "mode" "<MODE>")])
3450 \f
3451 ;; Zero extension instructions
3452
3453 (define_expand "zero_extendsidi2"
3454 [(set (match_operand:DI 0 "nonimmediate_operand")
3455 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3456
3457 (define_insn "*zero_extendsidi2"
3458 [(set (match_operand:DI 0 "nonimmediate_operand"
3459 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3460 (zero_extend:DI
3461 (match_operand:SI 1 "x86_64_zext_operand"
3462 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3463 ""
3464 {
3465 switch (get_attr_type (insn))
3466 {
3467 case TYPE_IMOVX:
3468 if (ix86_use_lea_for_mov (insn, operands))
3469 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3470 else
3471 return "mov{l}\t{%1, %k0|%k0, %1}";
3472
3473 case TYPE_MULTI:
3474 return "#";
3475
3476 case TYPE_MMXMOV:
3477 return "movd\t{%1, %0|%0, %1}";
3478
3479 case TYPE_SSELOG1:
3480 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3481
3482 case TYPE_SSEMOV:
3483 if (GENERAL_REG_P (operands[0]))
3484 return "%vmovd\t{%1, %k0|%k0, %1}";
3485
3486 return "%vmovd\t{%1, %0|%0, %1}";
3487
3488 default:
3489 gcc_unreachable ();
3490 }
3491 }
3492 [(set (attr "isa")
3493 (cond [(eq_attr "alternative" "0,1,2")
3494 (const_string "nox64")
3495 (eq_attr "alternative" "3,7")
3496 (const_string "x64")
3497 (eq_attr "alternative" "8")
3498 (const_string "x64_sse4")
3499 (eq_attr "alternative" "10")
3500 (const_string "sse2")
3501 ]
3502 (const_string "*")))
3503 (set (attr "type")
3504 (cond [(eq_attr "alternative" "0,1,2,4")
3505 (const_string "multi")
3506 (eq_attr "alternative" "5,6")
3507 (const_string "mmxmov")
3508 (eq_attr "alternative" "7,9,10")
3509 (const_string "ssemov")
3510 (eq_attr "alternative" "8")
3511 (const_string "sselog1")
3512 ]
3513 (const_string "imovx")))
3514 (set (attr "prefix_extra")
3515 (if_then_else (eq_attr "alternative" "8")
3516 (const_string "1")
3517 (const_string "*")))
3518 (set (attr "length_immediate")
3519 (if_then_else (eq_attr "alternative" "8")
3520 (const_string "1")
3521 (const_string "*")))
3522 (set (attr "prefix")
3523 (if_then_else (eq_attr "type" "ssemov,sselog1")
3524 (const_string "maybe_vex")
3525 (const_string "orig")))
3526 (set (attr "prefix_0f")
3527 (if_then_else (eq_attr "type" "imovx")
3528 (const_string "0")
3529 (const_string "*")))
3530 (set (attr "mode")
3531 (cond [(eq_attr "alternative" "5,6")
3532 (const_string "DI")
3533 (eq_attr "alternative" "7,8,9")
3534 (const_string "TI")
3535 ]
3536 (const_string "SI")))])
3537
3538 (define_split
3539 [(set (match_operand:DI 0 "memory_operand")
3540 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3541 "reload_completed"
3542 [(set (match_dup 4) (const_int 0))]
3543 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3544
3545 (define_split
3546 [(set (match_operand:DI 0 "register_operand")
3547 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3548 "!TARGET_64BIT && reload_completed
3549 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3550 && true_regnum (operands[0]) == true_regnum (operands[1])"
3551 [(set (match_dup 4) (const_int 0))]
3552 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3553
3554 (define_split
3555 [(set (match_operand:DI 0 "nonimmediate_operand")
3556 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3557 "!TARGET_64BIT && reload_completed
3558 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3559 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3560 [(set (match_dup 3) (match_dup 1))
3561 (set (match_dup 4) (const_int 0))]
3562 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3563
3564 (define_insn "zero_extend<mode>di2"
3565 [(set (match_operand:DI 0 "register_operand" "=r")
3566 (zero_extend:DI
3567 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3568 "TARGET_64BIT"
3569 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3570 [(set_attr "type" "imovx")
3571 (set_attr "mode" "SI")])
3572
3573 (define_expand "zero_extend<mode>si2"
3574 [(set (match_operand:SI 0 "register_operand")
3575 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3576 ""
3577 {
3578 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3579 {
3580 operands[1] = force_reg (<MODE>mode, operands[1]);
3581 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3582 DONE;
3583 }
3584 })
3585
3586 (define_insn_and_split "zero_extend<mode>si2_and"
3587 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3588 (zero_extend:SI
3589 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3590 (clobber (reg:CC FLAGS_REG))]
3591 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3592 "#"
3593 "&& reload_completed"
3594 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3595 (clobber (reg:CC FLAGS_REG))])]
3596 {
3597 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3598 {
3599 ix86_expand_clear (operands[0]);
3600
3601 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3602 emit_insn (gen_movstrict<mode>
3603 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3604 DONE;
3605 }
3606
3607 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3608 }
3609 [(set_attr "type" "alu1")
3610 (set_attr "mode" "SI")])
3611
3612 (define_insn "*zero_extend<mode>si2"
3613 [(set (match_operand:SI 0 "register_operand" "=r")
3614 (zero_extend:SI
3615 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3616 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3617 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3618 [(set_attr "type" "imovx")
3619 (set_attr "mode" "SI")])
3620
3621 (define_expand "zero_extendqihi2"
3622 [(set (match_operand:HI 0 "register_operand")
3623 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3624 ""
3625 {
3626 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3627 {
3628 operands[1] = force_reg (QImode, operands[1]);
3629 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3630 DONE;
3631 }
3632 })
3633
3634 (define_insn_and_split "zero_extendqihi2_and"
3635 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3636 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3637 (clobber (reg:CC FLAGS_REG))]
3638 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3639 "#"
3640 "&& reload_completed"
3641 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3642 (clobber (reg:CC FLAGS_REG))])]
3643 {
3644 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3645 {
3646 ix86_expand_clear (operands[0]);
3647
3648 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3649 emit_insn (gen_movstrictqi
3650 (gen_lowpart (QImode, operands[0]), operands[1]));
3651 DONE;
3652 }
3653
3654 operands[0] = gen_lowpart (SImode, operands[0]);
3655 }
3656 [(set_attr "type" "alu1")
3657 (set_attr "mode" "SI")])
3658
3659 ; zero extend to SImode to avoid partial register stalls
3660 (define_insn "*zero_extendqihi2"
3661 [(set (match_operand:HI 0 "register_operand" "=r")
3662 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3663 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3664 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3665 [(set_attr "type" "imovx")
3666 (set_attr "mode" "SI")])
3667 \f
3668 ;; Sign extension instructions
3669
3670 (define_expand "extendsidi2"
3671 [(set (match_operand:DI 0 "register_operand")
3672 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3673 ""
3674 {
3675 if (!TARGET_64BIT)
3676 {
3677 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3678 DONE;
3679 }
3680 })
3681
3682 (define_insn "*extendsidi2_rex64"
3683 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3684 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3685 "TARGET_64BIT"
3686 "@
3687 {cltq|cdqe}
3688 movs{lq|x}\t{%1, %0|%0, %1}"
3689 [(set_attr "type" "imovx")
3690 (set_attr "mode" "DI")
3691 (set_attr "prefix_0f" "0")
3692 (set_attr "modrm" "0,1")])
3693
3694 (define_insn "extendsidi2_1"
3695 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3696 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3697 (clobber (reg:CC FLAGS_REG))
3698 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3699 "!TARGET_64BIT"
3700 "#")
3701
3702 ;; Split the memory case. If the source register doesn't die, it will stay
3703 ;; this way, if it does die, following peephole2s take care of it.
3704 (define_split
3705 [(set (match_operand:DI 0 "memory_operand")
3706 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3707 (clobber (reg:CC FLAGS_REG))
3708 (clobber (match_operand:SI 2 "register_operand"))]
3709 "reload_completed"
3710 [(const_int 0)]
3711 {
3712 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3713
3714 emit_move_insn (operands[3], operands[1]);
3715
3716 /* Generate a cltd if possible and doing so it profitable. */
3717 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3718 && true_regnum (operands[1]) == AX_REG
3719 && true_regnum (operands[2]) == DX_REG)
3720 {
3721 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3722 }
3723 else
3724 {
3725 emit_move_insn (operands[2], operands[1]);
3726 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3727 }
3728 emit_move_insn (operands[4], operands[2]);
3729 DONE;
3730 })
3731
3732 ;; Peepholes for the case where the source register does die, after
3733 ;; being split with the above splitter.
3734 (define_peephole2
3735 [(set (match_operand:SI 0 "memory_operand")
3736 (match_operand:SI 1 "register_operand"))
3737 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3738 (parallel [(set (match_dup 2)
3739 (ashiftrt:SI (match_dup 2) (const_int 31)))
3740 (clobber (reg:CC FLAGS_REG))])
3741 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3742 "REGNO (operands[1]) != REGNO (operands[2])
3743 && peep2_reg_dead_p (2, operands[1])
3744 && peep2_reg_dead_p (4, operands[2])
3745 && !reg_mentioned_p (operands[2], operands[3])"
3746 [(set (match_dup 0) (match_dup 1))
3747 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3748 (clobber (reg:CC FLAGS_REG))])
3749 (set (match_dup 3) (match_dup 1))])
3750
3751 (define_peephole2
3752 [(set (match_operand:SI 0 "memory_operand")
3753 (match_operand:SI 1 "register_operand"))
3754 (parallel [(set (match_operand:SI 2 "register_operand")
3755 (ashiftrt:SI (match_dup 1) (const_int 31)))
3756 (clobber (reg:CC FLAGS_REG))])
3757 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3758 "/* cltd is shorter than sarl $31, %eax */
3759 !optimize_function_for_size_p (cfun)
3760 && true_regnum (operands[1]) == AX_REG
3761 && true_regnum (operands[2]) == DX_REG
3762 && peep2_reg_dead_p (2, operands[1])
3763 && peep2_reg_dead_p (3, operands[2])
3764 && !reg_mentioned_p (operands[2], operands[3])"
3765 [(set (match_dup 0) (match_dup 1))
3766 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3767 (clobber (reg:CC FLAGS_REG))])
3768 (set (match_dup 3) (match_dup 1))])
3769
3770 ;; Extend to register case. Optimize case where source and destination
3771 ;; registers match and cases where we can use cltd.
3772 (define_split
3773 [(set (match_operand:DI 0 "register_operand")
3774 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3775 (clobber (reg:CC FLAGS_REG))
3776 (clobber (match_scratch:SI 2))]
3777 "reload_completed"
3778 [(const_int 0)]
3779 {
3780 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3781
3782 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3783 emit_move_insn (operands[3], operands[1]);
3784
3785 /* Generate a cltd if possible and doing so it profitable. */
3786 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3787 && true_regnum (operands[3]) == AX_REG
3788 && true_regnum (operands[4]) == DX_REG)
3789 {
3790 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3791 DONE;
3792 }
3793
3794 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3795 emit_move_insn (operands[4], operands[1]);
3796
3797 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3798 DONE;
3799 })
3800
3801 (define_insn "extend<mode>di2"
3802 [(set (match_operand:DI 0 "register_operand" "=r")
3803 (sign_extend:DI
3804 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3805 "TARGET_64BIT"
3806 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3807 [(set_attr "type" "imovx")
3808 (set_attr "mode" "DI")])
3809
3810 (define_insn "extendhisi2"
3811 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3812 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3813 ""
3814 {
3815 switch (get_attr_prefix_0f (insn))
3816 {
3817 case 0:
3818 return "{cwtl|cwde}";
3819 default:
3820 return "movs{wl|x}\t{%1, %0|%0, %1}";
3821 }
3822 }
3823 [(set_attr "type" "imovx")
3824 (set_attr "mode" "SI")
3825 (set (attr "prefix_0f")
3826 ;; movsx is short decodable while cwtl is vector decoded.
3827 (if_then_else (and (eq_attr "cpu" "!k6")
3828 (eq_attr "alternative" "0"))
3829 (const_string "0")
3830 (const_string "1")))
3831 (set (attr "modrm")
3832 (if_then_else (eq_attr "prefix_0f" "0")
3833 (const_string "0")
3834 (const_string "1")))])
3835
3836 (define_insn "*extendhisi2_zext"
3837 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3838 (zero_extend:DI
3839 (sign_extend:SI
3840 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3841 "TARGET_64BIT"
3842 {
3843 switch (get_attr_prefix_0f (insn))
3844 {
3845 case 0:
3846 return "{cwtl|cwde}";
3847 default:
3848 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3849 }
3850 }
3851 [(set_attr "type" "imovx")
3852 (set_attr "mode" "SI")
3853 (set (attr "prefix_0f")
3854 ;; movsx is short decodable while cwtl is vector decoded.
3855 (if_then_else (and (eq_attr "cpu" "!k6")
3856 (eq_attr "alternative" "0"))
3857 (const_string "0")
3858 (const_string "1")))
3859 (set (attr "modrm")
3860 (if_then_else (eq_attr "prefix_0f" "0")
3861 (const_string "0")
3862 (const_string "1")))])
3863
3864 (define_insn "extendqisi2"
3865 [(set (match_operand:SI 0 "register_operand" "=r")
3866 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3867 ""
3868 "movs{bl|x}\t{%1, %0|%0, %1}"
3869 [(set_attr "type" "imovx")
3870 (set_attr "mode" "SI")])
3871
3872 (define_insn "*extendqisi2_zext"
3873 [(set (match_operand:DI 0 "register_operand" "=r")
3874 (zero_extend:DI
3875 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3876 "TARGET_64BIT"
3877 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3878 [(set_attr "type" "imovx")
3879 (set_attr "mode" "SI")])
3880
3881 (define_insn "extendqihi2"
3882 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3883 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3884 ""
3885 {
3886 switch (get_attr_prefix_0f (insn))
3887 {
3888 case 0:
3889 return "{cbtw|cbw}";
3890 default:
3891 return "movs{bw|x}\t{%1, %0|%0, %1}";
3892 }
3893 }
3894 [(set_attr "type" "imovx")
3895 (set_attr "mode" "HI")
3896 (set (attr "prefix_0f")
3897 ;; movsx is short decodable while cwtl is vector decoded.
3898 (if_then_else (and (eq_attr "cpu" "!k6")
3899 (eq_attr "alternative" "0"))
3900 (const_string "0")
3901 (const_string "1")))
3902 (set (attr "modrm")
3903 (if_then_else (eq_attr "prefix_0f" "0")
3904 (const_string "0")
3905 (const_string "1")))])
3906 \f
3907 ;; Conversions between float and double.
3908
3909 ;; These are all no-ops in the model used for the 80387.
3910 ;; So just emit moves.
3911
3912 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3913 (define_split
3914 [(set (match_operand:DF 0 "push_operand")
3915 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3916 "reload_completed"
3917 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3918 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3919
3920 (define_split
3921 [(set (match_operand:XF 0 "push_operand")
3922 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3923 "reload_completed"
3924 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3925 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3926 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3927
3928 (define_expand "extendsfdf2"
3929 [(set (match_operand:DF 0 "nonimmediate_operand")
3930 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3931 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3932 {
3933 /* ??? Needed for compress_float_constant since all fp constants
3934 are TARGET_LEGITIMATE_CONSTANT_P. */
3935 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3936 {
3937 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3938 && standard_80387_constant_p (operands[1]) > 0)
3939 {
3940 operands[1] = simplify_const_unary_operation
3941 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3942 emit_move_insn_1 (operands[0], operands[1]);
3943 DONE;
3944 }
3945 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3946 }
3947 })
3948
3949 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3950 cvtss2sd:
3951 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3952 cvtps2pd xmm2,xmm1
3953 We do the conversion post reload to avoid producing of 128bit spills
3954 that might lead to ICE on 32bit target. The sequence unlikely combine
3955 anyway. */
3956 (define_split
3957 [(set (match_operand:DF 0 "register_operand")
3958 (float_extend:DF
3959 (match_operand:SF 1 "nonimmediate_operand")))]
3960 "TARGET_USE_VECTOR_FP_CONVERTS
3961 && optimize_insn_for_speed_p ()
3962 && reload_completed && SSE_REG_P (operands[0])"
3963 [(set (match_dup 2)
3964 (float_extend:V2DF
3965 (vec_select:V2SF
3966 (match_dup 3)
3967 (parallel [(const_int 0) (const_int 1)]))))]
3968 {
3969 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3970 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3971 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3972 Try to avoid move when unpacking can be done in source. */
3973 if (REG_P (operands[1]))
3974 {
3975 /* If it is unsafe to overwrite upper half of source, we need
3976 to move to destination and unpack there. */
3977 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3978 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3979 && true_regnum (operands[0]) != true_regnum (operands[1]))
3980 {
3981 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3982 emit_move_insn (tmp, operands[1]);
3983 }
3984 else
3985 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3986 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3987 operands[3]));
3988 }
3989 else
3990 emit_insn (gen_vec_setv4sf_0 (operands[3],
3991 CONST0_RTX (V4SFmode), operands[1]));
3992 })
3993
3994 ;; It's more profitable to split and then extend in the same register.
3995 (define_peephole2
3996 [(set (match_operand:DF 0 "register_operand")
3997 (float_extend:DF
3998 (match_operand:SF 1 "memory_operand")))]
3999 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4000 && optimize_insn_for_speed_p ()
4001 && SSE_REG_P (operands[0])"
4002 [(set (match_dup 2) (match_dup 1))
4003 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4004 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4005
4006 (define_insn "*extendsfdf2_mixed"
4007 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4008 (float_extend:DF
4009 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4010 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4011 {
4012 switch (which_alternative)
4013 {
4014 case 0:
4015 case 1:
4016 return output_387_reg_move (insn, operands);
4017
4018 case 2:
4019 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4020
4021 default:
4022 gcc_unreachable ();
4023 }
4024 }
4025 [(set_attr "type" "fmov,fmov,ssecvt")
4026 (set_attr "prefix" "orig,orig,maybe_vex")
4027 (set_attr "mode" "SF,XF,DF")])
4028
4029 (define_insn "*extendsfdf2_sse"
4030 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4031 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4032 "TARGET_SSE2 && TARGET_SSE_MATH"
4033 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4034 [(set_attr "type" "ssecvt")
4035 (set_attr "prefix" "maybe_vex")
4036 (set_attr "mode" "DF")])
4037
4038 (define_insn "*extendsfdf2_i387"
4039 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4040 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4041 "TARGET_80387"
4042 "* return output_387_reg_move (insn, operands);"
4043 [(set_attr "type" "fmov")
4044 (set_attr "mode" "SF,XF")])
4045
4046 (define_expand "extend<mode>xf2"
4047 [(set (match_operand:XF 0 "nonimmediate_operand")
4048 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4049 "TARGET_80387"
4050 {
4051 /* ??? Needed for compress_float_constant since all fp constants
4052 are TARGET_LEGITIMATE_CONSTANT_P. */
4053 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4054 {
4055 if (standard_80387_constant_p (operands[1]) > 0)
4056 {
4057 operands[1] = simplify_const_unary_operation
4058 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4059 emit_move_insn_1 (operands[0], operands[1]);
4060 DONE;
4061 }
4062 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4063 }
4064 })
4065
4066 (define_insn "*extend<mode>xf2_i387"
4067 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4068 (float_extend:XF
4069 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4070 "TARGET_80387"
4071 "* return output_387_reg_move (insn, operands);"
4072 [(set_attr "type" "fmov")
4073 (set_attr "mode" "<MODE>,XF")])
4074
4075 ;; %%% This seems bad bad news.
4076 ;; This cannot output into an f-reg because there is no way to be sure
4077 ;; of truncating in that case. Otherwise this is just like a simple move
4078 ;; insn. So we pretend we can output to a reg in order to get better
4079 ;; register preferencing, but we really use a stack slot.
4080
4081 ;; Conversion from DFmode to SFmode.
4082
4083 (define_expand "truncdfsf2"
4084 [(set (match_operand:SF 0 "nonimmediate_operand")
4085 (float_truncate:SF
4086 (match_operand:DF 1 "nonimmediate_operand")))]
4087 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4088 {
4089 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4090 ;
4091 else if (flag_unsafe_math_optimizations)
4092 ;
4093 else
4094 {
4095 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4096 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4097 DONE;
4098 }
4099 })
4100
4101 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4102 cvtsd2ss:
4103 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4104 cvtpd2ps xmm2,xmm1
4105 We do the conversion post reload to avoid producing of 128bit spills
4106 that might lead to ICE on 32bit target. The sequence unlikely combine
4107 anyway. */
4108 (define_split
4109 [(set (match_operand:SF 0 "register_operand")
4110 (float_truncate:SF
4111 (match_operand:DF 1 "nonimmediate_operand")))]
4112 "TARGET_USE_VECTOR_FP_CONVERTS
4113 && optimize_insn_for_speed_p ()
4114 && reload_completed && SSE_REG_P (operands[0])"
4115 [(set (match_dup 2)
4116 (vec_concat:V4SF
4117 (float_truncate:V2SF
4118 (match_dup 4))
4119 (match_dup 3)))]
4120 {
4121 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4122 operands[3] = CONST0_RTX (V2SFmode);
4123 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4124 /* Use movsd for loading from memory, unpcklpd for registers.
4125 Try to avoid move when unpacking can be done in source, or SSE3
4126 movddup is available. */
4127 if (REG_P (operands[1]))
4128 {
4129 if (!TARGET_SSE3
4130 && true_regnum (operands[0]) != true_regnum (operands[1])
4131 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4132 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4133 {
4134 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4135 emit_move_insn (tmp, operands[1]);
4136 operands[1] = tmp;
4137 }
4138 else if (!TARGET_SSE3)
4139 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4140 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4141 }
4142 else
4143 emit_insn (gen_sse2_loadlpd (operands[4],
4144 CONST0_RTX (V2DFmode), operands[1]));
4145 })
4146
4147 ;; It's more profitable to split and then extend in the same register.
4148 (define_peephole2
4149 [(set (match_operand:SF 0 "register_operand")
4150 (float_truncate:SF
4151 (match_operand:DF 1 "memory_operand")))]
4152 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4153 && optimize_insn_for_speed_p ()
4154 && SSE_REG_P (operands[0])"
4155 [(set (match_dup 2) (match_dup 1))
4156 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4157 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4158
4159 (define_expand "truncdfsf2_with_temp"
4160 [(parallel [(set (match_operand:SF 0)
4161 (float_truncate:SF (match_operand:DF 1)))
4162 (clobber (match_operand:SF 2))])])
4163
4164 (define_insn "*truncdfsf_fast_mixed"
4165 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4166 (float_truncate:SF
4167 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4168 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4169 {
4170 switch (which_alternative)
4171 {
4172 case 0:
4173 return output_387_reg_move (insn, operands);
4174 case 1:
4175 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4176 default:
4177 gcc_unreachable ();
4178 }
4179 }
4180 [(set_attr "type" "fmov,ssecvt")
4181 (set_attr "prefix" "orig,maybe_vex")
4182 (set_attr "mode" "SF")])
4183
4184 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4185 ;; because nothing we do here is unsafe.
4186 (define_insn "*truncdfsf_fast_sse"
4187 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4188 (float_truncate:SF
4189 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4190 "TARGET_SSE2 && TARGET_SSE_MATH"
4191 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4192 [(set_attr "type" "ssecvt")
4193 (set_attr "prefix" "maybe_vex")
4194 (set_attr "mode" "SF")])
4195
4196 (define_insn "*truncdfsf_fast_i387"
4197 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4198 (float_truncate:SF
4199 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4200 "TARGET_80387 && flag_unsafe_math_optimizations"
4201 "* return output_387_reg_move (insn, operands);"
4202 [(set_attr "type" "fmov")
4203 (set_attr "mode" "SF")])
4204
4205 (define_insn "*truncdfsf_mixed"
4206 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4207 (float_truncate:SF
4208 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4209 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4210 "TARGET_MIX_SSE_I387"
4211 {
4212 switch (which_alternative)
4213 {
4214 case 0:
4215 return output_387_reg_move (insn, operands);
4216 case 1:
4217 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4218
4219 default:
4220 return "#";
4221 }
4222 }
4223 [(set_attr "isa" "*,sse2,*,*,*")
4224 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4225 (set_attr "unit" "*,*,i387,i387,i387")
4226 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4227 (set_attr "mode" "SF")])
4228
4229 (define_insn "*truncdfsf_i387"
4230 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4231 (float_truncate:SF
4232 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4233 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4234 "TARGET_80387"
4235 {
4236 switch (which_alternative)
4237 {
4238 case 0:
4239 return output_387_reg_move (insn, operands);
4240
4241 default:
4242 return "#";
4243 }
4244 }
4245 [(set_attr "type" "fmov,multi,multi,multi")
4246 (set_attr "unit" "*,i387,i387,i387")
4247 (set_attr "mode" "SF")])
4248
4249 (define_insn "*truncdfsf2_i387_1"
4250 [(set (match_operand:SF 0 "memory_operand" "=m")
4251 (float_truncate:SF
4252 (match_operand:DF 1 "register_operand" "f")))]
4253 "TARGET_80387
4254 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4255 && !TARGET_MIX_SSE_I387"
4256 "* return output_387_reg_move (insn, operands);"
4257 [(set_attr "type" "fmov")
4258 (set_attr "mode" "SF")])
4259
4260 (define_split
4261 [(set (match_operand:SF 0 "register_operand")
4262 (float_truncate:SF
4263 (match_operand:DF 1 "fp_register_operand")))
4264 (clobber (match_operand 2))]
4265 "reload_completed"
4266 [(set (match_dup 2) (match_dup 1))
4267 (set (match_dup 0) (match_dup 2))]
4268 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4269
4270 ;; Conversion from XFmode to {SF,DF}mode
4271
4272 (define_expand "truncxf<mode>2"
4273 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4274 (float_truncate:MODEF
4275 (match_operand:XF 1 "register_operand")))
4276 (clobber (match_dup 2))])]
4277 "TARGET_80387"
4278 {
4279 if (flag_unsafe_math_optimizations)
4280 {
4281 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4282 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4283 if (reg != operands[0])
4284 emit_move_insn (operands[0], reg);
4285 DONE;
4286 }
4287 else
4288 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4289 })
4290
4291 (define_insn "*truncxfsf2_mixed"
4292 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4293 (float_truncate:SF
4294 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4295 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4296 "TARGET_80387"
4297 {
4298 gcc_assert (!which_alternative);
4299 return output_387_reg_move (insn, operands);
4300 }
4301 [(set_attr "type" "fmov,multi,multi,multi")
4302 (set_attr "unit" "*,i387,i387,i387")
4303 (set_attr "mode" "SF")])
4304
4305 (define_insn "*truncxfdf2_mixed"
4306 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4307 (float_truncate:DF
4308 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4309 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4310 "TARGET_80387"
4311 {
4312 gcc_assert (!which_alternative);
4313 return output_387_reg_move (insn, operands);
4314 }
4315 [(set_attr "isa" "*,*,sse2,*")
4316 (set_attr "type" "fmov,multi,multi,multi")
4317 (set_attr "unit" "*,i387,i387,i387")
4318 (set_attr "mode" "DF")])
4319
4320 (define_insn "truncxf<mode>2_i387_noop"
4321 [(set (match_operand:MODEF 0 "register_operand" "=f")
4322 (float_truncate:MODEF
4323 (match_operand:XF 1 "register_operand" "f")))]
4324 "TARGET_80387 && flag_unsafe_math_optimizations"
4325 "* return output_387_reg_move (insn, operands);"
4326 [(set_attr "type" "fmov")
4327 (set_attr "mode" "<MODE>")])
4328
4329 (define_insn "*truncxf<mode>2_i387"
4330 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4331 (float_truncate:MODEF
4332 (match_operand:XF 1 "register_operand" "f")))]
4333 "TARGET_80387"
4334 "* return output_387_reg_move (insn, operands);"
4335 [(set_attr "type" "fmov")
4336 (set_attr "mode" "<MODE>")])
4337
4338 (define_split
4339 [(set (match_operand:MODEF 0 "register_operand")
4340 (float_truncate:MODEF
4341 (match_operand:XF 1 "register_operand")))
4342 (clobber (match_operand:MODEF 2 "memory_operand"))]
4343 "TARGET_80387 && reload_completed"
4344 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4345 (set (match_dup 0) (match_dup 2))])
4346
4347 (define_split
4348 [(set (match_operand:MODEF 0 "memory_operand")
4349 (float_truncate:MODEF
4350 (match_operand:XF 1 "register_operand")))
4351 (clobber (match_operand:MODEF 2 "memory_operand"))]
4352 "TARGET_80387"
4353 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4354 \f
4355 ;; Signed conversion to DImode.
4356
4357 (define_expand "fix_truncxfdi2"
4358 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4359 (fix:DI (match_operand:XF 1 "register_operand")))
4360 (clobber (reg:CC FLAGS_REG))])]
4361 "TARGET_80387"
4362 {
4363 if (TARGET_FISTTP)
4364 {
4365 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4366 DONE;
4367 }
4368 })
4369
4370 (define_expand "fix_trunc<mode>di2"
4371 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4372 (fix:DI (match_operand:MODEF 1 "register_operand")))
4373 (clobber (reg:CC FLAGS_REG))])]
4374 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4375 {
4376 if (TARGET_FISTTP
4377 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4378 {
4379 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4380 DONE;
4381 }
4382 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4383 {
4384 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4385 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4386 if (out != operands[0])
4387 emit_move_insn (operands[0], out);
4388 DONE;
4389 }
4390 })
4391
4392 ;; Signed conversion to SImode.
4393
4394 (define_expand "fix_truncxfsi2"
4395 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4396 (fix:SI (match_operand:XF 1 "register_operand")))
4397 (clobber (reg:CC FLAGS_REG))])]
4398 "TARGET_80387"
4399 {
4400 if (TARGET_FISTTP)
4401 {
4402 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4403 DONE;
4404 }
4405 })
4406
4407 (define_expand "fix_trunc<mode>si2"
4408 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4409 (fix:SI (match_operand:MODEF 1 "register_operand")))
4410 (clobber (reg:CC FLAGS_REG))])]
4411 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4412 {
4413 if (TARGET_FISTTP
4414 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4415 {
4416 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4417 DONE;
4418 }
4419 if (SSE_FLOAT_MODE_P (<MODE>mode))
4420 {
4421 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4422 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4423 if (out != operands[0])
4424 emit_move_insn (operands[0], out);
4425 DONE;
4426 }
4427 })
4428
4429 ;; Signed conversion to HImode.
4430
4431 (define_expand "fix_trunc<mode>hi2"
4432 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4433 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4434 (clobber (reg:CC FLAGS_REG))])]
4435 "TARGET_80387
4436 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4437 {
4438 if (TARGET_FISTTP)
4439 {
4440 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4441 DONE;
4442 }
4443 })
4444
4445 ;; Unsigned conversion to SImode.
4446
4447 (define_expand "fixuns_trunc<mode>si2"
4448 [(parallel
4449 [(set (match_operand:SI 0 "register_operand")
4450 (unsigned_fix:SI
4451 (match_operand:MODEF 1 "nonimmediate_operand")))
4452 (use (match_dup 2))
4453 (clobber (match_scratch:<ssevecmode> 3))
4454 (clobber (match_scratch:<ssevecmode> 4))])]
4455 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4456 {
4457 machine_mode mode = <MODE>mode;
4458 machine_mode vecmode = <ssevecmode>mode;
4459 REAL_VALUE_TYPE TWO31r;
4460 rtx two31;
4461
4462 if (optimize_insn_for_size_p ())
4463 FAIL;
4464
4465 real_ldexp (&TWO31r, &dconst1, 31);
4466 two31 = const_double_from_real_value (TWO31r, mode);
4467 two31 = ix86_build_const_vector (vecmode, true, two31);
4468 operands[2] = force_reg (vecmode, two31);
4469 })
4470
4471 (define_insn_and_split "*fixuns_trunc<mode>_1"
4472 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4473 (unsigned_fix:SI
4474 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4475 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4476 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4477 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4478 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4479 && optimize_function_for_speed_p (cfun)"
4480 "#"
4481 "&& reload_completed"
4482 [(const_int 0)]
4483 {
4484 ix86_split_convert_uns_si_sse (operands);
4485 DONE;
4486 })
4487
4488 ;; Unsigned conversion to HImode.
4489 ;; Without these patterns, we'll try the unsigned SI conversion which
4490 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4491
4492 (define_expand "fixuns_trunc<mode>hi2"
4493 [(set (match_dup 2)
4494 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4495 (set (match_operand:HI 0 "nonimmediate_operand")
4496 (subreg:HI (match_dup 2) 0))]
4497 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4498 "operands[2] = gen_reg_rtx (SImode);")
4499
4500 ;; When SSE is available, it is always faster to use it!
4501 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4502 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4503 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4504 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4505 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4506 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4507 [(set_attr "type" "sseicvt")
4508 (set_attr "prefix" "maybe_vex")
4509 (set (attr "prefix_rex")
4510 (if_then_else
4511 (match_test "<SWI48:MODE>mode == DImode")
4512 (const_string "1")
4513 (const_string "*")))
4514 (set_attr "mode" "<MODEF:MODE>")
4515 (set_attr "athlon_decode" "double,vector")
4516 (set_attr "amdfam10_decode" "double,double")
4517 (set_attr "bdver1_decode" "double,double")])
4518
4519 ;; Avoid vector decoded forms of the instruction.
4520 (define_peephole2
4521 [(match_scratch:MODEF 2 "x")
4522 (set (match_operand:SWI48 0 "register_operand")
4523 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4524 "TARGET_AVOID_VECTOR_DECODE
4525 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4526 && optimize_insn_for_speed_p ()"
4527 [(set (match_dup 2) (match_dup 1))
4528 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4529
4530 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4531 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4532 (fix:SWI248x (match_operand 1 "register_operand")))]
4533 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4534 && TARGET_FISTTP
4535 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4536 && (TARGET_64BIT || <MODE>mode != DImode))
4537 && TARGET_SSE_MATH)
4538 && can_create_pseudo_p ()"
4539 "#"
4540 "&& 1"
4541 [(const_int 0)]
4542 {
4543 if (memory_operand (operands[0], VOIDmode))
4544 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4545 else
4546 {
4547 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4548 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4549 operands[1],
4550 operands[2]));
4551 }
4552 DONE;
4553 }
4554 [(set_attr "type" "fisttp")
4555 (set_attr "mode" "<MODE>")])
4556
4557 (define_insn "fix_trunc<mode>_i387_fisttp"
4558 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4559 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4560 (clobber (match_scratch:XF 2 "=&1f"))]
4561 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4562 && TARGET_FISTTP
4563 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && (TARGET_64BIT || <MODE>mode != DImode))
4565 && TARGET_SSE_MATH)"
4566 "* return output_fix_trunc (insn, operands, true);"
4567 [(set_attr "type" "fisttp")
4568 (set_attr "mode" "<MODE>")])
4569
4570 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4571 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4572 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4573 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4574 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4575 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4576 && TARGET_FISTTP
4577 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4578 && (TARGET_64BIT || <MODE>mode != DImode))
4579 && TARGET_SSE_MATH)"
4580 "#"
4581 [(set_attr "type" "fisttp")
4582 (set_attr "mode" "<MODE>")])
4583
4584 (define_split
4585 [(set (match_operand:SWI248x 0 "register_operand")
4586 (fix:SWI248x (match_operand 1 "register_operand")))
4587 (clobber (match_operand:SWI248x 2 "memory_operand"))
4588 (clobber (match_scratch 3))]
4589 "reload_completed"
4590 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4591 (clobber (match_dup 3))])
4592 (set (match_dup 0) (match_dup 2))])
4593
4594 (define_split
4595 [(set (match_operand:SWI248x 0 "memory_operand")
4596 (fix:SWI248x (match_operand 1 "register_operand")))
4597 (clobber (match_operand:SWI248x 2 "memory_operand"))
4598 (clobber (match_scratch 3))]
4599 "reload_completed"
4600 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4601 (clobber (match_dup 3))])])
4602
4603 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4604 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4605 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4606 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4607 ;; function in i386.c.
4608 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4609 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4610 (fix:SWI248x (match_operand 1 "register_operand")))
4611 (clobber (reg:CC FLAGS_REG))]
4612 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4613 && !TARGET_FISTTP
4614 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4615 && (TARGET_64BIT || <MODE>mode != DImode))
4616 && can_create_pseudo_p ()"
4617 "#"
4618 "&& 1"
4619 [(const_int 0)]
4620 {
4621 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4622
4623 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4624 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4625 if (memory_operand (operands[0], VOIDmode))
4626 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4627 operands[2], operands[3]));
4628 else
4629 {
4630 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4631 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4632 operands[2], operands[3],
4633 operands[4]));
4634 }
4635 DONE;
4636 }
4637 [(set_attr "type" "fistp")
4638 (set_attr "i387_cw" "trunc")
4639 (set_attr "mode" "<MODE>")])
4640
4641 (define_insn "fix_truncdi_i387"
4642 [(set (match_operand:DI 0 "memory_operand" "=m")
4643 (fix:DI (match_operand 1 "register_operand" "f")))
4644 (use (match_operand:HI 2 "memory_operand" "m"))
4645 (use (match_operand:HI 3 "memory_operand" "m"))
4646 (clobber (match_scratch:XF 4 "=&1f"))]
4647 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4648 && !TARGET_FISTTP
4649 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4650 "* return output_fix_trunc (insn, operands, false);"
4651 [(set_attr "type" "fistp")
4652 (set_attr "i387_cw" "trunc")
4653 (set_attr "mode" "DI")])
4654
4655 (define_insn "fix_truncdi_i387_with_temp"
4656 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4657 (fix:DI (match_operand 1 "register_operand" "f,f")))
4658 (use (match_operand:HI 2 "memory_operand" "m,m"))
4659 (use (match_operand:HI 3 "memory_operand" "m,m"))
4660 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4661 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4662 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4663 && !TARGET_FISTTP
4664 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4665 "#"
4666 [(set_attr "type" "fistp")
4667 (set_attr "i387_cw" "trunc")
4668 (set_attr "mode" "DI")])
4669
4670 (define_split
4671 [(set (match_operand:DI 0 "register_operand")
4672 (fix:DI (match_operand 1 "register_operand")))
4673 (use (match_operand:HI 2 "memory_operand"))
4674 (use (match_operand:HI 3 "memory_operand"))
4675 (clobber (match_operand:DI 4 "memory_operand"))
4676 (clobber (match_scratch 5))]
4677 "reload_completed"
4678 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4679 (use (match_dup 2))
4680 (use (match_dup 3))
4681 (clobber (match_dup 5))])
4682 (set (match_dup 0) (match_dup 4))])
4683
4684 (define_split
4685 [(set (match_operand:DI 0 "memory_operand")
4686 (fix:DI (match_operand 1 "register_operand")))
4687 (use (match_operand:HI 2 "memory_operand"))
4688 (use (match_operand:HI 3 "memory_operand"))
4689 (clobber (match_operand:DI 4 "memory_operand"))
4690 (clobber (match_scratch 5))]
4691 "reload_completed"
4692 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4693 (use (match_dup 2))
4694 (use (match_dup 3))
4695 (clobber (match_dup 5))])])
4696
4697 (define_insn "fix_trunc<mode>_i387"
4698 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4699 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4700 (use (match_operand:HI 2 "memory_operand" "m"))
4701 (use (match_operand:HI 3 "memory_operand" "m"))]
4702 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4703 && !TARGET_FISTTP
4704 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4705 "* return output_fix_trunc (insn, operands, false);"
4706 [(set_attr "type" "fistp")
4707 (set_attr "i387_cw" "trunc")
4708 (set_attr "mode" "<MODE>")])
4709
4710 (define_insn "fix_trunc<mode>_i387_with_temp"
4711 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4712 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4713 (use (match_operand:HI 2 "memory_operand" "m,m"))
4714 (use (match_operand:HI 3 "memory_operand" "m,m"))
4715 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4716 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4717 && !TARGET_FISTTP
4718 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4719 "#"
4720 [(set_attr "type" "fistp")
4721 (set_attr "i387_cw" "trunc")
4722 (set_attr "mode" "<MODE>")])
4723
4724 (define_split
4725 [(set (match_operand:SWI24 0 "register_operand")
4726 (fix:SWI24 (match_operand 1 "register_operand")))
4727 (use (match_operand:HI 2 "memory_operand"))
4728 (use (match_operand:HI 3 "memory_operand"))
4729 (clobber (match_operand:SWI24 4 "memory_operand"))]
4730 "reload_completed"
4731 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4732 (use (match_dup 2))
4733 (use (match_dup 3))])
4734 (set (match_dup 0) (match_dup 4))])
4735
4736 (define_split
4737 [(set (match_operand:SWI24 0 "memory_operand")
4738 (fix:SWI24 (match_operand 1 "register_operand")))
4739 (use (match_operand:HI 2 "memory_operand"))
4740 (use (match_operand:HI 3 "memory_operand"))
4741 (clobber (match_operand:SWI24 4 "memory_operand"))]
4742 "reload_completed"
4743 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4744 (use (match_dup 2))
4745 (use (match_dup 3))])])
4746
4747 (define_insn "x86_fnstcw_1"
4748 [(set (match_operand:HI 0 "memory_operand" "=m")
4749 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4750 "TARGET_80387"
4751 "fnstcw\t%0"
4752 [(set (attr "length")
4753 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4754 (set_attr "mode" "HI")
4755 (set_attr "unit" "i387")
4756 (set_attr "bdver1_decode" "vector")])
4757
4758 (define_insn "x86_fldcw_1"
4759 [(set (reg:HI FPCR_REG)
4760 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4761 "TARGET_80387"
4762 "fldcw\t%0"
4763 [(set (attr "length")
4764 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4765 (set_attr "mode" "HI")
4766 (set_attr "unit" "i387")
4767 (set_attr "athlon_decode" "vector")
4768 (set_attr "amdfam10_decode" "vector")
4769 (set_attr "bdver1_decode" "vector")])
4770 \f
4771 ;; Conversion between fixed point and floating point.
4772
4773 ;; Even though we only accept memory inputs, the backend _really_
4774 ;; wants to be able to do this between registers. Thankfully, LRA
4775 ;; will fix this up for us during register allocation.
4776
4777 (define_insn "floathi<mode>2"
4778 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4779 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4780 "TARGET_80387
4781 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4782 || TARGET_MIX_SSE_I387)"
4783 "fild%Z1\t%1"
4784 [(set_attr "type" "fmov")
4785 (set_attr "mode" "<MODE>")
4786 (set_attr "fp_int_src" "true")])
4787
4788 (define_insn "float<SWI48x:mode>xf2"
4789 [(set (match_operand:XF 0 "register_operand" "=f")
4790 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4791 "TARGET_80387"
4792 "fild%Z1\t%1"
4793 [(set_attr "type" "fmov")
4794 (set_attr "mode" "XF")
4795 (set_attr "fp_int_src" "true")])
4796
4797 (define_expand "float<SWI48:mode><MODEF:mode>2"
4798 [(set (match_operand:MODEF 0 "register_operand")
4799 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4800 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4801 {
4802 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4803 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4804 {
4805 rtx reg = gen_reg_rtx (XFmode);
4806 rtx (*insn)(rtx, rtx);
4807
4808 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4809
4810 if (<MODEF:MODE>mode == SFmode)
4811 insn = gen_truncxfsf2;
4812 else if (<MODEF:MODE>mode == DFmode)
4813 insn = gen_truncxfdf2;
4814 else
4815 gcc_unreachable ();
4816
4817 emit_insn (insn (operands[0], reg));
4818 DONE;
4819 }
4820 })
4821
4822 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4823 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4824 (float:MODEF
4825 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4826 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4827 "@
4828 fild%Z1\t%1
4829 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4830 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4831 [(set_attr "type" "fmov,sseicvt,sseicvt")
4832 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4833 (set_attr "mode" "<MODEF:MODE>")
4834 (set (attr "prefix_rex")
4835 (if_then_else
4836 (and (eq_attr "prefix" "maybe_vex")
4837 (match_test "<SWI48:MODE>mode == DImode"))
4838 (const_string "1")
4839 (const_string "*")))
4840 (set_attr "unit" "i387,*,*")
4841 (set_attr "athlon_decode" "*,double,direct")
4842 (set_attr "amdfam10_decode" "*,vector,double")
4843 (set_attr "bdver1_decode" "*,double,direct")
4844 (set_attr "fp_int_src" "true")
4845 (set (attr "enabled")
4846 (cond [(eq_attr "alternative" "0")
4847 (symbol_ref "TARGET_MIX_SSE_I387
4848 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4849 <SWI48:MODE>mode)")
4850 ]
4851 (symbol_ref "true")))
4852 (set (attr "preferred_for_speed")
4853 (cond [(eq_attr "alternative" "1")
4854 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4855 (symbol_ref "true")))
4856 ])
4857
4858 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4859 [(set (match_operand:MODEF 0 "register_operand" "=f")
4860 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4861 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4862 "fild%Z1\t%1"
4863 [(set_attr "type" "fmov")
4864 (set_attr "mode" "<MODEF:MODE>")
4865 (set_attr "fp_int_src" "true")])
4866
4867 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4868 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4869 ;; alternative in sse2_loadld.
4870 (define_split
4871 [(set (match_operand:MODEF 0 "register_operand")
4872 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4873 "TARGET_SSE2 && TARGET_SSE_MATH
4874 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4875 && reload_completed && SSE_REG_P (operands[0])
4876 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4877 [(const_int 0)]
4878 {
4879 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4880 <MODE>mode, 0);
4881 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4882
4883 emit_insn (gen_sse2_loadld (operands[4],
4884 CONST0_RTX (V4SImode), operands[1]));
4885
4886 if (<ssevecmode>mode == V4SFmode)
4887 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4888 else
4889 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4890 DONE;
4891 })
4892
4893 ;; Avoid partial SSE register dependency stalls
4894 (define_split
4895 [(set (match_operand:MODEF 0 "register_operand")
4896 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4897 "TARGET_SSE2 && TARGET_SSE_MATH
4898 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4899 && optimize_function_for_speed_p (cfun)
4900 && reload_completed && SSE_REG_P (operands[0])"
4901 [(const_int 0)]
4902 {
4903 const machine_mode vmode = <MODEF:ssevecmode>mode;
4904 const machine_mode mode = <MODEF:MODE>mode;
4905 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4906
4907 emit_move_insn (op0, CONST0_RTX (vmode));
4908
4909 t = gen_rtx_FLOAT (mode, operands[1]);
4910 t = gen_rtx_VEC_DUPLICATE (vmode, t);
4911 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4912 emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4913 DONE;
4914 })
4915
4916 ;; Break partial reg stall for cvtsd2ss.
4917
4918 (define_peephole2
4919 [(set (match_operand:SF 0 "register_operand")
4920 (float_truncate:SF
4921 (match_operand:DF 1 "nonimmediate_operand")))]
4922 "TARGET_SSE2 && TARGET_SSE_MATH
4923 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4924 && optimize_function_for_speed_p (cfun)
4925 && SSE_REG_P (operands[0])
4926 && (!SSE_REG_P (operands[1])
4927 || REGNO (operands[0]) != REGNO (operands[1]))"
4928 [(set (match_dup 0)
4929 (vec_merge:V4SF
4930 (vec_duplicate:V4SF
4931 (float_truncate:V2SF
4932 (match_dup 1)))
4933 (match_dup 0)
4934 (const_int 1)))]
4935 {
4936 operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4937 SFmode, 0);
4938 operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4939 DFmode, 0);
4940 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4941 })
4942
4943 ;; Break partial reg stall for cvtss2sd.
4944
4945 (define_peephole2
4946 [(set (match_operand:DF 0 "register_operand")
4947 (float_extend:DF
4948 (match_operand:SF 1 "nonimmediate_operand")))]
4949 "TARGET_SSE2 && TARGET_SSE_MATH
4950 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4951 && optimize_function_for_speed_p (cfun)
4952 && SSE_REG_P (operands[0])
4953 && (!SSE_REG_P (operands[1])
4954 || REGNO (operands[0]) != REGNO (operands[1]))"
4955 [(set (match_dup 0)
4956 (vec_merge:V2DF
4957 (float_extend:V2DF
4958 (vec_select:V2SF
4959 (match_dup 1)
4960 (parallel [(const_int 0) (const_int 1)])))
4961 (match_dup 0)
4962 (const_int 1)))]
4963 {
4964 operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4965 DFmode, 0);
4966 operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4967 SFmode, 0);
4968 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4969 })
4970
4971 ;; Avoid store forwarding (partial memory) stall penalty
4972 ;; by passing DImode value through XMM registers. */
4973
4974 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4975 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4976 (float:X87MODEF
4977 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4978 (clobber (match_scratch:V4SI 3 "=X,x"))
4979 (clobber (match_scratch:V4SI 4 "=X,x"))
4980 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4981 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4982 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4983 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4984 "#"
4985 [(set_attr "type" "multi")
4986 (set_attr "mode" "<X87MODEF:MODE>")
4987 (set_attr "unit" "i387")
4988 (set_attr "fp_int_src" "true")])
4989
4990 (define_split
4991 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4992 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4993 (clobber (match_scratch:V4SI 3))
4994 (clobber (match_scratch:V4SI 4))
4995 (clobber (match_operand:DI 2 "memory_operand"))]
4996 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4997 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4998 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4999 && reload_completed"
5000 [(set (match_dup 2) (match_dup 3))
5001 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5002 {
5003 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5004 Assemble the 64-bit DImode value in an xmm register. */
5005 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5006 gen_rtx_SUBREG (SImode, operands[1], 0)));
5007 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5008 gen_rtx_SUBREG (SImode, operands[1], 4)));
5009 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5010 operands[4]));
5011
5012 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5013 })
5014
5015 (define_split
5016 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5017 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5018 (clobber (match_scratch:V4SI 3))
5019 (clobber (match_scratch:V4SI 4))
5020 (clobber (match_operand:DI 2 "memory_operand"))]
5021 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5022 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5023 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5024 && reload_completed"
5025 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5026
5027 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5028 [(set (match_operand:MODEF 0 "register_operand")
5029 (unsigned_float:MODEF
5030 (match_operand:SWI12 1 "nonimmediate_operand")))]
5031 "!TARGET_64BIT
5032 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5033 {
5034 operands[1] = convert_to_mode (SImode, operands[1], 1);
5035 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5036 DONE;
5037 })
5038
5039 ;; Avoid store forwarding (partial memory) stall penalty by extending
5040 ;; SImode value to DImode through XMM register instead of pushing two
5041 ;; SImode values to stack. Also note that fild loads from memory only.
5042
5043 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5044 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5045 (unsigned_float:X87MODEF
5046 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5047 (clobber (match_scratch:DI 3 "=x"))
5048 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5049 "!TARGET_64BIT
5050 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5051 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5052 "#"
5053 "&& reload_completed"
5054 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5055 (set (match_dup 2) (match_dup 3))
5056 (set (match_dup 0)
5057 (float:X87MODEF (match_dup 2)))]
5058 ""
5059 [(set_attr "type" "multi")
5060 (set_attr "mode" "<MODE>")])
5061
5062 (define_expand "floatunssi<mode>2"
5063 [(parallel
5064 [(set (match_operand:X87MODEF 0 "register_operand")
5065 (unsigned_float:X87MODEF
5066 (match_operand:SI 1 "nonimmediate_operand")))
5067 (clobber (match_scratch:DI 3))
5068 (clobber (match_dup 2))])]
5069 "!TARGET_64BIT
5070 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5071 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5072 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5073 {
5074 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5075 {
5076 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5077 DONE;
5078 }
5079 else
5080 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5081 })
5082
5083 (define_expand "floatunsdisf2"
5084 [(use (match_operand:SF 0 "register_operand"))
5085 (use (match_operand:DI 1 "nonimmediate_operand"))]
5086 "TARGET_64BIT && TARGET_SSE_MATH"
5087 "x86_emit_floatuns (operands); DONE;")
5088
5089 (define_expand "floatunsdidf2"
5090 [(use (match_operand:DF 0 "register_operand"))
5091 (use (match_operand:DI 1 "nonimmediate_operand"))]
5092 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5093 && TARGET_SSE2 && TARGET_SSE_MATH"
5094 {
5095 if (TARGET_64BIT)
5096 x86_emit_floatuns (operands);
5097 else
5098 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5099 DONE;
5100 })
5101 \f
5102 ;; Load effective address instructions
5103
5104 (define_insn_and_split "*lea<mode>"
5105 [(set (match_operand:SWI48 0 "register_operand" "=r")
5106 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5107 ""
5108 {
5109 if (SImode_address_operand (operands[1], VOIDmode))
5110 {
5111 gcc_assert (TARGET_64BIT);
5112 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5113 }
5114 else
5115 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5116 }
5117 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5118 [(const_int 0)]
5119 {
5120 machine_mode mode = <MODE>mode;
5121 rtx pat;
5122
5123 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5124 change operands[] array behind our back. */
5125 pat = PATTERN (curr_insn);
5126
5127 operands[0] = SET_DEST (pat);
5128 operands[1] = SET_SRC (pat);
5129
5130 /* Emit all operations in SImode for zero-extended addresses. */
5131 if (SImode_address_operand (operands[1], VOIDmode))
5132 mode = SImode;
5133
5134 ix86_split_lea_for_addr (curr_insn, operands, mode);
5135
5136 /* Zero-extend return register to DImode for zero-extended addresses. */
5137 if (mode != <MODE>mode)
5138 emit_insn (gen_zero_extendsidi2
5139 (operands[0], gen_lowpart (mode, operands[0])));
5140
5141 DONE;
5142 }
5143 [(set_attr "type" "lea")
5144 (set (attr "mode")
5145 (if_then_else
5146 (match_operand 1 "SImode_address_operand")
5147 (const_string "SI")
5148 (const_string "<MODE>")))])
5149 \f
5150 ;; Add instructions
5151
5152 (define_expand "add<mode>3"
5153 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5154 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5155 (match_operand:SDWIM 2 "<general_operand>")))]
5156 ""
5157 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5158
5159 (define_insn_and_split "*add<dwi>3_doubleword"
5160 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5161 (plus:<DWI>
5162 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5163 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5164 (clobber (reg:CC FLAGS_REG))]
5165 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5166 "#"
5167 "reload_completed"
5168 [(parallel [(set (reg:CC FLAGS_REG)
5169 (unspec:CC [(match_dup 1) (match_dup 2)]
5170 UNSPEC_ADD_CARRY))
5171 (set (match_dup 0)
5172 (plus:DWIH (match_dup 1) (match_dup 2)))])
5173 (parallel [(set (match_dup 3)
5174 (plus:DWIH
5175 (match_dup 4)
5176 (plus:DWIH
5177 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5178 (match_dup 5))))
5179 (clobber (reg:CC FLAGS_REG))])]
5180 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5181
5182 (define_insn "*add<mode>3_cc"
5183 [(set (reg:CC FLAGS_REG)
5184 (unspec:CC
5185 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5186 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5187 UNSPEC_ADD_CARRY))
5188 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5189 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5190 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5191 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5192 [(set_attr "type" "alu")
5193 (set_attr "mode" "<MODE>")])
5194
5195 (define_insn "addqi3_cc"
5196 [(set (reg:CC FLAGS_REG)
5197 (unspec:CC
5198 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5199 (match_operand:QI 2 "general_operand" "qn,qm")]
5200 UNSPEC_ADD_CARRY))
5201 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5202 (plus:QI (match_dup 1) (match_dup 2)))]
5203 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5204 "add{b}\t{%2, %0|%0, %2}"
5205 [(set_attr "type" "alu")
5206 (set_attr "mode" "QI")])
5207
5208 (define_insn "*add<mode>_1"
5209 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5210 (plus:SWI48
5211 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5212 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5213 (clobber (reg:CC FLAGS_REG))]
5214 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5215 {
5216 switch (get_attr_type (insn))
5217 {
5218 case TYPE_LEA:
5219 return "#";
5220
5221 case TYPE_INCDEC:
5222 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5223 if (operands[2] == const1_rtx)
5224 return "inc{<imodesuffix>}\t%0";
5225 else
5226 {
5227 gcc_assert (operands[2] == constm1_rtx);
5228 return "dec{<imodesuffix>}\t%0";
5229 }
5230
5231 default:
5232 /* For most processors, ADD is faster than LEA. This alternative
5233 was added to use ADD as much as possible. */
5234 if (which_alternative == 2)
5235 std::swap (operands[1], operands[2]);
5236
5237 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5238 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5239 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5240
5241 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5242 }
5243 }
5244 [(set (attr "type")
5245 (cond [(eq_attr "alternative" "3")
5246 (const_string "lea")
5247 (match_operand:SWI48 2 "incdec_operand")
5248 (const_string "incdec")
5249 ]
5250 (const_string "alu")))
5251 (set (attr "length_immediate")
5252 (if_then_else
5253 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5254 (const_string "1")
5255 (const_string "*")))
5256 (set_attr "mode" "<MODE>")])
5257
5258 ;; It may seem that nonimmediate operand is proper one for operand 1.
5259 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5260 ;; we take care in ix86_binary_operator_ok to not allow two memory
5261 ;; operands so proper swapping will be done in reload. This allow
5262 ;; patterns constructed from addsi_1 to match.
5263
5264 (define_insn "addsi_1_zext"
5265 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5266 (zero_extend:DI
5267 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5268 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5269 (clobber (reg:CC FLAGS_REG))]
5270 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5271 {
5272 switch (get_attr_type (insn))
5273 {
5274 case TYPE_LEA:
5275 return "#";
5276
5277 case TYPE_INCDEC:
5278 if (operands[2] == const1_rtx)
5279 return "inc{l}\t%k0";
5280 else
5281 {
5282 gcc_assert (operands[2] == constm1_rtx);
5283 return "dec{l}\t%k0";
5284 }
5285
5286 default:
5287 /* For most processors, ADD is faster than LEA. This alternative
5288 was added to use ADD as much as possible. */
5289 if (which_alternative == 1)
5290 std::swap (operands[1], operands[2]);
5291
5292 if (x86_maybe_negate_const_int (&operands[2], SImode))
5293 return "sub{l}\t{%2, %k0|%k0, %2}";
5294
5295 return "add{l}\t{%2, %k0|%k0, %2}";
5296 }
5297 }
5298 [(set (attr "type")
5299 (cond [(eq_attr "alternative" "2")
5300 (const_string "lea")
5301 (match_operand:SI 2 "incdec_operand")
5302 (const_string "incdec")
5303 ]
5304 (const_string "alu")))
5305 (set (attr "length_immediate")
5306 (if_then_else
5307 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5308 (const_string "1")
5309 (const_string "*")))
5310 (set_attr "mode" "SI")])
5311
5312 (define_insn "*addhi_1"
5313 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5314 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5315 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5316 (clobber (reg:CC FLAGS_REG))]
5317 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5318 {
5319 switch (get_attr_type (insn))
5320 {
5321 case TYPE_LEA:
5322 return "#";
5323
5324 case TYPE_INCDEC:
5325 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5326 if (operands[2] == const1_rtx)
5327 return "inc{w}\t%0";
5328 else
5329 {
5330 gcc_assert (operands[2] == constm1_rtx);
5331 return "dec{w}\t%0";
5332 }
5333
5334 default:
5335 /* For most processors, ADD is faster than LEA. This alternative
5336 was added to use ADD as much as possible. */
5337 if (which_alternative == 2)
5338 std::swap (operands[1], operands[2]);
5339
5340 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5341 if (x86_maybe_negate_const_int (&operands[2], HImode))
5342 return "sub{w}\t{%2, %0|%0, %2}";
5343
5344 return "add{w}\t{%2, %0|%0, %2}";
5345 }
5346 }
5347 [(set (attr "type")
5348 (cond [(eq_attr "alternative" "3")
5349 (const_string "lea")
5350 (match_operand:HI 2 "incdec_operand")
5351 (const_string "incdec")
5352 ]
5353 (const_string "alu")))
5354 (set (attr "length_immediate")
5355 (if_then_else
5356 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5357 (const_string "1")
5358 (const_string "*")))
5359 (set_attr "mode" "HI,HI,HI,SI")])
5360
5361 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5362 (define_insn "*addqi_1"
5363 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5364 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5365 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5366 (clobber (reg:CC FLAGS_REG))]
5367 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5368 {
5369 bool widen = (which_alternative == 3 || which_alternative == 4);
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 widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5380 else
5381 {
5382 gcc_assert (operands[2] == constm1_rtx);
5383 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5384 }
5385
5386 default:
5387 /* For most processors, ADD is faster than LEA. These alternatives
5388 were added to use ADD as much as possible. */
5389 if (which_alternative == 2 || which_alternative == 4)
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], QImode))
5394 {
5395 if (widen)
5396 return "sub{l}\t{%2, %k0|%k0, %2}";
5397 else
5398 return "sub{b}\t{%2, %0|%0, %2}";
5399 }
5400 if (widen)
5401 return "add{l}\t{%k2, %k0|%k0, %k2}";
5402 else
5403 return "add{b}\t{%2, %0|%0, %2}";
5404 }
5405 }
5406 [(set (attr "type")
5407 (cond [(eq_attr "alternative" "5")
5408 (const_string "lea")
5409 (match_operand:QI 2 "incdec_operand")
5410 (const_string "incdec")
5411 ]
5412 (const_string "alu")))
5413 (set (attr "length_immediate")
5414 (if_then_else
5415 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5416 (const_string "1")
5417 (const_string "*")))
5418 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5419
5420 (define_insn "*addqi_1_slp"
5421 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5422 (plus:QI (match_dup 0)
5423 (match_operand:QI 1 "general_operand" "qn,qm")))
5424 (clobber (reg:CC FLAGS_REG))]
5425 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5426 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5427 {
5428 switch (get_attr_type (insn))
5429 {
5430 case TYPE_INCDEC:
5431 if (operands[1] == const1_rtx)
5432 return "inc{b}\t%0";
5433 else
5434 {
5435 gcc_assert (operands[1] == constm1_rtx);
5436 return "dec{b}\t%0";
5437 }
5438
5439 default:
5440 if (x86_maybe_negate_const_int (&operands[1], QImode))
5441 return "sub{b}\t{%1, %0|%0, %1}";
5442
5443 return "add{b}\t{%1, %0|%0, %1}";
5444 }
5445 }
5446 [(set (attr "type")
5447 (if_then_else (match_operand:QI 1 "incdec_operand")
5448 (const_string "incdec")
5449 (const_string "alu1")))
5450 (set (attr "memory")
5451 (if_then_else (match_operand 1 "memory_operand")
5452 (const_string "load")
5453 (const_string "none")))
5454 (set_attr "mode" "QI")])
5455
5456 ;; Split non destructive adds if we cannot use lea.
5457 (define_split
5458 [(set (match_operand:SWI48 0 "register_operand")
5459 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5460 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5461 (clobber (reg:CC FLAGS_REG))]
5462 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5463 [(set (match_dup 0) (match_dup 1))
5464 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5465 (clobber (reg:CC FLAGS_REG))])])
5466
5467 ;; Convert add to the lea pattern to avoid flags dependency.
5468 (define_split
5469 [(set (match_operand:SWI 0 "register_operand")
5470 (plus:SWI (match_operand:SWI 1 "register_operand")
5471 (match_operand:SWI 2 "<nonmemory_operand>")))
5472 (clobber (reg:CC FLAGS_REG))]
5473 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5474 [(const_int 0)]
5475 {
5476 machine_mode mode = <MODE>mode;
5477 rtx pat;
5478
5479 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5480 {
5481 mode = SImode;
5482 operands[0] = gen_lowpart (mode, operands[0]);
5483 operands[1] = gen_lowpart (mode, operands[1]);
5484 operands[2] = gen_lowpart (mode, operands[2]);
5485 }
5486
5487 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5488
5489 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5490 DONE;
5491 })
5492
5493 ;; Split non destructive adds if we cannot use lea.
5494 (define_split
5495 [(set (match_operand:DI 0 "register_operand")
5496 (zero_extend:DI
5497 (plus:SI (match_operand:SI 1 "register_operand")
5498 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5499 (clobber (reg:CC FLAGS_REG))]
5500 "TARGET_64BIT
5501 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5502 [(set (match_dup 3) (match_dup 1))
5503 (parallel [(set (match_dup 0)
5504 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5505 (clobber (reg:CC FLAGS_REG))])]
5506 "operands[3] = gen_lowpart (SImode, operands[0]);")
5507
5508 ;; Convert add to the lea pattern to avoid flags dependency.
5509 (define_split
5510 [(set (match_operand:DI 0 "register_operand")
5511 (zero_extend:DI
5512 (plus:SI (match_operand:SI 1 "register_operand")
5513 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5514 (clobber (reg:CC FLAGS_REG))]
5515 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5516 [(set (match_dup 0)
5517 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5518
5519 (define_insn "*add<mode>_2"
5520 [(set (reg FLAGS_REG)
5521 (compare
5522 (plus:SWI
5523 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5524 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5525 (const_int 0)))
5526 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5527 (plus:SWI (match_dup 1) (match_dup 2)))]
5528 "ix86_match_ccmode (insn, CCGOCmode)
5529 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5530 {
5531 switch (get_attr_type (insn))
5532 {
5533 case TYPE_INCDEC:
5534 if (operands[2] == const1_rtx)
5535 return "inc{<imodesuffix>}\t%0";
5536 else
5537 {
5538 gcc_assert (operands[2] == constm1_rtx);
5539 return "dec{<imodesuffix>}\t%0";
5540 }
5541
5542 default:
5543 if (which_alternative == 2)
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], <MODE>mode))
5548 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5549
5550 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5551 }
5552 }
5553 [(set (attr "type")
5554 (if_then_else (match_operand:SWI 2 "incdec_operand")
5555 (const_string "incdec")
5556 (const_string "alu")))
5557 (set (attr "length_immediate")
5558 (if_then_else
5559 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5560 (const_string "1")
5561 (const_string "*")))
5562 (set_attr "mode" "<MODE>")])
5563
5564 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5565 (define_insn "*addsi_2_zext"
5566 [(set (reg FLAGS_REG)
5567 (compare
5568 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5569 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5570 (const_int 0)))
5571 (set (match_operand:DI 0 "register_operand" "=r,r")
5572 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5573 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5574 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5575 {
5576 switch (get_attr_type (insn))
5577 {
5578 case TYPE_INCDEC:
5579 if (operands[2] == const1_rtx)
5580 return "inc{l}\t%k0";
5581 else
5582 {
5583 gcc_assert (operands[2] == constm1_rtx);
5584 return "dec{l}\t%k0";
5585 }
5586
5587 default:
5588 if (which_alternative == 1)
5589 std::swap (operands[1], operands[2]);
5590
5591 if (x86_maybe_negate_const_int (&operands[2], SImode))
5592 return "sub{l}\t{%2, %k0|%k0, %2}";
5593
5594 return "add{l}\t{%2, %k0|%k0, %2}";
5595 }
5596 }
5597 [(set (attr "type")
5598 (if_then_else (match_operand:SI 2 "incdec_operand")
5599 (const_string "incdec")
5600 (const_string "alu")))
5601 (set (attr "length_immediate")
5602 (if_then_else
5603 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5604 (const_string "1")
5605 (const_string "*")))
5606 (set_attr "mode" "SI")])
5607
5608 (define_insn "*add<mode>_3"
5609 [(set (reg FLAGS_REG)
5610 (compare
5611 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5612 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5613 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5614 "ix86_match_ccmode (insn, CCZmode)
5615 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5616 {
5617 switch (get_attr_type (insn))
5618 {
5619 case TYPE_INCDEC:
5620 if (operands[2] == const1_rtx)
5621 return "inc{<imodesuffix>}\t%0";
5622 else
5623 {
5624 gcc_assert (operands[2] == constm1_rtx);
5625 return "dec{<imodesuffix>}\t%0";
5626 }
5627
5628 default:
5629 if (which_alternative == 1)
5630 std::swap (operands[1], operands[2]);
5631
5632 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5633 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5634 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5635
5636 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5637 }
5638 }
5639 [(set (attr "type")
5640 (if_then_else (match_operand:SWI 2 "incdec_operand")
5641 (const_string "incdec")
5642 (const_string "alu")))
5643 (set (attr "length_immediate")
5644 (if_then_else
5645 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5646 (const_string "1")
5647 (const_string "*")))
5648 (set_attr "mode" "<MODE>")])
5649
5650 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5651 (define_insn "*addsi_3_zext"
5652 [(set (reg FLAGS_REG)
5653 (compare
5654 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5655 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5656 (set (match_operand:DI 0 "register_operand" "=r,r")
5657 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5658 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5659 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5660 {
5661 switch (get_attr_type (insn))
5662 {
5663 case TYPE_INCDEC:
5664 if (operands[2] == const1_rtx)
5665 return "inc{l}\t%k0";
5666 else
5667 {
5668 gcc_assert (operands[2] == constm1_rtx);
5669 return "dec{l}\t%k0";
5670 }
5671
5672 default:
5673 if (which_alternative == 1)
5674 std::swap (operands[1], operands[2]);
5675
5676 if (x86_maybe_negate_const_int (&operands[2], SImode))
5677 return "sub{l}\t{%2, %k0|%k0, %2}";
5678
5679 return "add{l}\t{%2, %k0|%k0, %2}";
5680 }
5681 }
5682 [(set (attr "type")
5683 (if_then_else (match_operand:SI 2 "incdec_operand")
5684 (const_string "incdec")
5685 (const_string "alu")))
5686 (set (attr "length_immediate")
5687 (if_then_else
5688 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5689 (const_string "1")
5690 (const_string "*")))
5691 (set_attr "mode" "SI")])
5692
5693 ; For comparisons against 1, -1 and 128, we may generate better code
5694 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5695 ; is matched then. We can't accept general immediate, because for
5696 ; case of overflows, the result is messed up.
5697 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5698 ; only for comparisons not depending on it.
5699
5700 (define_insn "*adddi_4"
5701 [(set (reg FLAGS_REG)
5702 (compare
5703 (match_operand:DI 1 "nonimmediate_operand" "0")
5704 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5705 (clobber (match_scratch:DI 0 "=rm"))]
5706 "TARGET_64BIT
5707 && ix86_match_ccmode (insn, CCGCmode)"
5708 {
5709 switch (get_attr_type (insn))
5710 {
5711 case TYPE_INCDEC:
5712 if (operands[2] == constm1_rtx)
5713 return "inc{q}\t%0";
5714 else
5715 {
5716 gcc_assert (operands[2] == const1_rtx);
5717 return "dec{q}\t%0";
5718 }
5719
5720 default:
5721 if (x86_maybe_negate_const_int (&operands[2], DImode))
5722 return "add{q}\t{%2, %0|%0, %2}";
5723
5724 return "sub{q}\t{%2, %0|%0, %2}";
5725 }
5726 }
5727 [(set (attr "type")
5728 (if_then_else (match_operand:DI 2 "incdec_operand")
5729 (const_string "incdec")
5730 (const_string "alu")))
5731 (set (attr "length_immediate")
5732 (if_then_else
5733 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5734 (const_string "1")
5735 (const_string "*")))
5736 (set_attr "mode" "DI")])
5737
5738 ; For comparisons against 1, -1 and 128, we may generate better code
5739 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5740 ; is matched then. We can't accept general immediate, because for
5741 ; case of overflows, the result is messed up.
5742 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5743 ; only for comparisons not depending on it.
5744
5745 (define_insn "*add<mode>_4"
5746 [(set (reg FLAGS_REG)
5747 (compare
5748 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5749 (match_operand:SWI124 2 "const_int_operand" "n")))
5750 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5751 "ix86_match_ccmode (insn, CCGCmode)"
5752 {
5753 switch (get_attr_type (insn))
5754 {
5755 case TYPE_INCDEC:
5756 if (operands[2] == constm1_rtx)
5757 return "inc{<imodesuffix>}\t%0";
5758 else
5759 {
5760 gcc_assert (operands[2] == const1_rtx);
5761 return "dec{<imodesuffix>}\t%0";
5762 }
5763
5764 default:
5765 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5766 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5767
5768 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5769 }
5770 }
5771 [(set (attr "type")
5772 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5773 (const_string "incdec")
5774 (const_string "alu")))
5775 (set (attr "length_immediate")
5776 (if_then_else
5777 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5778 (const_string "1")
5779 (const_string "*")))
5780 (set_attr "mode" "<MODE>")])
5781
5782 (define_insn "*add<mode>_5"
5783 [(set (reg FLAGS_REG)
5784 (compare
5785 (plus:SWI
5786 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5787 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5788 (const_int 0)))
5789 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5790 "ix86_match_ccmode (insn, CCGOCmode)
5791 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5792 {
5793 switch (get_attr_type (insn))
5794 {
5795 case TYPE_INCDEC:
5796 if (operands[2] == const1_rtx)
5797 return "inc{<imodesuffix>}\t%0";
5798 else
5799 {
5800 gcc_assert (operands[2] == constm1_rtx);
5801 return "dec{<imodesuffix>}\t%0";
5802 }
5803
5804 default:
5805 if (which_alternative == 1)
5806 std::swap (operands[1], operands[2]);
5807
5808 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5810 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5811
5812 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5813 }
5814 }
5815 [(set (attr "type")
5816 (if_then_else (match_operand:SWI 2 "incdec_operand")
5817 (const_string "incdec")
5818 (const_string "alu")))
5819 (set (attr "length_immediate")
5820 (if_then_else
5821 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5822 (const_string "1")
5823 (const_string "*")))
5824 (set_attr "mode" "<MODE>")])
5825
5826 (define_insn "addqi_ext_1"
5827 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5828 (const_int 8)
5829 (const_int 8))
5830 (plus:SI
5831 (zero_extract:SI
5832 (match_operand 1 "ext_register_operand" "0,0")
5833 (const_int 8)
5834 (const_int 8))
5835 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5836 (clobber (reg:CC FLAGS_REG))]
5837 ""
5838 {
5839 switch (get_attr_type (insn))
5840 {
5841 case TYPE_INCDEC:
5842 if (operands[2] == const1_rtx)
5843 return "inc{b}\t%h0";
5844 else
5845 {
5846 gcc_assert (operands[2] == constm1_rtx);
5847 return "dec{b}\t%h0";
5848 }
5849
5850 default:
5851 return "add{b}\t{%2, %h0|%h0, %2}";
5852 }
5853 }
5854 [(set_attr "isa" "*,nox64")
5855 (set (attr "type")
5856 (if_then_else (match_operand:QI 2 "incdec_operand")
5857 (const_string "incdec")
5858 (const_string "alu")))
5859 (set_attr "modrm" "1")
5860 (set_attr "mode" "QI")])
5861
5862 (define_insn "*addqi_ext_2"
5863 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5864 (const_int 8)
5865 (const_int 8))
5866 (plus:SI
5867 (zero_extract:SI
5868 (match_operand 1 "ext_register_operand" "%0")
5869 (const_int 8)
5870 (const_int 8))
5871 (zero_extract:SI
5872 (match_operand 2 "ext_register_operand" "Q")
5873 (const_int 8)
5874 (const_int 8))))
5875 (clobber (reg:CC FLAGS_REG))]
5876 ""
5877 "add{b}\t{%h2, %h0|%h0, %h2}"
5878 [(set_attr "type" "alu")
5879 (set_attr "mode" "QI")])
5880
5881 ;; Add with jump on overflow.
5882 (define_expand "addv<mode>4"
5883 [(parallel [(set (reg:CCO FLAGS_REG)
5884 (eq:CCO (plus:<DWI>
5885 (sign_extend:<DWI>
5886 (match_operand:SWI 1 "nonimmediate_operand"))
5887 (match_dup 4))
5888 (sign_extend:<DWI>
5889 (plus:SWI (match_dup 1)
5890 (match_operand:SWI 2
5891 "<general_operand>")))))
5892 (set (match_operand:SWI 0 "register_operand")
5893 (plus:SWI (match_dup 1) (match_dup 2)))])
5894 (set (pc) (if_then_else
5895 (eq (reg:CCO FLAGS_REG) (const_int 0))
5896 (label_ref (match_operand 3))
5897 (pc)))]
5898 ""
5899 {
5900 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5901 if (CONST_INT_P (operands[2]))
5902 operands[4] = operands[2];
5903 else
5904 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5905 })
5906
5907 (define_insn "*addv<mode>4"
5908 [(set (reg:CCO FLAGS_REG)
5909 (eq:CCO (plus:<DWI>
5910 (sign_extend:<DWI>
5911 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5912 (sign_extend:<DWI>
5913 (match_operand:SWI 2 "<general_sext_operand>"
5914 "<r>mWe,<r>We")))
5915 (sign_extend:<DWI>
5916 (plus:SWI (match_dup 1) (match_dup 2)))))
5917 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5918 (plus:SWI (match_dup 1) (match_dup 2)))]
5919 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5920 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5921 [(set_attr "type" "alu")
5922 (set_attr "mode" "<MODE>")])
5923
5924 (define_insn "*addv<mode>4_1"
5925 [(set (reg:CCO FLAGS_REG)
5926 (eq:CCO (plus:<DWI>
5927 (sign_extend:<DWI>
5928 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5929 (match_operand:<DWI> 3 "const_int_operand" "i"))
5930 (sign_extend:<DWI>
5931 (plus:SWI (match_dup 1)
5932 (match_operand:SWI 2 "x86_64_immediate_operand"
5933 "<i>")))))
5934 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5935 (plus:SWI (match_dup 1) (match_dup 2)))]
5936 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5937 && CONST_INT_P (operands[2])
5938 && INTVAL (operands[2]) == INTVAL (operands[3])"
5939 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5940 [(set_attr "type" "alu")
5941 (set_attr "mode" "<MODE>")
5942 (set (attr "length_immediate")
5943 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5944 (const_string "1")
5945 (match_test "<MODE_SIZE> == 8")
5946 (const_string "4")]
5947 (const_string "<MODE_SIZE>")))])
5948
5949 ;; The lea patterns for modes less than 32 bits need to be matched by
5950 ;; several insns converted to real lea by splitters.
5951
5952 (define_insn_and_split "*lea_general_1"
5953 [(set (match_operand 0 "register_operand" "=r")
5954 (plus (plus (match_operand 1 "index_register_operand" "l")
5955 (match_operand 2 "register_operand" "r"))
5956 (match_operand 3 "immediate_operand" "i")))]
5957 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5958 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5959 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5960 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5961 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5962 || GET_MODE (operands[3]) == VOIDmode)"
5963 "#"
5964 "&& reload_completed"
5965 [(const_int 0)]
5966 {
5967 machine_mode mode = SImode;
5968 rtx pat;
5969
5970 operands[0] = gen_lowpart (mode, operands[0]);
5971 operands[1] = gen_lowpart (mode, operands[1]);
5972 operands[2] = gen_lowpart (mode, operands[2]);
5973 operands[3] = gen_lowpart (mode, operands[3]);
5974
5975 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5976 operands[3]);
5977
5978 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5979 DONE;
5980 }
5981 [(set_attr "type" "lea")
5982 (set_attr "mode" "SI")])
5983
5984 (define_insn_and_split "*lea_general_2"
5985 [(set (match_operand 0 "register_operand" "=r")
5986 (plus (mult (match_operand 1 "index_register_operand" "l")
5987 (match_operand 2 "const248_operand" "n"))
5988 (match_operand 3 "nonmemory_operand" "ri")))]
5989 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5990 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5991 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5992 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5993 || GET_MODE (operands[3]) == VOIDmode)"
5994 "#"
5995 "&& reload_completed"
5996 [(const_int 0)]
5997 {
5998 machine_mode mode = SImode;
5999 rtx pat;
6000
6001 operands[0] = gen_lowpart (mode, operands[0]);
6002 operands[1] = gen_lowpart (mode, operands[1]);
6003 operands[3] = gen_lowpart (mode, operands[3]);
6004
6005 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6006 operands[3]);
6007
6008 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6009 DONE;
6010 }
6011 [(set_attr "type" "lea")
6012 (set_attr "mode" "SI")])
6013
6014 (define_insn_and_split "*lea_general_3"
6015 [(set (match_operand 0 "register_operand" "=r")
6016 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6017 (match_operand 2 "const248_operand" "n"))
6018 (match_operand 3 "register_operand" "r"))
6019 (match_operand 4 "immediate_operand" "i")))]
6020 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6021 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6022 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6023 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6024 "#"
6025 "&& reload_completed"
6026 [(const_int 0)]
6027 {
6028 machine_mode mode = SImode;
6029 rtx pat;
6030
6031 operands[0] = gen_lowpart (mode, operands[0]);
6032 operands[1] = gen_lowpart (mode, operands[1]);
6033 operands[3] = gen_lowpart (mode, operands[3]);
6034 operands[4] = gen_lowpart (mode, operands[4]);
6035
6036 pat = gen_rtx_PLUS (mode,
6037 gen_rtx_PLUS (mode,
6038 gen_rtx_MULT (mode, operands[1],
6039 operands[2]),
6040 operands[3]),
6041 operands[4]);
6042
6043 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6044 DONE;
6045 }
6046 [(set_attr "type" "lea")
6047 (set_attr "mode" "SI")])
6048
6049 (define_insn_and_split "*lea_general_4"
6050 [(set (match_operand 0 "register_operand" "=r")
6051 (any_or (ashift
6052 (match_operand 1 "index_register_operand" "l")
6053 (match_operand 2 "const_int_operand" "n"))
6054 (match_operand 3 "const_int_operand" "n")))]
6055 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6056 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6057 || GET_MODE (operands[0]) == SImode
6058 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6059 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6060 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6061 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6062 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6063 "#"
6064 "&& reload_completed"
6065 [(const_int 0)]
6066 {
6067 machine_mode mode = GET_MODE (operands[0]);
6068 rtx pat;
6069
6070 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6071 {
6072 mode = SImode;
6073 operands[0] = gen_lowpart (mode, operands[0]);
6074 operands[1] = gen_lowpart (mode, operands[1]);
6075 }
6076
6077 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6078
6079 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6080 INTVAL (operands[3]));
6081
6082 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6083 DONE;
6084 }
6085 [(set_attr "type" "lea")
6086 (set (attr "mode")
6087 (if_then_else (match_operand:DI 0)
6088 (const_string "DI")
6089 (const_string "SI")))])
6090 \f
6091 ;; Subtract instructions
6092
6093 (define_expand "sub<mode>3"
6094 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6095 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6096 (match_operand:SDWIM 2 "<general_operand>")))]
6097 ""
6098 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6099
6100 (define_insn_and_split "*sub<dwi>3_doubleword"
6101 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6102 (minus:<DWI>
6103 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6104 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6105 (clobber (reg:CC FLAGS_REG))]
6106 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6107 "#"
6108 "reload_completed"
6109 [(parallel [(set (reg:CC FLAGS_REG)
6110 (compare:CC (match_dup 1) (match_dup 2)))
6111 (set (match_dup 0)
6112 (minus:DWIH (match_dup 1) (match_dup 2)))])
6113 (parallel [(set (match_dup 3)
6114 (minus:DWIH
6115 (match_dup 4)
6116 (plus:DWIH
6117 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6118 (match_dup 5))))
6119 (clobber (reg:CC FLAGS_REG))])]
6120 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6121
6122 (define_insn "*sub<mode>_1"
6123 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6124 (minus:SWI
6125 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6126 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6127 (clobber (reg:CC FLAGS_REG))]
6128 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6129 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6130 [(set_attr "type" "alu")
6131 (set_attr "mode" "<MODE>")])
6132
6133 (define_insn "*subsi_1_zext"
6134 [(set (match_operand:DI 0 "register_operand" "=r")
6135 (zero_extend:DI
6136 (minus:SI (match_operand:SI 1 "register_operand" "0")
6137 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6138 (clobber (reg:CC FLAGS_REG))]
6139 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6140 "sub{l}\t{%2, %k0|%k0, %2}"
6141 [(set_attr "type" "alu")
6142 (set_attr "mode" "SI")])
6143
6144 (define_insn "*subqi_1_slp"
6145 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6146 (minus:QI (match_dup 0)
6147 (match_operand:QI 1 "general_operand" "qn,qm")))
6148 (clobber (reg:CC FLAGS_REG))]
6149 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6150 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6151 "sub{b}\t{%1, %0|%0, %1}"
6152 [(set_attr "type" "alu1")
6153 (set_attr "mode" "QI")])
6154
6155 (define_insn "*sub<mode>_2"
6156 [(set (reg FLAGS_REG)
6157 (compare
6158 (minus:SWI
6159 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6160 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6161 (const_int 0)))
6162 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6163 (minus:SWI (match_dup 1) (match_dup 2)))]
6164 "ix86_match_ccmode (insn, CCGOCmode)
6165 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6166 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6167 [(set_attr "type" "alu")
6168 (set_attr "mode" "<MODE>")])
6169
6170 (define_insn "*subsi_2_zext"
6171 [(set (reg FLAGS_REG)
6172 (compare
6173 (minus:SI (match_operand:SI 1 "register_operand" "0")
6174 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6175 (const_int 0)))
6176 (set (match_operand:DI 0 "register_operand" "=r")
6177 (zero_extend:DI
6178 (minus:SI (match_dup 1)
6179 (match_dup 2))))]
6180 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6181 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6182 "sub{l}\t{%2, %k0|%k0, %2}"
6183 [(set_attr "type" "alu")
6184 (set_attr "mode" "SI")])
6185
6186 ;; Subtract with jump on overflow.
6187 (define_expand "subv<mode>4"
6188 [(parallel [(set (reg:CCO FLAGS_REG)
6189 (eq:CCO (minus:<DWI>
6190 (sign_extend:<DWI>
6191 (match_operand:SWI 1 "nonimmediate_operand"))
6192 (match_dup 4))
6193 (sign_extend:<DWI>
6194 (minus:SWI (match_dup 1)
6195 (match_operand:SWI 2
6196 "<general_operand>")))))
6197 (set (match_operand:SWI 0 "register_operand")
6198 (minus:SWI (match_dup 1) (match_dup 2)))])
6199 (set (pc) (if_then_else
6200 (eq (reg:CCO FLAGS_REG) (const_int 0))
6201 (label_ref (match_operand 3))
6202 (pc)))]
6203 ""
6204 {
6205 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6206 if (CONST_INT_P (operands[2]))
6207 operands[4] = operands[2];
6208 else
6209 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6210 })
6211
6212 (define_insn "*subv<mode>4"
6213 [(set (reg:CCO FLAGS_REG)
6214 (eq:CCO (minus:<DWI>
6215 (sign_extend:<DWI>
6216 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6217 (sign_extend:<DWI>
6218 (match_operand:SWI 2 "<general_sext_operand>"
6219 "<r>We,<r>m")))
6220 (sign_extend:<DWI>
6221 (minus:SWI (match_dup 1) (match_dup 2)))))
6222 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6223 (minus:SWI (match_dup 1) (match_dup 2)))]
6224 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6225 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6226 [(set_attr "type" "alu")
6227 (set_attr "mode" "<MODE>")])
6228
6229 (define_insn "*subv<mode>4_1"
6230 [(set (reg:CCO FLAGS_REG)
6231 (eq:CCO (minus:<DWI>
6232 (sign_extend:<DWI>
6233 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6234 (match_operand:<DWI> 3 "const_int_operand" "i"))
6235 (sign_extend:<DWI>
6236 (minus:SWI (match_dup 1)
6237 (match_operand:SWI 2 "x86_64_immediate_operand"
6238 "<i>")))))
6239 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6240 (minus:SWI (match_dup 1) (match_dup 2)))]
6241 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6242 && CONST_INT_P (operands[2])
6243 && INTVAL (operands[2]) == INTVAL (operands[3])"
6244 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6245 [(set_attr "type" "alu")
6246 (set_attr "mode" "<MODE>")
6247 (set (attr "length_immediate")
6248 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6249 (const_string "1")
6250 (match_test "<MODE_SIZE> == 8")
6251 (const_string "4")]
6252 (const_string "<MODE_SIZE>")))])
6253
6254 (define_insn "*sub<mode>_3"
6255 [(set (reg FLAGS_REG)
6256 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6257 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6258 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6259 (minus:SWI (match_dup 1) (match_dup 2)))]
6260 "ix86_match_ccmode (insn, CCmode)
6261 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6262 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6263 [(set_attr "type" "alu")
6264 (set_attr "mode" "<MODE>")])
6265
6266 (define_insn "*subsi_3_zext"
6267 [(set (reg FLAGS_REG)
6268 (compare (match_operand:SI 1 "register_operand" "0")
6269 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6270 (set (match_operand:DI 0 "register_operand" "=r")
6271 (zero_extend:DI
6272 (minus:SI (match_dup 1)
6273 (match_dup 2))))]
6274 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6275 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6276 "sub{l}\t{%2, %1|%1, %2}"
6277 [(set_attr "type" "alu")
6278 (set_attr "mode" "SI")])
6279 \f
6280 ;; Add with carry and subtract with borrow
6281
6282 (define_expand "<plusminus_insn><mode>3_carry"
6283 [(parallel
6284 [(set (match_operand:SWI 0 "nonimmediate_operand")
6285 (plusminus:SWI
6286 (match_operand:SWI 1 "nonimmediate_operand")
6287 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6288 [(match_operand 3 "flags_reg_operand")
6289 (const_int 0)])
6290 (match_operand:SWI 2 "<general_operand>"))))
6291 (clobber (reg:CC FLAGS_REG))])]
6292 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6293
6294 (define_insn "*<plusminus_insn><mode>3_carry"
6295 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6296 (plusminus:SWI
6297 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6298 (plus:SWI
6299 (match_operator 3 "ix86_carry_flag_operator"
6300 [(reg FLAGS_REG) (const_int 0)])
6301 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6302 (clobber (reg:CC FLAGS_REG))]
6303 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6304 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6305 [(set_attr "type" "alu")
6306 (set_attr "use_carry" "1")
6307 (set_attr "pent_pair" "pu")
6308 (set_attr "mode" "<MODE>")])
6309
6310 (define_insn "*addsi3_carry_zext"
6311 [(set (match_operand:DI 0 "register_operand" "=r")
6312 (zero_extend:DI
6313 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6314 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6315 [(reg FLAGS_REG) (const_int 0)])
6316 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6317 (clobber (reg:CC FLAGS_REG))]
6318 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6319 "adc{l}\t{%2, %k0|%k0, %2}"
6320 [(set_attr "type" "alu")
6321 (set_attr "use_carry" "1")
6322 (set_attr "pent_pair" "pu")
6323 (set_attr "mode" "SI")])
6324
6325 (define_insn "*subsi3_carry_zext"
6326 [(set (match_operand:DI 0 "register_operand" "=r")
6327 (zero_extend:DI
6328 (minus:SI (match_operand:SI 1 "register_operand" "0")
6329 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6330 [(reg FLAGS_REG) (const_int 0)])
6331 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6332 (clobber (reg:CC FLAGS_REG))]
6333 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6334 "sbb{l}\t{%2, %k0|%k0, %2}"
6335 [(set_attr "type" "alu")
6336 (set_attr "pent_pair" "pu")
6337 (set_attr "mode" "SI")])
6338 \f
6339 ;; ADCX instruction
6340
6341 (define_insn "adcx<mode>3"
6342 [(set (reg:CCC FLAGS_REG)
6343 (compare:CCC
6344 (plus:SWI48
6345 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6346 (plus:SWI48
6347 (match_operator 4 "ix86_carry_flag_operator"
6348 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6349 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6350 (const_int 0)))
6351 (set (match_operand:SWI48 0 "register_operand" "=r")
6352 (plus:SWI48 (match_dup 1)
6353 (plus:SWI48 (match_op_dup 4
6354 [(match_dup 3) (const_int 0)])
6355 (match_dup 2))))]
6356 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6357 "adcx\t{%2, %0|%0, %2}"
6358 [(set_attr "type" "alu")
6359 (set_attr "use_carry" "1")
6360 (set_attr "mode" "<MODE>")])
6361 \f
6362 ;; Overflow setting add instructions
6363
6364 (define_insn "*add<mode>3_cconly_overflow"
6365 [(set (reg:CCC FLAGS_REG)
6366 (compare:CCC
6367 (plus:SWI
6368 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6369 (match_operand:SWI 2 "<general_operand>" "<g>"))
6370 (match_dup 1)))
6371 (clobber (match_scratch:SWI 0 "=<r>"))]
6372 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6373 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6374 [(set_attr "type" "alu")
6375 (set_attr "mode" "<MODE>")])
6376
6377 (define_insn "*add<mode>3_cc_overflow"
6378 [(set (reg:CCC FLAGS_REG)
6379 (compare:CCC
6380 (plus:SWI
6381 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6382 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6383 (match_dup 1)))
6384 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6385 (plus:SWI (match_dup 1) (match_dup 2)))]
6386 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6387 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6388 [(set_attr "type" "alu")
6389 (set_attr "mode" "<MODE>")])
6390
6391 (define_insn "*addsi3_zext_cc_overflow"
6392 [(set (reg:CCC FLAGS_REG)
6393 (compare:CCC
6394 (plus:SI
6395 (match_operand:SI 1 "nonimmediate_operand" "%0")
6396 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6397 (match_dup 1)))
6398 (set (match_operand:DI 0 "register_operand" "=r")
6399 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6400 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6401 "add{l}\t{%2, %k0|%k0, %2}"
6402 [(set_attr "type" "alu")
6403 (set_attr "mode" "SI")])
6404
6405 ;; The patterns that match these are at the end of this file.
6406
6407 (define_expand "<plusminus_insn>xf3"
6408 [(set (match_operand:XF 0 "register_operand")
6409 (plusminus:XF
6410 (match_operand:XF 1 "register_operand")
6411 (match_operand:XF 2 "register_operand")))]
6412 "TARGET_80387")
6413
6414 (define_expand "<plusminus_insn><mode>3"
6415 [(set (match_operand:MODEF 0 "register_operand")
6416 (plusminus:MODEF
6417 (match_operand:MODEF 1 "register_operand")
6418 (match_operand:MODEF 2 "nonimmediate_operand")))]
6419 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6420 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6421 \f
6422 ;; Multiply instructions
6423
6424 (define_expand "mul<mode>3"
6425 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6426 (mult:SWIM248
6427 (match_operand:SWIM248 1 "register_operand")
6428 (match_operand:SWIM248 2 "<general_operand>")))
6429 (clobber (reg:CC FLAGS_REG))])])
6430
6431 (define_expand "mulqi3"
6432 [(parallel [(set (match_operand:QI 0 "register_operand")
6433 (mult:QI
6434 (match_operand:QI 1 "register_operand")
6435 (match_operand:QI 2 "nonimmediate_operand")))
6436 (clobber (reg:CC FLAGS_REG))])]
6437 "TARGET_QIMODE_MATH")
6438
6439 ;; On AMDFAM10
6440 ;; IMUL reg32/64, reg32/64, imm8 Direct
6441 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6442 ;; IMUL reg32/64, reg32/64, imm32 Direct
6443 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6444 ;; IMUL reg32/64, reg32/64 Direct
6445 ;; IMUL reg32/64, mem32/64 Direct
6446 ;;
6447 ;; On BDVER1, all above IMULs use DirectPath
6448
6449 (define_insn "*mul<mode>3_1"
6450 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6451 (mult:SWI48
6452 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6453 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6454 (clobber (reg:CC FLAGS_REG))]
6455 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6456 "@
6457 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6458 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6459 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6460 [(set_attr "type" "imul")
6461 (set_attr "prefix_0f" "0,0,1")
6462 (set (attr "athlon_decode")
6463 (cond [(eq_attr "cpu" "athlon")
6464 (const_string "vector")
6465 (eq_attr "alternative" "1")
6466 (const_string "vector")
6467 (and (eq_attr "alternative" "2")
6468 (match_operand 1 "memory_operand"))
6469 (const_string "vector")]
6470 (const_string "direct")))
6471 (set (attr "amdfam10_decode")
6472 (cond [(and (eq_attr "alternative" "0,1")
6473 (match_operand 1 "memory_operand"))
6474 (const_string "vector")]
6475 (const_string "direct")))
6476 (set_attr "bdver1_decode" "direct")
6477 (set_attr "mode" "<MODE>")])
6478
6479 (define_insn "*mulsi3_1_zext"
6480 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6481 (zero_extend:DI
6482 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6483 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6484 (clobber (reg:CC FLAGS_REG))]
6485 "TARGET_64BIT
6486 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6487 "@
6488 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6489 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6490 imul{l}\t{%2, %k0|%k0, %2}"
6491 [(set_attr "type" "imul")
6492 (set_attr "prefix_0f" "0,0,1")
6493 (set (attr "athlon_decode")
6494 (cond [(eq_attr "cpu" "athlon")
6495 (const_string "vector")
6496 (eq_attr "alternative" "1")
6497 (const_string "vector")
6498 (and (eq_attr "alternative" "2")
6499 (match_operand 1 "memory_operand"))
6500 (const_string "vector")]
6501 (const_string "direct")))
6502 (set (attr "amdfam10_decode")
6503 (cond [(and (eq_attr "alternative" "0,1")
6504 (match_operand 1 "memory_operand"))
6505 (const_string "vector")]
6506 (const_string "direct")))
6507 (set_attr "bdver1_decode" "direct")
6508 (set_attr "mode" "SI")])
6509
6510 ;; On AMDFAM10
6511 ;; IMUL reg16, reg16, imm8 VectorPath
6512 ;; IMUL reg16, mem16, imm8 VectorPath
6513 ;; IMUL reg16, reg16, imm16 VectorPath
6514 ;; IMUL reg16, mem16, imm16 VectorPath
6515 ;; IMUL reg16, reg16 Direct
6516 ;; IMUL reg16, mem16 Direct
6517 ;;
6518 ;; On BDVER1, all HI MULs use DoublePath
6519
6520 (define_insn "*mulhi3_1"
6521 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6522 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6523 (match_operand:HI 2 "general_operand" "K,n,mr")))
6524 (clobber (reg:CC FLAGS_REG))]
6525 "TARGET_HIMODE_MATH
6526 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6527 "@
6528 imul{w}\t{%2, %1, %0|%0, %1, %2}
6529 imul{w}\t{%2, %1, %0|%0, %1, %2}
6530 imul{w}\t{%2, %0|%0, %2}"
6531 [(set_attr "type" "imul")
6532 (set_attr "prefix_0f" "0,0,1")
6533 (set (attr "athlon_decode")
6534 (cond [(eq_attr "cpu" "athlon")
6535 (const_string "vector")
6536 (eq_attr "alternative" "1,2")
6537 (const_string "vector")]
6538 (const_string "direct")))
6539 (set (attr "amdfam10_decode")
6540 (cond [(eq_attr "alternative" "0,1")
6541 (const_string "vector")]
6542 (const_string "direct")))
6543 (set_attr "bdver1_decode" "double")
6544 (set_attr "mode" "HI")])
6545
6546 ;;On AMDFAM10 and BDVER1
6547 ;; MUL reg8 Direct
6548 ;; MUL mem8 Direct
6549
6550 (define_insn "*mulqi3_1"
6551 [(set (match_operand:QI 0 "register_operand" "=a")
6552 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6553 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6554 (clobber (reg:CC FLAGS_REG))]
6555 "TARGET_QIMODE_MATH
6556 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6557 "mul{b}\t%2"
6558 [(set_attr "type" "imul")
6559 (set_attr "length_immediate" "0")
6560 (set (attr "athlon_decode")
6561 (if_then_else (eq_attr "cpu" "athlon")
6562 (const_string "vector")
6563 (const_string "direct")))
6564 (set_attr "amdfam10_decode" "direct")
6565 (set_attr "bdver1_decode" "direct")
6566 (set_attr "mode" "QI")])
6567
6568 ;; Multiply with jump on overflow.
6569 (define_expand "mulv<mode>4"
6570 [(parallel [(set (reg:CCO FLAGS_REG)
6571 (eq:CCO (mult:<DWI>
6572 (sign_extend:<DWI>
6573 (match_operand:SWI48 1 "register_operand"))
6574 (match_dup 4))
6575 (sign_extend:<DWI>
6576 (mult:SWI48 (match_dup 1)
6577 (match_operand:SWI48 2
6578 "<general_operand>")))))
6579 (set (match_operand:SWI48 0 "register_operand")
6580 (mult:SWI48 (match_dup 1) (match_dup 2)))])
6581 (set (pc) (if_then_else
6582 (eq (reg:CCO FLAGS_REG) (const_int 0))
6583 (label_ref (match_operand 3))
6584 (pc)))]
6585 ""
6586 {
6587 if (CONST_INT_P (operands[2]))
6588 operands[4] = operands[2];
6589 else
6590 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6591 })
6592
6593 (define_insn "*mulv<mode>4"
6594 [(set (reg:CCO FLAGS_REG)
6595 (eq:CCO (mult:<DWI>
6596 (sign_extend:<DWI>
6597 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6598 (sign_extend:<DWI>
6599 (match_operand:SWI48 2 "<general_sext_operand>"
6600 "We,mr")))
6601 (sign_extend:<DWI>
6602 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6603 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6604 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6605 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6606 "@
6607 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6608 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6609 [(set_attr "type" "imul")
6610 (set_attr "prefix_0f" "0,1")
6611 (set (attr "athlon_decode")
6612 (cond [(eq_attr "cpu" "athlon")
6613 (const_string "vector")
6614 (eq_attr "alternative" "0")
6615 (const_string "vector")
6616 (and (eq_attr "alternative" "1")
6617 (match_operand 1 "memory_operand"))
6618 (const_string "vector")]
6619 (const_string "direct")))
6620 (set (attr "amdfam10_decode")
6621 (cond [(and (eq_attr "alternative" "1")
6622 (match_operand 1 "memory_operand"))
6623 (const_string "vector")]
6624 (const_string "direct")))
6625 (set_attr "bdver1_decode" "direct")
6626 (set_attr "mode" "<MODE>")])
6627
6628 (define_insn "*mulv<mode>4_1"
6629 [(set (reg:CCO FLAGS_REG)
6630 (eq:CCO (mult:<DWI>
6631 (sign_extend:<DWI>
6632 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6633 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6634 (sign_extend:<DWI>
6635 (mult:SWI48 (match_dup 1)
6636 (match_operand:SWI 2 "x86_64_immediate_operand"
6637 "K,<i>")))))
6638 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6639 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6640 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6641 && CONST_INT_P (operands[2])
6642 && INTVAL (operands[2]) == INTVAL (operands[3])"
6643 "@
6644 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6645 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6646 [(set_attr "type" "imul")
6647 (set (attr "athlon_decode")
6648 (cond [(eq_attr "cpu" "athlon")
6649 (const_string "vector")
6650 (eq_attr "alternative" "1")
6651 (const_string "vector")]
6652 (const_string "direct")))
6653 (set (attr "amdfam10_decode")
6654 (cond [(match_operand 1 "memory_operand")
6655 (const_string "vector")]
6656 (const_string "direct")))
6657 (set_attr "bdver1_decode" "direct")
6658 (set_attr "mode" "<MODE>")
6659 (set (attr "length_immediate")
6660 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6661 (const_string "1")
6662 (match_test "<MODE_SIZE> == 8")
6663 (const_string "4")]
6664 (const_string "<MODE_SIZE>")))])
6665
6666 (define_expand "<u>mul<mode><dwi>3"
6667 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6668 (mult:<DWI>
6669 (any_extend:<DWI>
6670 (match_operand:DWIH 1 "nonimmediate_operand"))
6671 (any_extend:<DWI>
6672 (match_operand:DWIH 2 "register_operand"))))
6673 (clobber (reg:CC FLAGS_REG))])])
6674
6675 (define_expand "<u>mulqihi3"
6676 [(parallel [(set (match_operand:HI 0 "register_operand")
6677 (mult:HI
6678 (any_extend:HI
6679 (match_operand:QI 1 "nonimmediate_operand"))
6680 (any_extend:HI
6681 (match_operand:QI 2 "register_operand"))))
6682 (clobber (reg:CC FLAGS_REG))])]
6683 "TARGET_QIMODE_MATH")
6684
6685 (define_insn "*bmi2_umulditi3_1"
6686 [(set (match_operand:DI 0 "register_operand" "=r")
6687 (mult:DI
6688 (match_operand:DI 2 "nonimmediate_operand" "%d")
6689 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6690 (set (match_operand:DI 1 "register_operand" "=r")
6691 (truncate:DI
6692 (lshiftrt:TI
6693 (mult:TI (zero_extend:TI (match_dup 2))
6694 (zero_extend:TI (match_dup 3)))
6695 (const_int 64))))]
6696 "TARGET_64BIT && TARGET_BMI2
6697 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6698 "mulx\t{%3, %0, %1|%1, %0, %3}"
6699 [(set_attr "type" "imulx")
6700 (set_attr "prefix" "vex")
6701 (set_attr "mode" "DI")])
6702
6703 (define_insn "*bmi2_umulsidi3_1"
6704 [(set (match_operand:SI 0 "register_operand" "=r")
6705 (mult:SI
6706 (match_operand:SI 2 "nonimmediate_operand" "%d")
6707 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6708 (set (match_operand:SI 1 "register_operand" "=r")
6709 (truncate:SI
6710 (lshiftrt:DI
6711 (mult:DI (zero_extend:DI (match_dup 2))
6712 (zero_extend:DI (match_dup 3)))
6713 (const_int 32))))]
6714 "!TARGET_64BIT && TARGET_BMI2
6715 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6716 "mulx\t{%3, %0, %1|%1, %0, %3}"
6717 [(set_attr "type" "imulx")
6718 (set_attr "prefix" "vex")
6719 (set_attr "mode" "SI")])
6720
6721 (define_insn "*umul<mode><dwi>3_1"
6722 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6723 (mult:<DWI>
6724 (zero_extend:<DWI>
6725 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6726 (zero_extend:<DWI>
6727 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6728 (clobber (reg:CC FLAGS_REG))]
6729 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6730 "@
6731 #
6732 mul{<imodesuffix>}\t%2"
6733 [(set_attr "isa" "bmi2,*")
6734 (set_attr "type" "imulx,imul")
6735 (set_attr "length_immediate" "*,0")
6736 (set (attr "athlon_decode")
6737 (cond [(eq_attr "alternative" "1")
6738 (if_then_else (eq_attr "cpu" "athlon")
6739 (const_string "vector")
6740 (const_string "double"))]
6741 (const_string "*")))
6742 (set_attr "amdfam10_decode" "*,double")
6743 (set_attr "bdver1_decode" "*,direct")
6744 (set_attr "prefix" "vex,orig")
6745 (set_attr "mode" "<MODE>")])
6746
6747 ;; Convert mul to the mulx pattern to avoid flags dependency.
6748 (define_split
6749 [(set (match_operand:<DWI> 0 "register_operand")
6750 (mult:<DWI>
6751 (zero_extend:<DWI>
6752 (match_operand:DWIH 1 "register_operand"))
6753 (zero_extend:<DWI>
6754 (match_operand:DWIH 2 "nonimmediate_operand"))))
6755 (clobber (reg:CC FLAGS_REG))]
6756 "TARGET_BMI2 && reload_completed
6757 && true_regnum (operands[1]) == DX_REG"
6758 [(parallel [(set (match_dup 3)
6759 (mult:DWIH (match_dup 1) (match_dup 2)))
6760 (set (match_dup 4)
6761 (truncate:DWIH
6762 (lshiftrt:<DWI>
6763 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6764 (zero_extend:<DWI> (match_dup 2)))
6765 (match_dup 5))))])]
6766 {
6767 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6768
6769 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6770 })
6771
6772 (define_insn "*mul<mode><dwi>3_1"
6773 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6774 (mult:<DWI>
6775 (sign_extend:<DWI>
6776 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6777 (sign_extend:<DWI>
6778 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6779 (clobber (reg:CC FLAGS_REG))]
6780 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6781 "imul{<imodesuffix>}\t%2"
6782 [(set_attr "type" "imul")
6783 (set_attr "length_immediate" "0")
6784 (set (attr "athlon_decode")
6785 (if_then_else (eq_attr "cpu" "athlon")
6786 (const_string "vector")
6787 (const_string "double")))
6788 (set_attr "amdfam10_decode" "double")
6789 (set_attr "bdver1_decode" "direct")
6790 (set_attr "mode" "<MODE>")])
6791
6792 (define_insn "*<u>mulqihi3_1"
6793 [(set (match_operand:HI 0 "register_operand" "=a")
6794 (mult:HI
6795 (any_extend:HI
6796 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6797 (any_extend:HI
6798 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6799 (clobber (reg:CC FLAGS_REG))]
6800 "TARGET_QIMODE_MATH
6801 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6802 "<sgnprefix>mul{b}\t%2"
6803 [(set_attr "type" "imul")
6804 (set_attr "length_immediate" "0")
6805 (set (attr "athlon_decode")
6806 (if_then_else (eq_attr "cpu" "athlon")
6807 (const_string "vector")
6808 (const_string "direct")))
6809 (set_attr "amdfam10_decode" "direct")
6810 (set_attr "bdver1_decode" "direct")
6811 (set_attr "mode" "QI")])
6812
6813 (define_expand "<s>mul<mode>3_highpart"
6814 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6815 (truncate:SWI48
6816 (lshiftrt:<DWI>
6817 (mult:<DWI>
6818 (any_extend:<DWI>
6819 (match_operand:SWI48 1 "nonimmediate_operand"))
6820 (any_extend:<DWI>
6821 (match_operand:SWI48 2 "register_operand")))
6822 (match_dup 4))))
6823 (clobber (match_scratch:SWI48 3))
6824 (clobber (reg:CC FLAGS_REG))])]
6825 ""
6826 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6827
6828 (define_insn "*<s>muldi3_highpart_1"
6829 [(set (match_operand:DI 0 "register_operand" "=d")
6830 (truncate:DI
6831 (lshiftrt:TI
6832 (mult:TI
6833 (any_extend:TI
6834 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6835 (any_extend:TI
6836 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6837 (const_int 64))))
6838 (clobber (match_scratch:DI 3 "=1"))
6839 (clobber (reg:CC FLAGS_REG))]
6840 "TARGET_64BIT
6841 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6842 "<sgnprefix>mul{q}\t%2"
6843 [(set_attr "type" "imul")
6844 (set_attr "length_immediate" "0")
6845 (set (attr "athlon_decode")
6846 (if_then_else (eq_attr "cpu" "athlon")
6847 (const_string "vector")
6848 (const_string "double")))
6849 (set_attr "amdfam10_decode" "double")
6850 (set_attr "bdver1_decode" "direct")
6851 (set_attr "mode" "DI")])
6852
6853 (define_insn "*<s>mulsi3_highpart_1"
6854 [(set (match_operand:SI 0 "register_operand" "=d")
6855 (truncate:SI
6856 (lshiftrt:DI
6857 (mult:DI
6858 (any_extend:DI
6859 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6860 (any_extend:DI
6861 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6862 (const_int 32))))
6863 (clobber (match_scratch:SI 3 "=1"))
6864 (clobber (reg:CC FLAGS_REG))]
6865 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6866 "<sgnprefix>mul{l}\t%2"
6867 [(set_attr "type" "imul")
6868 (set_attr "length_immediate" "0")
6869 (set (attr "athlon_decode")
6870 (if_then_else (eq_attr "cpu" "athlon")
6871 (const_string "vector")
6872 (const_string "double")))
6873 (set_attr "amdfam10_decode" "double")
6874 (set_attr "bdver1_decode" "direct")
6875 (set_attr "mode" "SI")])
6876
6877 (define_insn "*<s>mulsi3_highpart_zext"
6878 [(set (match_operand:DI 0 "register_operand" "=d")
6879 (zero_extend:DI (truncate:SI
6880 (lshiftrt:DI
6881 (mult:DI (any_extend:DI
6882 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6883 (any_extend:DI
6884 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6885 (const_int 32)))))
6886 (clobber (match_scratch:SI 3 "=1"))
6887 (clobber (reg:CC FLAGS_REG))]
6888 "TARGET_64BIT
6889 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6890 "<sgnprefix>mul{l}\t%2"
6891 [(set_attr "type" "imul")
6892 (set_attr "length_immediate" "0")
6893 (set (attr "athlon_decode")
6894 (if_then_else (eq_attr "cpu" "athlon")
6895 (const_string "vector")
6896 (const_string "double")))
6897 (set_attr "amdfam10_decode" "double")
6898 (set_attr "bdver1_decode" "direct")
6899 (set_attr "mode" "SI")])
6900
6901 ;; The patterns that match these are at the end of this file.
6902
6903 (define_expand "mulxf3"
6904 [(set (match_operand:XF 0 "register_operand")
6905 (mult:XF (match_operand:XF 1 "register_operand")
6906 (match_operand:XF 2 "register_operand")))]
6907 "TARGET_80387")
6908
6909 (define_expand "mul<mode>3"
6910 [(set (match_operand:MODEF 0 "register_operand")
6911 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6912 (match_operand:MODEF 2 "nonimmediate_operand")))]
6913 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6914 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6915 \f
6916 ;; Divide instructions
6917
6918 ;; The patterns that match these are at the end of this file.
6919
6920 (define_expand "divxf3"
6921 [(set (match_operand:XF 0 "register_operand")
6922 (div:XF (match_operand:XF 1 "register_operand")
6923 (match_operand:XF 2 "register_operand")))]
6924 "TARGET_80387")
6925
6926 (define_expand "divdf3"
6927 [(set (match_operand:DF 0 "register_operand")
6928 (div:DF (match_operand:DF 1 "register_operand")
6929 (match_operand:DF 2 "nonimmediate_operand")))]
6930 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6931 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6932
6933 (define_expand "divsf3"
6934 [(set (match_operand:SF 0 "register_operand")
6935 (div:SF (match_operand:SF 1 "register_operand")
6936 (match_operand:SF 2 "nonimmediate_operand")))]
6937 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6938 || TARGET_SSE_MATH"
6939 {
6940 if (TARGET_SSE_MATH
6941 && TARGET_RECIP_DIV
6942 && optimize_insn_for_speed_p ()
6943 && flag_finite_math_only && !flag_trapping_math
6944 && flag_unsafe_math_optimizations)
6945 {
6946 ix86_emit_swdivsf (operands[0], operands[1],
6947 operands[2], SFmode);
6948 DONE;
6949 }
6950 })
6951 \f
6952 ;; Divmod instructions.
6953
6954 (define_expand "divmod<mode>4"
6955 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6956 (div:SWIM248
6957 (match_operand:SWIM248 1 "register_operand")
6958 (match_operand:SWIM248 2 "nonimmediate_operand")))
6959 (set (match_operand:SWIM248 3 "register_operand")
6960 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6961 (clobber (reg:CC FLAGS_REG))])])
6962
6963 ;; Split with 8bit unsigned divide:
6964 ;; if (dividend an divisor are in [0-255])
6965 ;; use 8bit unsigned integer divide
6966 ;; else
6967 ;; use original integer divide
6968 (define_split
6969 [(set (match_operand:SWI48 0 "register_operand")
6970 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6971 (match_operand:SWI48 3 "nonimmediate_operand")))
6972 (set (match_operand:SWI48 1 "register_operand")
6973 (mod:SWI48 (match_dup 2) (match_dup 3)))
6974 (clobber (reg:CC FLAGS_REG))]
6975 "TARGET_USE_8BIT_IDIV
6976 && TARGET_QIMODE_MATH
6977 && can_create_pseudo_p ()
6978 && !optimize_insn_for_size_p ()"
6979 [(const_int 0)]
6980 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6981
6982 (define_insn_and_split "divmod<mode>4_1"
6983 [(set (match_operand:SWI48 0 "register_operand" "=a")
6984 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6985 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6986 (set (match_operand:SWI48 1 "register_operand" "=&d")
6987 (mod:SWI48 (match_dup 2) (match_dup 3)))
6988 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6989 (clobber (reg:CC FLAGS_REG))]
6990 ""
6991 "#"
6992 "reload_completed"
6993 [(parallel [(set (match_dup 1)
6994 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6995 (clobber (reg:CC FLAGS_REG))])
6996 (parallel [(set (match_dup 0)
6997 (div:SWI48 (match_dup 2) (match_dup 3)))
6998 (set (match_dup 1)
6999 (mod:SWI48 (match_dup 2) (match_dup 3)))
7000 (use (match_dup 1))
7001 (clobber (reg:CC FLAGS_REG))])]
7002 {
7003 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7004
7005 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7006 operands[4] = operands[2];
7007 else
7008 {
7009 /* Avoid use of cltd in favor of a mov+shift. */
7010 emit_move_insn (operands[1], operands[2]);
7011 operands[4] = operands[1];
7012 }
7013 }
7014 [(set_attr "type" "multi")
7015 (set_attr "mode" "<MODE>")])
7016
7017 (define_insn_and_split "*divmod<mode>4"
7018 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7019 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7020 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7021 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7022 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7023 (clobber (reg:CC FLAGS_REG))]
7024 ""
7025 "#"
7026 "reload_completed"
7027 [(parallel [(set (match_dup 1)
7028 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7029 (clobber (reg:CC FLAGS_REG))])
7030 (parallel [(set (match_dup 0)
7031 (div:SWIM248 (match_dup 2) (match_dup 3)))
7032 (set (match_dup 1)
7033 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7034 (use (match_dup 1))
7035 (clobber (reg:CC FLAGS_REG))])]
7036 {
7037 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7038
7039 if (<MODE>mode != HImode
7040 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7041 operands[4] = operands[2];
7042 else
7043 {
7044 /* Avoid use of cltd in favor of a mov+shift. */
7045 emit_move_insn (operands[1], operands[2]);
7046 operands[4] = operands[1];
7047 }
7048 }
7049 [(set_attr "type" "multi")
7050 (set_attr "mode" "<MODE>")])
7051
7052 (define_insn "*divmod<mode>4_noext"
7053 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7054 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7055 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7056 (set (match_operand:SWIM248 1 "register_operand" "=d")
7057 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7058 (use (match_operand:SWIM248 4 "register_operand" "1"))
7059 (clobber (reg:CC FLAGS_REG))]
7060 ""
7061 "idiv{<imodesuffix>}\t%3"
7062 [(set_attr "type" "idiv")
7063 (set_attr "mode" "<MODE>")])
7064
7065 (define_expand "divmodqi4"
7066 [(parallel [(set (match_operand:QI 0 "register_operand")
7067 (div:QI
7068 (match_operand:QI 1 "register_operand")
7069 (match_operand:QI 2 "nonimmediate_operand")))
7070 (set (match_operand:QI 3 "register_operand")
7071 (mod:QI (match_dup 1) (match_dup 2)))
7072 (clobber (reg:CC FLAGS_REG))])]
7073 "TARGET_QIMODE_MATH"
7074 {
7075 rtx div, mod, insn;
7076 rtx tmp0, tmp1;
7077
7078 tmp0 = gen_reg_rtx (HImode);
7079 tmp1 = gen_reg_rtx (HImode);
7080
7081 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7082 in AX. */
7083 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7084 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7085
7086 /* Extract remainder from AH. */
7087 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7088 insn = emit_move_insn (operands[3], tmp1);
7089
7090 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7091 set_unique_reg_note (insn, REG_EQUAL, mod);
7092
7093 /* Extract quotient from AL. */
7094 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7095
7096 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7097 set_unique_reg_note (insn, REG_EQUAL, div);
7098
7099 DONE;
7100 })
7101
7102 ;; Divide AX by r/m8, with result stored in
7103 ;; AL <- Quotient
7104 ;; AH <- Remainder
7105 ;; Change div/mod to HImode and extend the second argument to HImode
7106 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7107 ;; combine may fail.
7108 (define_insn "divmodhiqi3"
7109 [(set (match_operand:HI 0 "register_operand" "=a")
7110 (ior:HI
7111 (ashift:HI
7112 (zero_extend:HI
7113 (truncate:QI
7114 (mod:HI (match_operand:HI 1 "register_operand" "0")
7115 (sign_extend:HI
7116 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7117 (const_int 8))
7118 (zero_extend:HI
7119 (truncate:QI
7120 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7121 (clobber (reg:CC FLAGS_REG))]
7122 "TARGET_QIMODE_MATH"
7123 "idiv{b}\t%2"
7124 [(set_attr "type" "idiv")
7125 (set_attr "mode" "QI")])
7126
7127 (define_expand "udivmod<mode>4"
7128 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7129 (udiv:SWIM248
7130 (match_operand:SWIM248 1 "register_operand")
7131 (match_operand:SWIM248 2 "nonimmediate_operand")))
7132 (set (match_operand:SWIM248 3 "register_operand")
7133 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7134 (clobber (reg:CC FLAGS_REG))])])
7135
7136 ;; Split with 8bit unsigned divide:
7137 ;; if (dividend an divisor are in [0-255])
7138 ;; use 8bit unsigned integer divide
7139 ;; else
7140 ;; use original integer divide
7141 (define_split
7142 [(set (match_operand:SWI48 0 "register_operand")
7143 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7144 (match_operand:SWI48 3 "nonimmediate_operand")))
7145 (set (match_operand:SWI48 1 "register_operand")
7146 (umod:SWI48 (match_dup 2) (match_dup 3)))
7147 (clobber (reg:CC FLAGS_REG))]
7148 "TARGET_USE_8BIT_IDIV
7149 && TARGET_QIMODE_MATH
7150 && can_create_pseudo_p ()
7151 && !optimize_insn_for_size_p ()"
7152 [(const_int 0)]
7153 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7154
7155 (define_insn_and_split "udivmod<mode>4_1"
7156 [(set (match_operand:SWI48 0 "register_operand" "=a")
7157 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7158 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7159 (set (match_operand:SWI48 1 "register_operand" "=&d")
7160 (umod:SWI48 (match_dup 2) (match_dup 3)))
7161 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7162 (clobber (reg:CC FLAGS_REG))]
7163 ""
7164 "#"
7165 "reload_completed"
7166 [(set (match_dup 1) (const_int 0))
7167 (parallel [(set (match_dup 0)
7168 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7169 (set (match_dup 1)
7170 (umod:SWI48 (match_dup 2) (match_dup 3)))
7171 (use (match_dup 1))
7172 (clobber (reg:CC FLAGS_REG))])]
7173 ""
7174 [(set_attr "type" "multi")
7175 (set_attr "mode" "<MODE>")])
7176
7177 (define_insn_and_split "*udivmod<mode>4"
7178 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7179 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7180 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7181 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7182 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7183 (clobber (reg:CC FLAGS_REG))]
7184 ""
7185 "#"
7186 "reload_completed"
7187 [(set (match_dup 1) (const_int 0))
7188 (parallel [(set (match_dup 0)
7189 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7190 (set (match_dup 1)
7191 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7192 (use (match_dup 1))
7193 (clobber (reg:CC FLAGS_REG))])]
7194 ""
7195 [(set_attr "type" "multi")
7196 (set_attr "mode" "<MODE>")])
7197
7198 (define_insn "*udivmod<mode>4_noext"
7199 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7200 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7201 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7202 (set (match_operand:SWIM248 1 "register_operand" "=d")
7203 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7204 (use (match_operand:SWIM248 4 "register_operand" "1"))
7205 (clobber (reg:CC FLAGS_REG))]
7206 ""
7207 "div{<imodesuffix>}\t%3"
7208 [(set_attr "type" "idiv")
7209 (set_attr "mode" "<MODE>")])
7210
7211 (define_expand "udivmodqi4"
7212 [(parallel [(set (match_operand:QI 0 "register_operand")
7213 (udiv:QI
7214 (match_operand:QI 1 "register_operand")
7215 (match_operand:QI 2 "nonimmediate_operand")))
7216 (set (match_operand:QI 3 "register_operand")
7217 (umod:QI (match_dup 1) (match_dup 2)))
7218 (clobber (reg:CC FLAGS_REG))])]
7219 "TARGET_QIMODE_MATH"
7220 {
7221 rtx div, mod, insn;
7222 rtx tmp0, tmp1;
7223
7224 tmp0 = gen_reg_rtx (HImode);
7225 tmp1 = gen_reg_rtx (HImode);
7226
7227 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7228 in AX. */
7229 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7230 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7231
7232 /* Extract remainder from AH. */
7233 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7234 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7235 insn = emit_move_insn (operands[3], tmp1);
7236
7237 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7238 set_unique_reg_note (insn, REG_EQUAL, mod);
7239
7240 /* Extract quotient from AL. */
7241 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7242
7243 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7244 set_unique_reg_note (insn, REG_EQUAL, div);
7245
7246 DONE;
7247 })
7248
7249 (define_insn "udivmodhiqi3"
7250 [(set (match_operand:HI 0 "register_operand" "=a")
7251 (ior:HI
7252 (ashift:HI
7253 (zero_extend:HI
7254 (truncate:QI
7255 (mod:HI (match_operand:HI 1 "register_operand" "0")
7256 (zero_extend:HI
7257 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7258 (const_int 8))
7259 (zero_extend:HI
7260 (truncate:QI
7261 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7262 (clobber (reg:CC FLAGS_REG))]
7263 "TARGET_QIMODE_MATH"
7264 "div{b}\t%2"
7265 [(set_attr "type" "idiv")
7266 (set_attr "mode" "QI")])
7267
7268 ;; We cannot use div/idiv for double division, because it causes
7269 ;; "division by zero" on the overflow and that's not what we expect
7270 ;; from truncate. Because true (non truncating) double division is
7271 ;; never generated, we can't create this insn anyway.
7272 ;
7273 ;(define_insn ""
7274 ; [(set (match_operand:SI 0 "register_operand" "=a")
7275 ; (truncate:SI
7276 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7277 ; (zero_extend:DI
7278 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7279 ; (set (match_operand:SI 3 "register_operand" "=d")
7280 ; (truncate:SI
7281 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7282 ; (clobber (reg:CC FLAGS_REG))]
7283 ; ""
7284 ; "div{l}\t{%2, %0|%0, %2}"
7285 ; [(set_attr "type" "idiv")])
7286 \f
7287 ;;- Logical AND instructions
7288
7289 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7290 ;; Note that this excludes ah.
7291
7292 (define_expand "testsi_ccno_1"
7293 [(set (reg:CCNO FLAGS_REG)
7294 (compare:CCNO
7295 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7296 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7297 (const_int 0)))])
7298
7299 (define_expand "testqi_ccz_1"
7300 [(set (reg:CCZ FLAGS_REG)
7301 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7302 (match_operand:QI 1 "nonmemory_operand"))
7303 (const_int 0)))])
7304
7305 (define_expand "testdi_ccno_1"
7306 [(set (reg:CCNO FLAGS_REG)
7307 (compare:CCNO
7308 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7309 (match_operand:DI 1 "x86_64_szext_general_operand"))
7310 (const_int 0)))]
7311 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7312
7313 (define_insn "*testdi_1"
7314 [(set (reg FLAGS_REG)
7315 (compare
7316 (and:DI
7317 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7318 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7319 (const_int 0)))]
7320 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7321 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7322 "@
7323 test{l}\t{%k1, %k0|%k0, %k1}
7324 test{l}\t{%k1, %k0|%k0, %k1}
7325 test{q}\t{%1, %0|%0, %1}
7326 test{q}\t{%1, %0|%0, %1}
7327 test{q}\t{%1, %0|%0, %1}"
7328 [(set_attr "type" "test")
7329 (set_attr "modrm" "0,1,0,1,1")
7330 (set_attr "mode" "SI,SI,DI,DI,DI")])
7331
7332 (define_insn "*testqi_1_maybe_si"
7333 [(set (reg FLAGS_REG)
7334 (compare
7335 (and:QI
7336 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7337 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7338 (const_int 0)))]
7339 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7340 && ix86_match_ccmode (insn,
7341 CONST_INT_P (operands[1])
7342 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7343 {
7344 if (which_alternative == 3)
7345 {
7346 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7347 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7348 return "test{l}\t{%1, %k0|%k0, %1}";
7349 }
7350 return "test{b}\t{%1, %0|%0, %1}";
7351 }
7352 [(set_attr "type" "test")
7353 (set_attr "modrm" "0,1,1,1")
7354 (set_attr "mode" "QI,QI,QI,SI")
7355 (set_attr "pent_pair" "uv,np,uv,np")])
7356
7357 (define_insn "*test<mode>_1"
7358 [(set (reg FLAGS_REG)
7359 (compare
7360 (and:SWI124
7361 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7362 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7363 (const_int 0)))]
7364 "ix86_match_ccmode (insn, CCNOmode)
7365 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7366 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7367 [(set_attr "type" "test")
7368 (set_attr "modrm" "0,1,1")
7369 (set_attr "mode" "<MODE>")
7370 (set_attr "pent_pair" "uv,np,uv")])
7371
7372 (define_expand "testqi_ext_ccno_0"
7373 [(set (reg:CCNO FLAGS_REG)
7374 (compare:CCNO
7375 (and:SI
7376 (zero_extract:SI
7377 (match_operand 0 "ext_register_operand")
7378 (const_int 8)
7379 (const_int 8))
7380 (match_operand 1 "const_int_operand"))
7381 (const_int 0)))])
7382
7383 (define_insn "*testqi_ext_0"
7384 [(set (reg FLAGS_REG)
7385 (compare
7386 (and:SI
7387 (zero_extract:SI
7388 (match_operand 0 "ext_register_operand" "Q")
7389 (const_int 8)
7390 (const_int 8))
7391 (match_operand 1 "const_int_operand" "n"))
7392 (const_int 0)))]
7393 "ix86_match_ccmode (insn, CCNOmode)"
7394 "test{b}\t{%1, %h0|%h0, %1}"
7395 [(set_attr "type" "test")
7396 (set_attr "mode" "QI")
7397 (set_attr "length_immediate" "1")
7398 (set_attr "modrm" "1")
7399 (set_attr "pent_pair" "np")])
7400
7401 (define_insn "*testqi_ext_1"
7402 [(set (reg FLAGS_REG)
7403 (compare
7404 (and:SI
7405 (zero_extract:SI
7406 (match_operand 0 "ext_register_operand" "Q,Q")
7407 (const_int 8)
7408 (const_int 8))
7409 (zero_extend:SI
7410 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7411 (const_int 0)))]
7412 "ix86_match_ccmode (insn, CCNOmode)"
7413 "test{b}\t{%1, %h0|%h0, %1}"
7414 [(set_attr "isa" "*,nox64")
7415 (set_attr "type" "test")
7416 (set_attr "mode" "QI")])
7417
7418 (define_insn "*testqi_ext_2"
7419 [(set (reg FLAGS_REG)
7420 (compare
7421 (and:SI
7422 (zero_extract:SI
7423 (match_operand 0 "ext_register_operand" "Q")
7424 (const_int 8)
7425 (const_int 8))
7426 (zero_extract:SI
7427 (match_operand 1 "ext_register_operand" "Q")
7428 (const_int 8)
7429 (const_int 8)))
7430 (const_int 0)))]
7431 "ix86_match_ccmode (insn, CCNOmode)"
7432 "test{b}\t{%h1, %h0|%h0, %h1}"
7433 [(set_attr "type" "test")
7434 (set_attr "mode" "QI")])
7435
7436 ;; Combine likes to form bit extractions for some tests. Humor it.
7437 (define_insn "*testqi_ext_3"
7438 [(set (reg FLAGS_REG)
7439 (compare (zero_extract:SWI48
7440 (match_operand 0 "nonimmediate_operand" "rm")
7441 (match_operand:SWI48 1 "const_int_operand")
7442 (match_operand:SWI48 2 "const_int_operand"))
7443 (const_int 0)))]
7444 "ix86_match_ccmode (insn, CCNOmode)
7445 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7446 || GET_MODE (operands[0]) == SImode
7447 || GET_MODE (operands[0]) == HImode
7448 || GET_MODE (operands[0]) == QImode)
7449 /* Ensure that resulting mask is zero or sign extended operand. */
7450 && INTVAL (operands[2]) >= 0
7451 && ((INTVAL (operands[1]) > 0
7452 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7453 || (<MODE>mode == DImode
7454 && INTVAL (operands[1]) > 32
7455 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7456 "#")
7457
7458 (define_split
7459 [(set (match_operand 0 "flags_reg_operand")
7460 (match_operator 1 "compare_operator"
7461 [(zero_extract
7462 (match_operand 2 "nonimmediate_operand")
7463 (match_operand 3 "const_int_operand")
7464 (match_operand 4 "const_int_operand"))
7465 (const_int 0)]))]
7466 "ix86_match_ccmode (insn, CCNOmode)"
7467 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7468 {
7469 rtx val = operands[2];
7470 HOST_WIDE_INT len = INTVAL (operands[3]);
7471 HOST_WIDE_INT pos = INTVAL (operands[4]);
7472 HOST_WIDE_INT mask;
7473 machine_mode mode, submode;
7474
7475 mode = GET_MODE (val);
7476 if (MEM_P (val))
7477 {
7478 /* ??? Combine likes to put non-volatile mem extractions in QImode
7479 no matter the size of the test. So find a mode that works. */
7480 if (! MEM_VOLATILE_P (val))
7481 {
7482 mode = smallest_mode_for_size (pos + len, MODE_INT);
7483 val = adjust_address (val, mode, 0);
7484 }
7485 }
7486 else if (GET_CODE (val) == SUBREG
7487 && (submode = GET_MODE (SUBREG_REG (val)),
7488 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7489 && pos + len <= GET_MODE_BITSIZE (submode)
7490 && GET_MODE_CLASS (submode) == MODE_INT)
7491 {
7492 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7493 mode = submode;
7494 val = SUBREG_REG (val);
7495 }
7496 else if (mode == HImode && pos + len <= 8)
7497 {
7498 /* Small HImode tests can be converted to QImode. */
7499 mode = QImode;
7500 val = gen_lowpart (QImode, val);
7501 }
7502
7503 if (len == HOST_BITS_PER_WIDE_INT)
7504 mask = -1;
7505 else
7506 mask = ((HOST_WIDE_INT)1 << len) - 1;
7507 mask <<= pos;
7508
7509 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7510 })
7511
7512 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7513 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7514 ;; this is relatively important trick.
7515 ;; Do the conversion only post-reload to avoid limiting of the register class
7516 ;; to QI regs.
7517 (define_split
7518 [(set (match_operand 0 "flags_reg_operand")
7519 (match_operator 1 "compare_operator"
7520 [(and (match_operand 2 "register_operand")
7521 (match_operand 3 "const_int_operand"))
7522 (const_int 0)]))]
7523 "reload_completed
7524 && QI_REG_P (operands[2])
7525 && GET_MODE (operands[2]) != QImode
7526 && ((ix86_match_ccmode (insn, CCZmode)
7527 && !(INTVAL (operands[3]) & ~(255 << 8)))
7528 || (ix86_match_ccmode (insn, CCNOmode)
7529 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7530 [(set (match_dup 0)
7531 (match_op_dup 1
7532 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7533 (match_dup 3))
7534 (const_int 0)]))]
7535 {
7536 operands[2] = gen_lowpart (SImode, operands[2]);
7537 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7538 })
7539
7540 (define_split
7541 [(set (match_operand 0 "flags_reg_operand")
7542 (match_operator 1 "compare_operator"
7543 [(and (match_operand 2 "nonimmediate_operand")
7544 (match_operand 3 "const_int_operand"))
7545 (const_int 0)]))]
7546 "reload_completed
7547 && GET_MODE (operands[2]) != QImode
7548 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7549 && ((ix86_match_ccmode (insn, CCZmode)
7550 && !(INTVAL (operands[3]) & ~255))
7551 || (ix86_match_ccmode (insn, CCNOmode)
7552 && !(INTVAL (operands[3]) & ~127)))"
7553 [(set (match_dup 0)
7554 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7555 (const_int 0)]))]
7556 {
7557 operands[2] = gen_lowpart (QImode, operands[2]);
7558 operands[3] = gen_lowpart (QImode, operands[3]);
7559 })
7560
7561 (define_split
7562 [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7563 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7564 (match_operand:SWI1248x 2 "mask_reg_operand")))
7565 (clobber (reg:CC FLAGS_REG))]
7566 "TARGET_AVX512F && reload_completed"
7567 [(set (match_dup 0)
7568 (any_logic:SWI1248x (match_dup 1)
7569 (match_dup 2)))])
7570
7571 (define_insn "*k<logic><mode>"
7572 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7573 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7574 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7575 "TARGET_AVX512F"
7576 {
7577 if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7578 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7579 else
7580 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7581 }
7582 [(set_attr "mode" "<MODE>")
7583 (set_attr "type" "msklog")
7584 (set_attr "prefix" "vex")])
7585
7586 ;; %%% This used to optimize known byte-wide and operations to memory,
7587 ;; and sometimes to QImode registers. If this is considered useful,
7588 ;; it should be done with splitters.
7589
7590 (define_expand "and<mode>3"
7591 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7592 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7593 (match_operand:SWIM 2 "<general_szext_operand>")))]
7594 ""
7595 {
7596 machine_mode mode = <MODE>mode;
7597 rtx (*insn) (rtx, rtx);
7598
7599 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7600 {
7601 HOST_WIDE_INT ival = INTVAL (operands[2]);
7602
7603 if (ival == (HOST_WIDE_INT) 0xffffffff)
7604 mode = SImode;
7605 else if (ival == 0xffff)
7606 mode = HImode;
7607 else if (ival == 0xff)
7608 mode = QImode;
7609 }
7610
7611 if (mode == <MODE>mode)
7612 {
7613 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7614 DONE;
7615 }
7616
7617 if (<MODE>mode == DImode)
7618 insn = (mode == SImode)
7619 ? gen_zero_extendsidi2
7620 : (mode == HImode)
7621 ? gen_zero_extendhidi2
7622 : gen_zero_extendqidi2;
7623 else if (<MODE>mode == SImode)
7624 insn = (mode == HImode)
7625 ? gen_zero_extendhisi2
7626 : gen_zero_extendqisi2;
7627 else if (<MODE>mode == HImode)
7628 insn = gen_zero_extendqihi2;
7629 else
7630 gcc_unreachable ();
7631
7632 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7633 DONE;
7634 })
7635
7636 (define_insn "*anddi_1"
7637 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7638 (and:DI
7639 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7640 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7641 (clobber (reg:CC FLAGS_REG))]
7642 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7643 {
7644 switch (get_attr_type (insn))
7645 {
7646 case TYPE_IMOVX:
7647 return "#";
7648
7649 case TYPE_MSKLOG:
7650 return "kandq\t{%2, %1, %0|%0, %1, %2}";
7651
7652 default:
7653 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7654 if (get_attr_mode (insn) == MODE_SI)
7655 return "and{l}\t{%k2, %k0|%k0, %k2}";
7656 else
7657 return "and{q}\t{%2, %0|%0, %2}";
7658 }
7659 }
7660 [(set_attr "type" "alu,alu,alu,imovx,msklog")
7661 (set_attr "length_immediate" "*,*,*,0,0")
7662 (set (attr "prefix_rex")
7663 (if_then_else
7664 (and (eq_attr "type" "imovx")
7665 (and (match_test "INTVAL (operands[2]) == 0xff")
7666 (match_operand 1 "ext_QIreg_operand")))
7667 (const_string "1")
7668 (const_string "*")))
7669 (set_attr "mode" "SI,DI,DI,SI,DI")])
7670
7671 (define_insn "*andsi_1"
7672 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7673 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7674 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7675 (clobber (reg:CC FLAGS_REG))]
7676 "ix86_binary_operator_ok (AND, SImode, operands)"
7677 {
7678 switch (get_attr_type (insn))
7679 {
7680 case TYPE_IMOVX:
7681 return "#";
7682
7683 case TYPE_MSKLOG:
7684 return "kandd\t{%2, %1, %0|%0, %1, %2}";
7685
7686 default:
7687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7688 return "and{l}\t{%2, %0|%0, %2}";
7689 }
7690 }
7691 [(set_attr "type" "alu,alu,imovx,msklog")
7692 (set (attr "prefix_rex")
7693 (if_then_else
7694 (and (eq_attr "type" "imovx")
7695 (and (match_test "INTVAL (operands[2]) == 0xff")
7696 (match_operand 1 "ext_QIreg_operand")))
7697 (const_string "1")
7698 (const_string "*")))
7699 (set_attr "length_immediate" "*,*,0,0")
7700 (set_attr "mode" "SI")])
7701
7702 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7703 (define_insn "*andsi_1_zext"
7704 [(set (match_operand:DI 0 "register_operand" "=r")
7705 (zero_extend:DI
7706 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7707 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7708 (clobber (reg:CC FLAGS_REG))]
7709 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7710 "and{l}\t{%2, %k0|%k0, %2}"
7711 [(set_attr "type" "alu")
7712 (set_attr "mode" "SI")])
7713
7714 (define_insn "*andhi_1"
7715 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7716 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7717 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7718 (clobber (reg:CC FLAGS_REG))]
7719 "ix86_binary_operator_ok (AND, HImode, operands)"
7720 {
7721 switch (get_attr_type (insn))
7722 {
7723 case TYPE_IMOVX:
7724 return "#";
7725
7726 case TYPE_MSKLOG:
7727 return "kandw\t{%2, %1, %0|%0, %1, %2}";
7728
7729 default:
7730 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7731 return "and{w}\t{%2, %0|%0, %2}";
7732 }
7733 }
7734 [(set_attr "type" "alu,alu,imovx,msklog")
7735 (set_attr "length_immediate" "*,*,0,*")
7736 (set (attr "prefix_rex")
7737 (if_then_else
7738 (and (eq_attr "type" "imovx")
7739 (match_operand 1 "ext_QIreg_operand"))
7740 (const_string "1")
7741 (const_string "*")))
7742 (set_attr "mode" "HI,HI,SI,HI")])
7743
7744 ;; %%% Potential partial reg stall on alternative 2. What to do?
7745 (define_insn "*andqi_1"
7746 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7747 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7748 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7749 (clobber (reg:CC FLAGS_REG))]
7750 "ix86_binary_operator_ok (AND, QImode, operands)"
7751 {
7752 switch (which_alternative)
7753 {
7754 case 0:
7755 case 1:
7756 return "and{b}\t{%2, %0|%0, %2}";
7757 case 2:
7758 return "and{l}\t{%k2, %k0|%k0, %k2}";
7759 case 3:
7760 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7761 : "kandw\t{%2, %1, %0|%0, %1, %2}";
7762 default:
7763 gcc_unreachable ();
7764 }
7765 }
7766 [(set_attr "type" "alu,alu,alu,msklog")
7767 (set_attr "mode" "QI,QI,SI,HI")])
7768
7769 (define_insn "*andqi_1_slp"
7770 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7771 (and:QI (match_dup 0)
7772 (match_operand:QI 1 "general_operand" "qn,qmn")))
7773 (clobber (reg:CC FLAGS_REG))]
7774 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7775 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7776 "and{b}\t{%1, %0|%0, %1}"
7777 [(set_attr "type" "alu1")
7778 (set_attr "mode" "QI")])
7779
7780 (define_insn "kandn<mode>"
7781 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7782 (and:SWI12
7783 (not:SWI12
7784 (match_operand:SWI12 1 "register_operand" "r,0,k"))
7785 (match_operand:SWI12 2 "register_operand" "r,r,k")))
7786 (clobber (reg:CC FLAGS_REG))]
7787 "TARGET_AVX512F"
7788 {
7789 switch (which_alternative)
7790 {
7791 case 0:
7792 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7793 case 1:
7794 return "#";
7795 case 2:
7796 if (TARGET_AVX512DQ && <MODE>mode == QImode)
7797 return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7798 else
7799 return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7800 default:
7801 gcc_unreachable ();
7802 }
7803 }
7804 [(set_attr "isa" "bmi,*,avx512f")
7805 (set_attr "type" "bitmanip,*,msklog")
7806 (set_attr "prefix" "*,*,vex")
7807 (set_attr "btver2_decode" "direct,*,*")
7808 (set_attr "mode" "<MODE>")])
7809
7810 (define_split
7811 [(set (match_operand:SWI12 0 "general_reg_operand")
7812 (and:SWI12
7813 (not:SWI12
7814 (match_dup 0))
7815 (match_operand:SWI12 1 "general_reg_operand")))
7816 (clobber (reg:CC FLAGS_REG))]
7817 "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7818 [(set (match_dup 0)
7819 (not:HI (match_dup 0)))
7820 (parallel [(set (match_dup 0)
7821 (and:HI (match_dup 0)
7822 (match_dup 1)))
7823 (clobber (reg:CC FLAGS_REG))])])
7824
7825 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7826 (define_split
7827 [(set (match_operand:DI 0 "register_operand")
7828 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7829 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7830 (clobber (reg:CC FLAGS_REG))]
7831 "TARGET_64BIT"
7832 [(parallel [(set (match_dup 0)
7833 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7834 (clobber (reg:CC FLAGS_REG))])]
7835 "operands[2] = gen_lowpart (SImode, operands[2]);")
7836
7837 (define_split
7838 [(set (match_operand:SWI248 0 "register_operand")
7839 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7840 (match_operand:SWI248 2 "const_int_operand")))
7841 (clobber (reg:CC FLAGS_REG))]
7842 "reload_completed
7843 && true_regnum (operands[0]) != true_regnum (operands[1])"
7844 [(const_int 0)]
7845 {
7846 HOST_WIDE_INT ival = INTVAL (operands[2]);
7847 machine_mode mode;
7848 rtx (*insn) (rtx, rtx);
7849
7850 if (ival == (HOST_WIDE_INT) 0xffffffff)
7851 mode = SImode;
7852 else if (ival == 0xffff)
7853 mode = HImode;
7854 else
7855 {
7856 gcc_assert (ival == 0xff);
7857 mode = QImode;
7858 }
7859
7860 if (<MODE>mode == DImode)
7861 insn = (mode == SImode)
7862 ? gen_zero_extendsidi2
7863 : (mode == HImode)
7864 ? gen_zero_extendhidi2
7865 : gen_zero_extendqidi2;
7866 else
7867 {
7868 if (<MODE>mode != SImode)
7869 /* Zero extend to SImode to avoid partial register stalls. */
7870 operands[0] = gen_lowpart (SImode, operands[0]);
7871
7872 insn = (mode == HImode)
7873 ? gen_zero_extendhisi2
7874 : gen_zero_extendqisi2;
7875 }
7876 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7877 DONE;
7878 })
7879
7880 (define_split
7881 [(set (match_operand 0 "register_operand")
7882 (and (match_dup 0)
7883 (const_int -65536)))
7884 (clobber (reg:CC FLAGS_REG))]
7885 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7886 || optimize_function_for_size_p (cfun)"
7887 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7888 "operands[1] = gen_lowpart (HImode, operands[0]);")
7889
7890 (define_split
7891 [(set (match_operand 0 "ext_register_operand")
7892 (and (match_dup 0)
7893 (const_int -256)))
7894 (clobber (reg:CC FLAGS_REG))]
7895 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7896 && reload_completed"
7897 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7898 "operands[1] = gen_lowpart (QImode, operands[0]);")
7899
7900 (define_split
7901 [(set (match_operand 0 "ext_register_operand")
7902 (and (match_dup 0)
7903 (const_int -65281)))
7904 (clobber (reg:CC FLAGS_REG))]
7905 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7906 && reload_completed"
7907 [(parallel [(set (zero_extract:SI (match_dup 0)
7908 (const_int 8)
7909 (const_int 8))
7910 (xor:SI
7911 (zero_extract:SI (match_dup 0)
7912 (const_int 8)
7913 (const_int 8))
7914 (zero_extract:SI (match_dup 0)
7915 (const_int 8)
7916 (const_int 8))))
7917 (clobber (reg:CC FLAGS_REG))])]
7918 "operands[0] = gen_lowpart (SImode, operands[0]);")
7919
7920 (define_insn "*anddi_2"
7921 [(set (reg FLAGS_REG)
7922 (compare
7923 (and:DI
7924 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7925 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7926 (const_int 0)))
7927 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7928 (and:DI (match_dup 1) (match_dup 2)))]
7929 "TARGET_64BIT
7930 && ix86_match_ccmode
7931 (insn,
7932 /* If we are going to emit andl instead of andq, and the operands[2]
7933 constant might have the SImode sign bit set, make sure the sign
7934 flag isn't tested, because the instruction will set the sign flag
7935 based on bit 31 rather than bit 63. If it isn't CONST_INT,
7936 conservatively assume it might have bit 31 set. */
7937 (satisfies_constraint_Z (operands[2])
7938 && (!CONST_INT_P (operands[2])
7939 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7940 ? CCZmode : CCNOmode)
7941 && ix86_binary_operator_ok (AND, DImode, operands)"
7942 "@
7943 and{l}\t{%k2, %k0|%k0, %k2}
7944 and{q}\t{%2, %0|%0, %2}
7945 and{q}\t{%2, %0|%0, %2}"
7946 [(set_attr "type" "alu")
7947 (set_attr "mode" "SI,DI,DI")])
7948
7949 (define_insn "*andqi_2_maybe_si"
7950 [(set (reg FLAGS_REG)
7951 (compare (and:QI
7952 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7953 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7954 (const_int 0)))
7955 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7956 (and:QI (match_dup 1) (match_dup 2)))]
7957 "ix86_binary_operator_ok (AND, QImode, operands)
7958 && ix86_match_ccmode (insn,
7959 CONST_INT_P (operands[2])
7960 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7961 {
7962 if (which_alternative == 2)
7963 {
7964 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7965 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7966 return "and{l}\t{%2, %k0|%k0, %2}";
7967 }
7968 return "and{b}\t{%2, %0|%0, %2}";
7969 }
7970 [(set_attr "type" "alu")
7971 (set_attr "mode" "QI,QI,SI")])
7972
7973 (define_insn "*and<mode>_2"
7974 [(set (reg FLAGS_REG)
7975 (compare (and:SWI124
7976 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7977 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7978 (const_int 0)))
7979 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7980 (and:SWI124 (match_dup 1) (match_dup 2)))]
7981 "ix86_match_ccmode (insn, CCNOmode)
7982 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7983 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7984 [(set_attr "type" "alu")
7985 (set_attr "mode" "<MODE>")])
7986
7987 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7988 (define_insn "*andsi_2_zext"
7989 [(set (reg FLAGS_REG)
7990 (compare (and:SI
7991 (match_operand:SI 1 "nonimmediate_operand" "%0")
7992 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7993 (const_int 0)))
7994 (set (match_operand:DI 0 "register_operand" "=r")
7995 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7996 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7997 && ix86_binary_operator_ok (AND, SImode, operands)"
7998 "and{l}\t{%2, %k0|%k0, %2}"
7999 [(set_attr "type" "alu")
8000 (set_attr "mode" "SI")])
8001
8002 (define_insn "*andqi_2_slp"
8003 [(set (reg FLAGS_REG)
8004 (compare (and:QI
8005 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8006 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8007 (const_int 0)))
8008 (set (strict_low_part (match_dup 0))
8009 (and:QI (match_dup 0) (match_dup 1)))]
8010 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8011 && ix86_match_ccmode (insn, CCNOmode)
8012 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8013 "and{b}\t{%1, %0|%0, %1}"
8014 [(set_attr "type" "alu1")
8015 (set_attr "mode" "QI")])
8016
8017 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8018 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8019 ;; for a QImode operand, which of course failed.
8020 (define_insn "andqi_ext_0"
8021 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8022 (const_int 8)
8023 (const_int 8))
8024 (and:SI
8025 (zero_extract:SI
8026 (match_operand 1 "ext_register_operand" "0")
8027 (const_int 8)
8028 (const_int 8))
8029 (match_operand 2 "const_int_operand" "n")))
8030 (clobber (reg:CC FLAGS_REG))]
8031 ""
8032 "and{b}\t{%2, %h0|%h0, %2}"
8033 [(set_attr "type" "alu")
8034 (set_attr "length_immediate" "1")
8035 (set_attr "modrm" "1")
8036 (set_attr "mode" "QI")])
8037
8038 ;; Generated by peephole translating test to and. This shows up
8039 ;; often in fp comparisons.
8040 (define_insn "*andqi_ext_0_cc"
8041 [(set (reg FLAGS_REG)
8042 (compare
8043 (and:SI
8044 (zero_extract:SI
8045 (match_operand 1 "ext_register_operand" "0")
8046 (const_int 8)
8047 (const_int 8))
8048 (match_operand 2 "const_int_operand" "n"))
8049 (const_int 0)))
8050 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8051 (const_int 8)
8052 (const_int 8))
8053 (and:SI
8054 (zero_extract:SI
8055 (match_dup 1)
8056 (const_int 8)
8057 (const_int 8))
8058 (match_dup 2)))]
8059 "ix86_match_ccmode (insn, CCNOmode)"
8060 "and{b}\t{%2, %h0|%h0, %2}"
8061 [(set_attr "type" "alu")
8062 (set_attr "length_immediate" "1")
8063 (set_attr "modrm" "1")
8064 (set_attr "mode" "QI")])
8065
8066 (define_insn "*andqi_ext_1"
8067 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8068 (const_int 8)
8069 (const_int 8))
8070 (and:SI
8071 (zero_extract:SI
8072 (match_operand 1 "ext_register_operand" "0,0")
8073 (const_int 8)
8074 (const_int 8))
8075 (zero_extend:SI
8076 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8077 (clobber (reg:CC FLAGS_REG))]
8078 ""
8079 "and{b}\t{%2, %h0|%h0, %2}"
8080 [(set_attr "isa" "*,nox64")
8081 (set_attr "type" "alu")
8082 (set_attr "length_immediate" "0")
8083 (set_attr "mode" "QI")])
8084
8085 (define_insn "*andqi_ext_2"
8086 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8087 (const_int 8)
8088 (const_int 8))
8089 (and:SI
8090 (zero_extract:SI
8091 (match_operand 1 "ext_register_operand" "%0")
8092 (const_int 8)
8093 (const_int 8))
8094 (zero_extract:SI
8095 (match_operand 2 "ext_register_operand" "Q")
8096 (const_int 8)
8097 (const_int 8))))
8098 (clobber (reg:CC FLAGS_REG))]
8099 ""
8100 "and{b}\t{%h2, %h0|%h0, %h2}"
8101 [(set_attr "type" "alu")
8102 (set_attr "length_immediate" "0")
8103 (set_attr "mode" "QI")])
8104
8105 ;; Convert wide AND instructions with immediate operand to shorter QImode
8106 ;; equivalents when possible.
8107 ;; Don't do the splitting with memory operands, since it introduces risk
8108 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8109 ;; for size, but that can (should?) be handled by generic code instead.
8110 (define_split
8111 [(set (match_operand 0 "register_operand")
8112 (and (match_operand 1 "register_operand")
8113 (match_operand 2 "const_int_operand")))
8114 (clobber (reg:CC FLAGS_REG))]
8115 "reload_completed
8116 && QI_REG_P (operands[0])
8117 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8118 && !(~INTVAL (operands[2]) & ~(255 << 8))
8119 && GET_MODE (operands[0]) != QImode"
8120 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8121 (and:SI (zero_extract:SI (match_dup 1)
8122 (const_int 8) (const_int 8))
8123 (match_dup 2)))
8124 (clobber (reg:CC FLAGS_REG))])]
8125 {
8126 operands[0] = gen_lowpart (SImode, operands[0]);
8127 operands[1] = gen_lowpart (SImode, operands[1]);
8128 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8129 })
8130
8131 ;; Since AND can be encoded with sign extended immediate, this is only
8132 ;; profitable when 7th bit is not set.
8133 (define_split
8134 [(set (match_operand 0 "register_operand")
8135 (and (match_operand 1 "general_operand")
8136 (match_operand 2 "const_int_operand")))
8137 (clobber (reg:CC FLAGS_REG))]
8138 "reload_completed
8139 && ANY_QI_REG_P (operands[0])
8140 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8141 && !(~INTVAL (operands[2]) & ~255)
8142 && !(INTVAL (operands[2]) & 128)
8143 && GET_MODE (operands[0]) != QImode"
8144 [(parallel [(set (strict_low_part (match_dup 0))
8145 (and:QI (match_dup 1)
8146 (match_dup 2)))
8147 (clobber (reg:CC FLAGS_REG))])]
8148 {
8149 operands[0] = gen_lowpart (QImode, operands[0]);
8150 operands[1] = gen_lowpart (QImode, operands[1]);
8151 operands[2] = gen_lowpart (QImode, operands[2]);
8152 })
8153 \f
8154 ;; Logical inclusive and exclusive OR instructions
8155
8156 ;; %%% This used to optimize known byte-wide and operations to memory.
8157 ;; If this is considered useful, it should be done with splitters.
8158
8159 (define_expand "<code><mode>3"
8160 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8161 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8162 (match_operand:SWIM 2 "<general_operand>")))]
8163 ""
8164 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8165
8166 (define_insn "*<code><mode>_1"
8167 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8168 (any_or:SWI48
8169 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8170 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8171 (clobber (reg:CC FLAGS_REG))]
8172 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8173 "@
8174 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8175 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8176 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8177 [(set_attr "type" "alu,alu,msklog")
8178 (set_attr "mode" "<MODE>")])
8179
8180 (define_insn "*<code>hi_1"
8181 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8182 (any_or:HI
8183 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8184 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8185 (clobber (reg:CC FLAGS_REG))]
8186 "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8187 "@
8188 <logic>{w}\t{%2, %0|%0, %2}
8189 <logic>{w}\t{%2, %0|%0, %2}
8190 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8191 [(set_attr "type" "alu,alu,msklog")
8192 (set_attr "mode" "HI")])
8193
8194 ;; %%% Potential partial reg stall on alternative 2. What to do?
8195 (define_insn "*<code>qi_1"
8196 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8197 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8198 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8199 (clobber (reg:CC FLAGS_REG))]
8200 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8201 "@
8202 <logic>{b}\t{%2, %0|%0, %2}
8203 <logic>{b}\t{%2, %0|%0, %2}
8204 <logic>{l}\t{%k2, %k0|%k0, %k2}
8205 k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8206 [(set_attr "type" "alu,alu,alu,msklog")
8207 (set_attr "mode" "QI,QI,SI,HI")])
8208
8209 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8210 (define_insn "*<code>si_1_zext"
8211 [(set (match_operand:DI 0 "register_operand" "=r")
8212 (zero_extend:DI
8213 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8214 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8215 (clobber (reg:CC FLAGS_REG))]
8216 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8217 "<logic>{l}\t{%2, %k0|%k0, %2}"
8218 [(set_attr "type" "alu")
8219 (set_attr "mode" "SI")])
8220
8221 (define_insn "*<code>si_1_zext_imm"
8222 [(set (match_operand:DI 0 "register_operand" "=r")
8223 (any_or:DI
8224 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8225 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8226 (clobber (reg:CC FLAGS_REG))]
8227 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8228 "<logic>{l}\t{%2, %k0|%k0, %2}"
8229 [(set_attr "type" "alu")
8230 (set_attr "mode" "SI")])
8231
8232 (define_insn "*<code>qi_1_slp"
8233 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8234 (any_or:QI (match_dup 0)
8235 (match_operand:QI 1 "general_operand" "qmn,qn")))
8236 (clobber (reg:CC FLAGS_REG))]
8237 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8238 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8239 "<logic>{b}\t{%1, %0|%0, %1}"
8240 [(set_attr "type" "alu1")
8241 (set_attr "mode" "QI")])
8242
8243 (define_insn "*<code><mode>_2"
8244 [(set (reg FLAGS_REG)
8245 (compare (any_or:SWI
8246 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8247 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8248 (const_int 0)))
8249 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8250 (any_or:SWI (match_dup 1) (match_dup 2)))]
8251 "ix86_match_ccmode (insn, CCNOmode)
8252 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8253 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "mode" "<MODE>")])
8256
8257 (define_insn "kxnor<mode>"
8258 [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8259 (not:SWI12
8260 (xor:SWI12
8261 (match_operand:SWI12 1 "register_operand" "0,k")
8262 (match_operand:SWI12 2 "register_operand" "r,k"))))
8263 (clobber (reg:CC FLAGS_REG))]
8264 "TARGET_AVX512F"
8265 {
8266 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8267 return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8268 return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8269 }
8270 [(set_attr "type" "*,msklog")
8271 (set_attr "prefix" "*,vex")
8272 (set_attr "mode" "<MODE>")])
8273
8274 (define_insn "kxnor<mode>"
8275 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8276 (not:SWI48x
8277 (xor:SWI48x
8278 (match_operand:SWI48x 1 "register_operand" "0,k")
8279 (match_operand:SWI48x 2 "register_operand" "r,k"))))
8280 (clobber (reg:CC FLAGS_REG))]
8281 "TARGET_AVX512BW"
8282 "@
8283 #
8284 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8285 [(set_attr "type" "*,msklog")
8286 (set_attr "prefix" "*,vex")
8287 (set_attr "mode" "<MODE>")])
8288
8289 (define_split
8290 [(set (match_operand:SWI1248x 0 "general_reg_operand")
8291 (not:SWI1248x
8292 (xor:SWI1248x
8293 (match_dup 0)
8294 (match_operand:SWI1248x 1 "general_reg_operand"))))
8295 (clobber (reg:CC FLAGS_REG))]
8296 "TARGET_AVX512F && reload_completed"
8297 [(parallel [(set (match_dup 0)
8298 (xor:HI (match_dup 0)
8299 (match_dup 1)))
8300 (clobber (reg:CC FLAGS_REG))])
8301 (set (match_dup 0)
8302 (not:HI (match_dup 0)))])
8303
8304 ;;There are kortrest[bdq] but no intrinsics for them.
8305 ;;We probably don't need to implement them.
8306 (define_insn "kortestzhi"
8307 [(set (reg:CCZ FLAGS_REG)
8308 (compare:CCZ
8309 (ior:HI
8310 (match_operand:HI 0 "register_operand" "k")
8311 (match_operand:HI 1 "register_operand" "k"))
8312 (const_int 0)))]
8313 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8314 "kortestw\t{%1, %0|%0, %1}"
8315 [(set_attr "mode" "HI")
8316 (set_attr "type" "msklog")
8317 (set_attr "prefix" "vex")])
8318
8319 (define_insn "kortestchi"
8320 [(set (reg:CCC FLAGS_REG)
8321 (compare:CCC
8322 (ior:HI
8323 (match_operand:HI 0 "register_operand" "k")
8324 (match_operand:HI 1 "register_operand" "k"))
8325 (const_int -1)))]
8326 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8327 "kortestw\t{%1, %0|%0, %1}"
8328 [(set_attr "mode" "HI")
8329 (set_attr "type" "msklog")
8330 (set_attr "prefix" "vex")])
8331
8332 (define_insn "kunpckhi"
8333 [(set (match_operand:HI 0 "register_operand" "=k")
8334 (ior:HI
8335 (ashift:HI
8336 (match_operand:HI 1 "register_operand" "k")
8337 (const_int 8))
8338 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8339 "TARGET_AVX512F"
8340 "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8341 [(set_attr "mode" "HI")
8342 (set_attr "type" "msklog")
8343 (set_attr "prefix" "vex")])
8344
8345 (define_insn "kunpcksi"
8346 [(set (match_operand:SI 0 "register_operand" "=k")
8347 (ior:SI
8348 (ashift:SI
8349 (match_operand:SI 1 "register_operand" "k")
8350 (const_int 16))
8351 (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8352 "TARGET_AVX512BW"
8353 "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8354 [(set_attr "mode" "SI")])
8355
8356 (define_insn "kunpckdi"
8357 [(set (match_operand:DI 0 "register_operand" "=k")
8358 (ior:DI
8359 (ashift:DI
8360 (match_operand:DI 1 "register_operand" "k")
8361 (const_int 32))
8362 (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8363 "TARGET_AVX512BW"
8364 "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8365 [(set_attr "mode" "DI")])
8366
8367 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8368 ;; ??? Special case for immediate operand is missing - it is tricky.
8369 (define_insn "*<code>si_2_zext"
8370 [(set (reg FLAGS_REG)
8371 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8372 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8373 (const_int 0)))
8374 (set (match_operand:DI 0 "register_operand" "=r")
8375 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8376 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8377 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8378 "<logic>{l}\t{%2, %k0|%k0, %2}"
8379 [(set_attr "type" "alu")
8380 (set_attr "mode" "SI")])
8381
8382 (define_insn "*<code>si_2_zext_imm"
8383 [(set (reg FLAGS_REG)
8384 (compare (any_or:SI
8385 (match_operand:SI 1 "nonimmediate_operand" "%0")
8386 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8387 (const_int 0)))
8388 (set (match_operand:DI 0 "register_operand" "=r")
8389 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8390 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8391 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8392 "<logic>{l}\t{%2, %k0|%k0, %2}"
8393 [(set_attr "type" "alu")
8394 (set_attr "mode" "SI")])
8395
8396 (define_insn "*<code>qi_2_slp"
8397 [(set (reg FLAGS_REG)
8398 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8399 (match_operand:QI 1 "general_operand" "qmn,qn"))
8400 (const_int 0)))
8401 (set (strict_low_part (match_dup 0))
8402 (any_or:QI (match_dup 0) (match_dup 1)))]
8403 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8404 && ix86_match_ccmode (insn, CCNOmode)
8405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8406 "<logic>{b}\t{%1, %0|%0, %1}"
8407 [(set_attr "type" "alu1")
8408 (set_attr "mode" "QI")])
8409
8410 (define_insn "*<code><mode>_3"
8411 [(set (reg FLAGS_REG)
8412 (compare (any_or:SWI
8413 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8414 (match_operand:SWI 2 "<general_operand>" "<g>"))
8415 (const_int 0)))
8416 (clobber (match_scratch:SWI 0 "=<r>"))]
8417 "ix86_match_ccmode (insn, CCNOmode)
8418 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8419 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8420 [(set_attr "type" "alu")
8421 (set_attr "mode" "<MODE>")])
8422
8423 (define_insn "*<code>qi_ext_0"
8424 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8425 (const_int 8)
8426 (const_int 8))
8427 (any_or:SI
8428 (zero_extract:SI
8429 (match_operand 1 "ext_register_operand" "0")
8430 (const_int 8)
8431 (const_int 8))
8432 (match_operand 2 "const_int_operand" "n")))
8433 (clobber (reg:CC FLAGS_REG))]
8434 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8435 "<logic>{b}\t{%2, %h0|%h0, %2}"
8436 [(set_attr "type" "alu")
8437 (set_attr "length_immediate" "1")
8438 (set_attr "modrm" "1")
8439 (set_attr "mode" "QI")])
8440
8441 (define_insn "*<code>qi_ext_1"
8442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8443 (const_int 8)
8444 (const_int 8))
8445 (any_or:SI
8446 (zero_extract:SI
8447 (match_operand 1 "ext_register_operand" "0,0")
8448 (const_int 8)
8449 (const_int 8))
8450 (zero_extend:SI
8451 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8452 (clobber (reg:CC FLAGS_REG))]
8453 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8454 "<logic>{b}\t{%2, %h0|%h0, %2}"
8455 [(set_attr "isa" "*,nox64")
8456 (set_attr "type" "alu")
8457 (set_attr "length_immediate" "0")
8458 (set_attr "mode" "QI")])
8459
8460 (define_insn "*<code>qi_ext_2"
8461 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8462 (const_int 8)
8463 (const_int 8))
8464 (any_or:SI
8465 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8466 (const_int 8)
8467 (const_int 8))
8468 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8469 (const_int 8)
8470 (const_int 8))))
8471 (clobber (reg:CC FLAGS_REG))]
8472 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8473 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8474 [(set_attr "type" "alu")
8475 (set_attr "length_immediate" "0")
8476 (set_attr "mode" "QI")])
8477
8478 (define_split
8479 [(set (match_operand 0 "register_operand")
8480 (any_or (match_operand 1 "register_operand")
8481 (match_operand 2 "const_int_operand")))
8482 (clobber (reg:CC FLAGS_REG))]
8483 "reload_completed
8484 && QI_REG_P (operands[0])
8485 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8486 && !(INTVAL (operands[2]) & ~(255 << 8))
8487 && GET_MODE (operands[0]) != QImode"
8488 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8489 (any_or:SI (zero_extract:SI (match_dup 1)
8490 (const_int 8) (const_int 8))
8491 (match_dup 2)))
8492 (clobber (reg:CC FLAGS_REG))])]
8493 {
8494 operands[0] = gen_lowpart (SImode, operands[0]);
8495 operands[1] = gen_lowpart (SImode, operands[1]);
8496 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8497 })
8498
8499 ;; Since OR can be encoded with sign extended immediate, this is only
8500 ;; profitable when 7th bit is set.
8501 (define_split
8502 [(set (match_operand 0 "register_operand")
8503 (any_or (match_operand 1 "general_operand")
8504 (match_operand 2 "const_int_operand")))
8505 (clobber (reg:CC FLAGS_REG))]
8506 "reload_completed
8507 && ANY_QI_REG_P (operands[0])
8508 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8509 && !(INTVAL (operands[2]) & ~255)
8510 && (INTVAL (operands[2]) & 128)
8511 && GET_MODE (operands[0]) != QImode"
8512 [(parallel [(set (strict_low_part (match_dup 0))
8513 (any_or:QI (match_dup 1)
8514 (match_dup 2)))
8515 (clobber (reg:CC FLAGS_REG))])]
8516 {
8517 operands[0] = gen_lowpart (QImode, operands[0]);
8518 operands[1] = gen_lowpart (QImode, operands[1]);
8519 operands[2] = gen_lowpart (QImode, operands[2]);
8520 })
8521
8522 (define_expand "xorqi_cc_ext_1"
8523 [(parallel [
8524 (set (reg:CCNO FLAGS_REG)
8525 (compare:CCNO
8526 (xor:SI
8527 (zero_extract:SI
8528 (match_operand 1 "ext_register_operand")
8529 (const_int 8)
8530 (const_int 8))
8531 (match_operand:QI 2 "const_int_operand"))
8532 (const_int 0)))
8533 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8534 (const_int 8)
8535 (const_int 8))
8536 (xor:SI
8537 (zero_extract:SI
8538 (match_dup 1)
8539 (const_int 8)
8540 (const_int 8))
8541 (match_dup 2)))])])
8542
8543 (define_insn "*xorqi_cc_ext_1"
8544 [(set (reg FLAGS_REG)
8545 (compare
8546 (xor:SI
8547 (zero_extract:SI
8548 (match_operand 1 "ext_register_operand" "0,0")
8549 (const_int 8)
8550 (const_int 8))
8551 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8552 (const_int 0)))
8553 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8554 (const_int 8)
8555 (const_int 8))
8556 (xor:SI
8557 (zero_extract:SI
8558 (match_dup 1)
8559 (const_int 8)
8560 (const_int 8))
8561 (match_dup 2)))]
8562 "ix86_match_ccmode (insn, CCNOmode)"
8563 "xor{b}\t{%2, %h0|%h0, %2}"
8564 [(set_attr "isa" "*,nox64")
8565 (set_attr "type" "alu")
8566 (set_attr "modrm" "1")
8567 (set_attr "mode" "QI")])
8568 \f
8569 ;; Negation instructions
8570
8571 (define_expand "neg<mode>2"
8572 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8573 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8574 ""
8575 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8576
8577 (define_insn_and_split "*neg<dwi>2_doubleword"
8578 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8579 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8582 "#"
8583 "reload_completed"
8584 [(parallel
8585 [(set (reg:CCZ FLAGS_REG)
8586 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8587 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8588 (parallel
8589 [(set (match_dup 2)
8590 (plus:DWIH (match_dup 3)
8591 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8592 (const_int 0))))
8593 (clobber (reg:CC FLAGS_REG))])
8594 (parallel
8595 [(set (match_dup 2)
8596 (neg:DWIH (match_dup 2)))
8597 (clobber (reg:CC FLAGS_REG))])]
8598 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8599
8600 (define_insn "*neg<mode>2_1"
8601 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8602 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8603 (clobber (reg:CC FLAGS_REG))]
8604 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8605 "neg{<imodesuffix>}\t%0"
8606 [(set_attr "type" "negnot")
8607 (set_attr "mode" "<MODE>")])
8608
8609 ;; Combine is quite creative about this pattern.
8610 (define_insn "*negsi2_1_zext"
8611 [(set (match_operand:DI 0 "register_operand" "=r")
8612 (lshiftrt:DI
8613 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8614 (const_int 32)))
8615 (const_int 32)))
8616 (clobber (reg:CC FLAGS_REG))]
8617 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8618 "neg{l}\t%k0"
8619 [(set_attr "type" "negnot")
8620 (set_attr "mode" "SI")])
8621
8622 ;; The problem with neg is that it does not perform (compare x 0),
8623 ;; it really performs (compare 0 x), which leaves us with the zero
8624 ;; flag being the only useful item.
8625
8626 (define_insn "*neg<mode>2_cmpz"
8627 [(set (reg:CCZ FLAGS_REG)
8628 (compare:CCZ
8629 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8630 (const_int 0)))
8631 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8632 (neg:SWI (match_dup 1)))]
8633 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8634 "neg{<imodesuffix>}\t%0"
8635 [(set_attr "type" "negnot")
8636 (set_attr "mode" "<MODE>")])
8637
8638 (define_insn "*negsi2_cmpz_zext"
8639 [(set (reg:CCZ FLAGS_REG)
8640 (compare:CCZ
8641 (lshiftrt:DI
8642 (neg:DI (ashift:DI
8643 (match_operand:DI 1 "register_operand" "0")
8644 (const_int 32)))
8645 (const_int 32))
8646 (const_int 0)))
8647 (set (match_operand:DI 0 "register_operand" "=r")
8648 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8649 (const_int 32)))
8650 (const_int 32)))]
8651 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8652 "neg{l}\t%k0"
8653 [(set_attr "type" "negnot")
8654 (set_attr "mode" "SI")])
8655
8656 ;; Negate with jump on overflow.
8657 (define_expand "negv<mode>3"
8658 [(parallel [(set (reg:CCO FLAGS_REG)
8659 (ne:CCO (match_operand:SWI 1 "register_operand")
8660 (match_dup 3)))
8661 (set (match_operand:SWI 0 "register_operand")
8662 (neg:SWI (match_dup 1)))])
8663 (set (pc) (if_then_else
8664 (eq (reg:CCO FLAGS_REG) (const_int 0))
8665 (label_ref (match_operand 2))
8666 (pc)))]
8667 ""
8668 {
8669 operands[3]
8670 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8671 <MODE>mode);
8672 })
8673
8674 (define_insn "*negv<mode>3"
8675 [(set (reg:CCO FLAGS_REG)
8676 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8677 (match_operand:SWI 2 "const_int_operand")))
8678 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8679 (neg:SWI (match_dup 1)))]
8680 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8681 && mode_signbit_p (<MODE>mode, operands[2])"
8682 "neg{<imodesuffix>}\t%0"
8683 [(set_attr "type" "negnot")
8684 (set_attr "mode" "<MODE>")])
8685
8686 ;; Changing of sign for FP values is doable using integer unit too.
8687
8688 (define_expand "<code><mode>2"
8689 [(set (match_operand:X87MODEF 0 "register_operand")
8690 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8691 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8692 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8693
8694 (define_insn "*absneg<mode>2_mixed"
8695 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8696 (match_operator:MODEF 3 "absneg_operator"
8697 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8698 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8699 (clobber (reg:CC FLAGS_REG))]
8700 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8701 "#")
8702
8703 (define_insn "*absneg<mode>2_sse"
8704 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8705 (match_operator:MODEF 3 "absneg_operator"
8706 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8707 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8708 (clobber (reg:CC FLAGS_REG))]
8709 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8710 "#")
8711
8712 (define_insn "*absneg<mode>2_i387"
8713 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8714 (match_operator:X87MODEF 3 "absneg_operator"
8715 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8716 (use (match_operand 2))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8719 "#")
8720
8721 (define_expand "<code>tf2"
8722 [(set (match_operand:TF 0 "register_operand")
8723 (absneg:TF (match_operand:TF 1 "register_operand")))]
8724 "TARGET_SSE"
8725 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8726
8727 (define_insn "*absnegtf2_sse"
8728 [(set (match_operand:TF 0 "register_operand" "=x,x")
8729 (match_operator:TF 3 "absneg_operator"
8730 [(match_operand:TF 1 "register_operand" "0,x")]))
8731 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8732 (clobber (reg:CC FLAGS_REG))]
8733 "TARGET_SSE"
8734 "#")
8735
8736 ;; Splitters for fp abs and neg.
8737
8738 (define_split
8739 [(set (match_operand 0 "fp_register_operand")
8740 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8741 (use (match_operand 2))
8742 (clobber (reg:CC FLAGS_REG))]
8743 "reload_completed"
8744 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8745
8746 (define_split
8747 [(set (match_operand 0 "register_operand")
8748 (match_operator 3 "absneg_operator"
8749 [(match_operand 1 "register_operand")]))
8750 (use (match_operand 2 "nonimmediate_operand"))
8751 (clobber (reg:CC FLAGS_REG))]
8752 "reload_completed && SSE_REG_P (operands[0])"
8753 [(set (match_dup 0) (match_dup 3))]
8754 {
8755 machine_mode mode = GET_MODE (operands[0]);
8756 machine_mode vmode = GET_MODE (operands[2]);
8757 rtx tmp;
8758
8759 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8760 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8761 if (operands_match_p (operands[0], operands[2]))
8762 std::swap (operands[1], operands[2]);
8763 if (GET_CODE (operands[3]) == ABS)
8764 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8765 else
8766 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8767 operands[3] = tmp;
8768 })
8769
8770 (define_split
8771 [(set (match_operand:SF 0 "register_operand")
8772 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8773 (use (match_operand:V4SF 2))
8774 (clobber (reg:CC FLAGS_REG))]
8775 "reload_completed"
8776 [(parallel [(set (match_dup 0) (match_dup 1))
8777 (clobber (reg:CC FLAGS_REG))])]
8778 {
8779 rtx tmp;
8780 operands[0] = gen_lowpart (SImode, operands[0]);
8781 if (GET_CODE (operands[1]) == ABS)
8782 {
8783 tmp = gen_int_mode (0x7fffffff, SImode);
8784 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8785 }
8786 else
8787 {
8788 tmp = gen_int_mode (0x80000000, SImode);
8789 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8790 }
8791 operands[1] = tmp;
8792 })
8793
8794 (define_split
8795 [(set (match_operand:DF 0 "register_operand")
8796 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8797 (use (match_operand 2))
8798 (clobber (reg:CC FLAGS_REG))]
8799 "reload_completed"
8800 [(parallel [(set (match_dup 0) (match_dup 1))
8801 (clobber (reg:CC FLAGS_REG))])]
8802 {
8803 rtx tmp;
8804 if (TARGET_64BIT)
8805 {
8806 tmp = gen_lowpart (DImode, operands[0]);
8807 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8808 operands[0] = tmp;
8809
8810 if (GET_CODE (operands[1]) == ABS)
8811 tmp = const0_rtx;
8812 else
8813 tmp = gen_rtx_NOT (DImode, tmp);
8814 }
8815 else
8816 {
8817 operands[0] = gen_highpart (SImode, operands[0]);
8818 if (GET_CODE (operands[1]) == ABS)
8819 {
8820 tmp = gen_int_mode (0x7fffffff, SImode);
8821 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8822 }
8823 else
8824 {
8825 tmp = gen_int_mode (0x80000000, SImode);
8826 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8827 }
8828 }
8829 operands[1] = tmp;
8830 })
8831
8832 (define_split
8833 [(set (match_operand:XF 0 "register_operand")
8834 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8835 (use (match_operand 2))
8836 (clobber (reg:CC FLAGS_REG))]
8837 "reload_completed"
8838 [(parallel [(set (match_dup 0) (match_dup 1))
8839 (clobber (reg:CC FLAGS_REG))])]
8840 {
8841 rtx tmp;
8842 operands[0] = gen_rtx_REG (SImode,
8843 true_regnum (operands[0])
8844 + (TARGET_64BIT ? 1 : 2));
8845 if (GET_CODE (operands[1]) == ABS)
8846 {
8847 tmp = GEN_INT (0x7fff);
8848 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8849 }
8850 else
8851 {
8852 tmp = GEN_INT (0x8000);
8853 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8854 }
8855 operands[1] = tmp;
8856 })
8857
8858 ;; Conditionalize these after reload. If they match before reload, we
8859 ;; lose the clobber and ability to use integer instructions.
8860
8861 (define_insn "*<code><mode>2_1"
8862 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8863 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8864 "TARGET_80387
8865 && (reload_completed
8866 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8867 "f<absneg_mnemonic>"
8868 [(set_attr "type" "fsgn")
8869 (set_attr "mode" "<MODE>")])
8870
8871 (define_insn "*<code>extendsfdf2"
8872 [(set (match_operand:DF 0 "register_operand" "=f")
8873 (absneg:DF (float_extend:DF
8874 (match_operand:SF 1 "register_operand" "0"))))]
8875 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8876 "f<absneg_mnemonic>"
8877 [(set_attr "type" "fsgn")
8878 (set_attr "mode" "DF")])
8879
8880 (define_insn "*<code>extendsfxf2"
8881 [(set (match_operand:XF 0 "register_operand" "=f")
8882 (absneg:XF (float_extend:XF
8883 (match_operand:SF 1 "register_operand" "0"))))]
8884 "TARGET_80387"
8885 "f<absneg_mnemonic>"
8886 [(set_attr "type" "fsgn")
8887 (set_attr "mode" "XF")])
8888
8889 (define_insn "*<code>extenddfxf2"
8890 [(set (match_operand:XF 0 "register_operand" "=f")
8891 (absneg:XF (float_extend:XF
8892 (match_operand:DF 1 "register_operand" "0"))))]
8893 "TARGET_80387"
8894 "f<absneg_mnemonic>"
8895 [(set_attr "type" "fsgn")
8896 (set_attr "mode" "XF")])
8897
8898 ;; Copysign instructions
8899
8900 (define_mode_iterator CSGNMODE [SF DF TF])
8901 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8902
8903 (define_expand "copysign<mode>3"
8904 [(match_operand:CSGNMODE 0 "register_operand")
8905 (match_operand:CSGNMODE 1 "nonmemory_operand")
8906 (match_operand:CSGNMODE 2 "register_operand")]
8907 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8908 || (TARGET_SSE && (<MODE>mode == TFmode))"
8909 "ix86_expand_copysign (operands); DONE;")
8910
8911 (define_insn_and_split "copysign<mode>3_const"
8912 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8913 (unspec:CSGNMODE
8914 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8915 (match_operand:CSGNMODE 2 "register_operand" "0")
8916 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8917 UNSPEC_COPYSIGN))]
8918 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8919 || (TARGET_SSE && (<MODE>mode == TFmode))"
8920 "#"
8921 "&& reload_completed"
8922 [(const_int 0)]
8923 "ix86_split_copysign_const (operands); DONE;")
8924
8925 (define_insn "copysign<mode>3_var"
8926 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8927 (unspec:CSGNMODE
8928 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8929 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8930 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8931 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8932 UNSPEC_COPYSIGN))
8933 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8934 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8935 || (TARGET_SSE && (<MODE>mode == TFmode))"
8936 "#")
8937
8938 (define_split
8939 [(set (match_operand:CSGNMODE 0 "register_operand")
8940 (unspec:CSGNMODE
8941 [(match_operand:CSGNMODE 2 "register_operand")
8942 (match_operand:CSGNMODE 3 "register_operand")
8943 (match_operand:<CSGNVMODE> 4)
8944 (match_operand:<CSGNVMODE> 5)]
8945 UNSPEC_COPYSIGN))
8946 (clobber (match_scratch:<CSGNVMODE> 1))]
8947 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8948 || (TARGET_SSE && (<MODE>mode == TFmode)))
8949 && reload_completed"
8950 [(const_int 0)]
8951 "ix86_split_copysign_var (operands); DONE;")
8952 \f
8953 ;; One complement instructions
8954
8955 (define_expand "one_cmpl<mode>2"
8956 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8957 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8958 ""
8959 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8960
8961 (define_insn "*one_cmpl<mode>2_1"
8962 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
8963 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
8964 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8965 "@
8966 not{<imodesuffix>}\t%0
8967 knot<mskmodesuffix>\t{%1, %0|%0, %1}"
8968 [(set_attr "isa" "*,avx512bw")
8969 (set_attr "type" "negnot,msklog")
8970 (set_attr "prefix" "*,vex")
8971 (set_attr "mode" "<MODE>")])
8972
8973 (define_insn "*one_cmplhi2_1"
8974 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
8975 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
8976 "ix86_unary_operator_ok (NOT, HImode, operands)"
8977 "@
8978 not{w}\t%0
8979 knotw\t{%1, %0|%0, %1}"
8980 [(set_attr "isa" "*,avx512f")
8981 (set_attr "type" "negnot,msklog")
8982 (set_attr "prefix" "*,vex")
8983 (set_attr "mode" "HI")])
8984
8985 ;; %%% Potential partial reg stall on alternative 1. What to do?
8986 (define_insn "*one_cmplqi2_1"
8987 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
8988 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
8989 "ix86_unary_operator_ok (NOT, QImode, operands)"
8990 {
8991 switch (which_alternative)
8992 {
8993 case 0:
8994 return "not{b}\t%0";
8995 case 1:
8996 return "not{l}\t%k0";
8997 case 2:
8998 if (TARGET_AVX512DQ)
8999 return "knotb\t{%1, %0|%0, %1}";
9000 return "knotw\t{%1, %0|%0, %1}";
9001 default:
9002 gcc_unreachable ();
9003 }
9004 }
9005 [(set_attr "isa" "*,*,avx512f")
9006 (set_attr "type" "negnot,negnot,msklog")
9007 (set_attr "prefix" "*,*,vex")
9008 (set_attr "mode" "QI,SI,QI")])
9009
9010 ;; ??? Currently never generated - xor is used instead.
9011 (define_insn "*one_cmplsi2_1_zext"
9012 [(set (match_operand:DI 0 "register_operand" "=r")
9013 (zero_extend:DI
9014 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9015 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9016 "not{l}\t%k0"
9017 [(set_attr "type" "negnot")
9018 (set_attr "mode" "SI")])
9019
9020 (define_insn "*one_cmpl<mode>2_2"
9021 [(set (reg FLAGS_REG)
9022 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9023 (const_int 0)))
9024 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9025 (not:SWI (match_dup 1)))]
9026 "ix86_match_ccmode (insn, CCNOmode)
9027 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9028 "#"
9029 [(set_attr "type" "alu1")
9030 (set_attr "mode" "<MODE>")])
9031
9032 (define_split
9033 [(set (match_operand 0 "flags_reg_operand")
9034 (match_operator 2 "compare_operator"
9035 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9036 (const_int 0)]))
9037 (set (match_operand:SWI 1 "nonimmediate_operand")
9038 (not:SWI (match_dup 3)))]
9039 "ix86_match_ccmode (insn, CCNOmode)"
9040 [(parallel [(set (match_dup 0)
9041 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9042 (const_int 0)]))
9043 (set (match_dup 1)
9044 (xor:SWI (match_dup 3) (const_int -1)))])])
9045
9046 ;; ??? Currently never generated - xor is used instead.
9047 (define_insn "*one_cmplsi2_2_zext"
9048 [(set (reg FLAGS_REG)
9049 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9050 (const_int 0)))
9051 (set (match_operand:DI 0 "register_operand" "=r")
9052 (zero_extend:DI (not:SI (match_dup 1))))]
9053 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9054 && ix86_unary_operator_ok (NOT, SImode, operands)"
9055 "#"
9056 [(set_attr "type" "alu1")
9057 (set_attr "mode" "SI")])
9058
9059 (define_split
9060 [(set (match_operand 0 "flags_reg_operand")
9061 (match_operator 2 "compare_operator"
9062 [(not:SI (match_operand:SI 3 "register_operand"))
9063 (const_int 0)]))
9064 (set (match_operand:DI 1 "register_operand")
9065 (zero_extend:DI (not:SI (match_dup 3))))]
9066 "ix86_match_ccmode (insn, CCNOmode)"
9067 [(parallel [(set (match_dup 0)
9068 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9069 (const_int 0)]))
9070 (set (match_dup 1)
9071 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9072 \f
9073 ;; Shift instructions
9074
9075 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9076 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9077 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9078 ;; from the assembler input.
9079 ;;
9080 ;; This instruction shifts the target reg/mem as usual, but instead of
9081 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9082 ;; is a left shift double, bits are taken from the high order bits of
9083 ;; reg, else if the insn is a shift right double, bits are taken from the
9084 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9085 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9086 ;;
9087 ;; Since sh[lr]d does not change the `reg' operand, that is done
9088 ;; separately, making all shifts emit pairs of shift double and normal
9089 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9090 ;; support a 63 bit shift, each shift where the count is in a reg expands
9091 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9092 ;;
9093 ;; If the shift count is a constant, we need never emit more than one
9094 ;; shift pair, instead using moves and sign extension for counts greater
9095 ;; than 31.
9096
9097 (define_expand "ashl<mode>3"
9098 [(set (match_operand:SDWIM 0 "<shift_operand>")
9099 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9100 (match_operand:QI 2 "nonmemory_operand")))]
9101 ""
9102 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9103
9104 (define_insn "*ashl<mode>3_doubleword"
9105 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9106 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9107 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9108 (clobber (reg:CC FLAGS_REG))]
9109 ""
9110 "#"
9111 [(set_attr "type" "multi")])
9112
9113 (define_split
9114 [(set (match_operand:DWI 0 "register_operand")
9115 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9116 (match_operand:QI 2 "nonmemory_operand")))
9117 (clobber (reg:CC FLAGS_REG))]
9118 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9119 [(const_int 0)]
9120 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9121
9122 ;; By default we don't ask for a scratch register, because when DWImode
9123 ;; values are manipulated, registers are already at a premium. But if
9124 ;; we have one handy, we won't turn it away.
9125
9126 (define_peephole2
9127 [(match_scratch:DWIH 3 "r")
9128 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9129 (ashift:<DWI>
9130 (match_operand:<DWI> 1 "nonmemory_operand")
9131 (match_operand:QI 2 "nonmemory_operand")))
9132 (clobber (reg:CC FLAGS_REG))])
9133 (match_dup 3)]
9134 "TARGET_CMOVE"
9135 [(const_int 0)]
9136 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9137
9138 (define_insn "x86_64_shld"
9139 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9140 (ior:DI (ashift:DI (match_dup 0)
9141 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9142 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9143 (minus:QI (const_int 64) (match_dup 2)))))
9144 (clobber (reg:CC FLAGS_REG))]
9145 "TARGET_64BIT"
9146 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9147 [(set_attr "type" "ishift")
9148 (set_attr "prefix_0f" "1")
9149 (set_attr "mode" "DI")
9150 (set_attr "athlon_decode" "vector")
9151 (set_attr "amdfam10_decode" "vector")
9152 (set_attr "bdver1_decode" "vector")])
9153
9154 (define_insn "x86_shld"
9155 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9156 (ior:SI (ashift:SI (match_dup 0)
9157 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9158 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9159 (minus:QI (const_int 32) (match_dup 2)))))
9160 (clobber (reg:CC FLAGS_REG))]
9161 ""
9162 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9163 [(set_attr "type" "ishift")
9164 (set_attr "prefix_0f" "1")
9165 (set_attr "mode" "SI")
9166 (set_attr "pent_pair" "np")
9167 (set_attr "athlon_decode" "vector")
9168 (set_attr "amdfam10_decode" "vector")
9169 (set_attr "bdver1_decode" "vector")])
9170
9171 (define_expand "x86_shift<mode>_adj_1"
9172 [(set (reg:CCZ FLAGS_REG)
9173 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9174 (match_dup 4))
9175 (const_int 0)))
9176 (set (match_operand:SWI48 0 "register_operand")
9177 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9178 (match_operand:SWI48 1 "register_operand")
9179 (match_dup 0)))
9180 (set (match_dup 1)
9181 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9182 (match_operand:SWI48 3 "register_operand")
9183 (match_dup 1)))]
9184 "TARGET_CMOVE"
9185 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9186
9187 (define_expand "x86_shift<mode>_adj_2"
9188 [(use (match_operand:SWI48 0 "register_operand"))
9189 (use (match_operand:SWI48 1 "register_operand"))
9190 (use (match_operand:QI 2 "register_operand"))]
9191 ""
9192 {
9193 rtx_code_label *label = gen_label_rtx ();
9194 rtx tmp;
9195
9196 emit_insn (gen_testqi_ccz_1 (operands[2],
9197 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9198
9199 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9200 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9201 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9202 gen_rtx_LABEL_REF (VOIDmode, label),
9203 pc_rtx);
9204 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9205 JUMP_LABEL (tmp) = label;
9206
9207 emit_move_insn (operands[0], operands[1]);
9208 ix86_expand_clear (operands[1]);
9209
9210 emit_label (label);
9211 LABEL_NUSES (label) = 1;
9212
9213 DONE;
9214 })
9215
9216 ;; Avoid useless masking of count operand.
9217 (define_insn "*ashl<mode>3_mask"
9218 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9219 (ashift:SWI48
9220 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9221 (subreg:QI
9222 (and:SI
9223 (match_operand:SI 2 "register_operand" "c")
9224 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9225 (clobber (reg:CC FLAGS_REG))]
9226 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9227 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9228 == GET_MODE_BITSIZE (<MODE>mode)-1"
9229 {
9230 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9231 }
9232 [(set_attr "type" "ishift")
9233 (set_attr "mode" "<MODE>")])
9234
9235 (define_insn "*bmi2_ashl<mode>3_1"
9236 [(set (match_operand:SWI48 0 "register_operand" "=r")
9237 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9238 (match_operand:SWI48 2 "register_operand" "r")))]
9239 "TARGET_BMI2"
9240 "shlx\t{%2, %1, %0|%0, %1, %2}"
9241 [(set_attr "type" "ishiftx")
9242 (set_attr "mode" "<MODE>")])
9243
9244 (define_insn "*ashl<mode>3_1"
9245 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9246 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9247 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9248 (clobber (reg:CC FLAGS_REG))]
9249 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9250 {
9251 switch (get_attr_type (insn))
9252 {
9253 case TYPE_LEA:
9254 case TYPE_ISHIFTX:
9255 return "#";
9256
9257 case TYPE_ALU:
9258 gcc_assert (operands[2] == const1_rtx);
9259 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9260 return "add{<imodesuffix>}\t%0, %0";
9261
9262 default:
9263 if (operands[2] == const1_rtx
9264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265 return "sal{<imodesuffix>}\t%0";
9266 else
9267 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9268 }
9269 }
9270 [(set_attr "isa" "*,*,bmi2")
9271 (set (attr "type")
9272 (cond [(eq_attr "alternative" "1")
9273 (const_string "lea")
9274 (eq_attr "alternative" "2")
9275 (const_string "ishiftx")
9276 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9277 (match_operand 0 "register_operand"))
9278 (match_operand 2 "const1_operand"))
9279 (const_string "alu")
9280 ]
9281 (const_string "ishift")))
9282 (set (attr "length_immediate")
9283 (if_then_else
9284 (ior (eq_attr "type" "alu")
9285 (and (eq_attr "type" "ishift")
9286 (and (match_operand 2 "const1_operand")
9287 (ior (match_test "TARGET_SHIFT1")
9288 (match_test "optimize_function_for_size_p (cfun)")))))
9289 (const_string "0")
9290 (const_string "*")))
9291 (set_attr "mode" "<MODE>")])
9292
9293 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9294 (define_split
9295 [(set (match_operand:SWI48 0 "register_operand")
9296 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9297 (match_operand:QI 2 "register_operand")))
9298 (clobber (reg:CC FLAGS_REG))]
9299 "TARGET_BMI2 && reload_completed"
9300 [(set (match_dup 0)
9301 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9302 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9303
9304 (define_insn "*bmi2_ashlsi3_1_zext"
9305 [(set (match_operand:DI 0 "register_operand" "=r")
9306 (zero_extend:DI
9307 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9308 (match_operand:SI 2 "register_operand" "r"))))]
9309 "TARGET_64BIT && TARGET_BMI2"
9310 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9311 [(set_attr "type" "ishiftx")
9312 (set_attr "mode" "SI")])
9313
9314 (define_insn "*ashlsi3_1_zext"
9315 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9316 (zero_extend:DI
9317 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9318 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9319 (clobber (reg:CC FLAGS_REG))]
9320 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9321 {
9322 switch (get_attr_type (insn))
9323 {
9324 case TYPE_LEA:
9325 case TYPE_ISHIFTX:
9326 return "#";
9327
9328 case TYPE_ALU:
9329 gcc_assert (operands[2] == const1_rtx);
9330 return "add{l}\t%k0, %k0";
9331
9332 default:
9333 if (operands[2] == const1_rtx
9334 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9335 return "sal{l}\t%k0";
9336 else
9337 return "sal{l}\t{%2, %k0|%k0, %2}";
9338 }
9339 }
9340 [(set_attr "isa" "*,*,bmi2")
9341 (set (attr "type")
9342 (cond [(eq_attr "alternative" "1")
9343 (const_string "lea")
9344 (eq_attr "alternative" "2")
9345 (const_string "ishiftx")
9346 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9347 (match_operand 2 "const1_operand"))
9348 (const_string "alu")
9349 ]
9350 (const_string "ishift")))
9351 (set (attr "length_immediate")
9352 (if_then_else
9353 (ior (eq_attr "type" "alu")
9354 (and (eq_attr "type" "ishift")
9355 (and (match_operand 2 "const1_operand")
9356 (ior (match_test "TARGET_SHIFT1")
9357 (match_test "optimize_function_for_size_p (cfun)")))))
9358 (const_string "0")
9359 (const_string "*")))
9360 (set_attr "mode" "SI")])
9361
9362 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9363 (define_split
9364 [(set (match_operand:DI 0 "register_operand")
9365 (zero_extend:DI
9366 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9367 (match_operand:QI 2 "register_operand"))))
9368 (clobber (reg:CC FLAGS_REG))]
9369 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9370 [(set (match_dup 0)
9371 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9372 "operands[2] = gen_lowpart (SImode, operands[2]);")
9373
9374 (define_insn "*ashlhi3_1"
9375 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9376 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9377 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9378 (clobber (reg:CC FLAGS_REG))]
9379 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9380 {
9381 switch (get_attr_type (insn))
9382 {
9383 case TYPE_LEA:
9384 return "#";
9385
9386 case TYPE_ALU:
9387 gcc_assert (operands[2] == const1_rtx);
9388 return "add{w}\t%0, %0";
9389
9390 default:
9391 if (operands[2] == const1_rtx
9392 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9393 return "sal{w}\t%0";
9394 else
9395 return "sal{w}\t{%2, %0|%0, %2}";
9396 }
9397 }
9398 [(set (attr "type")
9399 (cond [(eq_attr "alternative" "1")
9400 (const_string "lea")
9401 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9402 (match_operand 0 "register_operand"))
9403 (match_operand 2 "const1_operand"))
9404 (const_string "alu")
9405 ]
9406 (const_string "ishift")))
9407 (set (attr "length_immediate")
9408 (if_then_else
9409 (ior (eq_attr "type" "alu")
9410 (and (eq_attr "type" "ishift")
9411 (and (match_operand 2 "const1_operand")
9412 (ior (match_test "TARGET_SHIFT1")
9413 (match_test "optimize_function_for_size_p (cfun)")))))
9414 (const_string "0")
9415 (const_string "*")))
9416 (set_attr "mode" "HI,SI")])
9417
9418 ;; %%% Potential partial reg stall on alternative 1. What to do?
9419 (define_insn "*ashlqi3_1"
9420 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9421 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9422 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9423 (clobber (reg:CC FLAGS_REG))]
9424 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9425 {
9426 switch (get_attr_type (insn))
9427 {
9428 case TYPE_LEA:
9429 return "#";
9430
9431 case TYPE_ALU:
9432 gcc_assert (operands[2] == const1_rtx);
9433 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9434 return "add{l}\t%k0, %k0";
9435 else
9436 return "add{b}\t%0, %0";
9437
9438 default:
9439 if (operands[2] == const1_rtx
9440 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9441 {
9442 if (get_attr_mode (insn) == MODE_SI)
9443 return "sal{l}\t%k0";
9444 else
9445 return "sal{b}\t%0";
9446 }
9447 else
9448 {
9449 if (get_attr_mode (insn) == MODE_SI)
9450 return "sal{l}\t{%2, %k0|%k0, %2}";
9451 else
9452 return "sal{b}\t{%2, %0|%0, %2}";
9453 }
9454 }
9455 }
9456 [(set (attr "type")
9457 (cond [(eq_attr "alternative" "2")
9458 (const_string "lea")
9459 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9460 (match_operand 0 "register_operand"))
9461 (match_operand 2 "const1_operand"))
9462 (const_string "alu")
9463 ]
9464 (const_string "ishift")))
9465 (set (attr "length_immediate")
9466 (if_then_else
9467 (ior (eq_attr "type" "alu")
9468 (and (eq_attr "type" "ishift")
9469 (and (match_operand 2 "const1_operand")
9470 (ior (match_test "TARGET_SHIFT1")
9471 (match_test "optimize_function_for_size_p (cfun)")))))
9472 (const_string "0")
9473 (const_string "*")))
9474 (set_attr "mode" "QI,SI,SI")])
9475
9476 (define_insn "*ashlqi3_1_slp"
9477 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9478 (ashift:QI (match_dup 0)
9479 (match_operand:QI 1 "nonmemory_operand" "cI")))
9480 (clobber (reg:CC FLAGS_REG))]
9481 "(optimize_function_for_size_p (cfun)
9482 || !TARGET_PARTIAL_FLAG_REG_STALL
9483 || (operands[1] == const1_rtx
9484 && (TARGET_SHIFT1
9485 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9486 {
9487 switch (get_attr_type (insn))
9488 {
9489 case TYPE_ALU:
9490 gcc_assert (operands[1] == const1_rtx);
9491 return "add{b}\t%0, %0";
9492
9493 default:
9494 if (operands[1] == const1_rtx
9495 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9496 return "sal{b}\t%0";
9497 else
9498 return "sal{b}\t{%1, %0|%0, %1}";
9499 }
9500 }
9501 [(set (attr "type")
9502 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9503 (match_operand 0 "register_operand"))
9504 (match_operand 1 "const1_operand"))
9505 (const_string "alu")
9506 ]
9507 (const_string "ishift1")))
9508 (set (attr "length_immediate")
9509 (if_then_else
9510 (ior (eq_attr "type" "alu")
9511 (and (eq_attr "type" "ishift1")
9512 (and (match_operand 1 "const1_operand")
9513 (ior (match_test "TARGET_SHIFT1")
9514 (match_test "optimize_function_for_size_p (cfun)")))))
9515 (const_string "0")
9516 (const_string "*")))
9517 (set_attr "mode" "QI")])
9518
9519 ;; Convert ashift to the lea pattern to avoid flags dependency.
9520 (define_split
9521 [(set (match_operand 0 "register_operand")
9522 (ashift (match_operand 1 "index_register_operand")
9523 (match_operand:QI 2 "const_int_operand")))
9524 (clobber (reg:CC FLAGS_REG))]
9525 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9526 && reload_completed
9527 && true_regnum (operands[0]) != true_regnum (operands[1])"
9528 [(const_int 0)]
9529 {
9530 machine_mode mode = GET_MODE (operands[0]);
9531 rtx pat;
9532
9533 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9534 {
9535 mode = SImode;
9536 operands[0] = gen_lowpart (mode, operands[0]);
9537 operands[1] = gen_lowpart (mode, operands[1]);
9538 }
9539
9540 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9541
9542 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9543
9544 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9545 DONE;
9546 })
9547
9548 ;; Convert ashift to the lea pattern to avoid flags dependency.
9549 (define_split
9550 [(set (match_operand:DI 0 "register_operand")
9551 (zero_extend:DI
9552 (ashift:SI (match_operand:SI 1 "index_register_operand")
9553 (match_operand:QI 2 "const_int_operand"))))
9554 (clobber (reg:CC FLAGS_REG))]
9555 "TARGET_64BIT && reload_completed
9556 && true_regnum (operands[0]) != true_regnum (operands[1])"
9557 [(set (match_dup 0)
9558 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9559 {
9560 operands[1] = gen_lowpart (SImode, operands[1]);
9561 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9562 })
9563
9564 ;; This pattern can't accept a variable shift count, since shifts by
9565 ;; zero don't affect the flags. We assume that shifts by constant
9566 ;; zero are optimized away.
9567 (define_insn "*ashl<mode>3_cmp"
9568 [(set (reg FLAGS_REG)
9569 (compare
9570 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9571 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9572 (const_int 0)))
9573 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9574 (ashift:SWI (match_dup 1) (match_dup 2)))]
9575 "(optimize_function_for_size_p (cfun)
9576 || !TARGET_PARTIAL_FLAG_REG_STALL
9577 || (operands[2] == const1_rtx
9578 && (TARGET_SHIFT1
9579 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9580 && ix86_match_ccmode (insn, CCGOCmode)
9581 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9582 {
9583 switch (get_attr_type (insn))
9584 {
9585 case TYPE_ALU:
9586 gcc_assert (operands[2] == const1_rtx);
9587 return "add{<imodesuffix>}\t%0, %0";
9588
9589 default:
9590 if (operands[2] == const1_rtx
9591 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9592 return "sal{<imodesuffix>}\t%0";
9593 else
9594 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9595 }
9596 }
9597 [(set (attr "type")
9598 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9599 (match_operand 0 "register_operand"))
9600 (match_operand 2 "const1_operand"))
9601 (const_string "alu")
9602 ]
9603 (const_string "ishift")))
9604 (set (attr "length_immediate")
9605 (if_then_else
9606 (ior (eq_attr "type" "alu")
9607 (and (eq_attr "type" "ishift")
9608 (and (match_operand 2 "const1_operand")
9609 (ior (match_test "TARGET_SHIFT1")
9610 (match_test "optimize_function_for_size_p (cfun)")))))
9611 (const_string "0")
9612 (const_string "*")))
9613 (set_attr "mode" "<MODE>")])
9614
9615 (define_insn "*ashlsi3_cmp_zext"
9616 [(set (reg FLAGS_REG)
9617 (compare
9618 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9619 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9620 (const_int 0)))
9621 (set (match_operand:DI 0 "register_operand" "=r")
9622 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9623 "TARGET_64BIT
9624 && (optimize_function_for_size_p (cfun)
9625 || !TARGET_PARTIAL_FLAG_REG_STALL
9626 || (operands[2] == const1_rtx
9627 && (TARGET_SHIFT1
9628 || TARGET_DOUBLE_WITH_ADD)))
9629 && ix86_match_ccmode (insn, CCGOCmode)
9630 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9631 {
9632 switch (get_attr_type (insn))
9633 {
9634 case TYPE_ALU:
9635 gcc_assert (operands[2] == const1_rtx);
9636 return "add{l}\t%k0, %k0";
9637
9638 default:
9639 if (operands[2] == const1_rtx
9640 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9641 return "sal{l}\t%k0";
9642 else
9643 return "sal{l}\t{%2, %k0|%k0, %2}";
9644 }
9645 }
9646 [(set (attr "type")
9647 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9648 (match_operand 2 "const1_operand"))
9649 (const_string "alu")
9650 ]
9651 (const_string "ishift")))
9652 (set (attr "length_immediate")
9653 (if_then_else
9654 (ior (eq_attr "type" "alu")
9655 (and (eq_attr "type" "ishift")
9656 (and (match_operand 2 "const1_operand")
9657 (ior (match_test "TARGET_SHIFT1")
9658 (match_test "optimize_function_for_size_p (cfun)")))))
9659 (const_string "0")
9660 (const_string "*")))
9661 (set_attr "mode" "SI")])
9662
9663 (define_insn "*ashl<mode>3_cconly"
9664 [(set (reg FLAGS_REG)
9665 (compare
9666 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9667 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9668 (const_int 0)))
9669 (clobber (match_scratch:SWI 0 "=<r>"))]
9670 "(optimize_function_for_size_p (cfun)
9671 || !TARGET_PARTIAL_FLAG_REG_STALL
9672 || (operands[2] == const1_rtx
9673 && (TARGET_SHIFT1
9674 || TARGET_DOUBLE_WITH_ADD)))
9675 && ix86_match_ccmode (insn, CCGOCmode)"
9676 {
9677 switch (get_attr_type (insn))
9678 {
9679 case TYPE_ALU:
9680 gcc_assert (operands[2] == const1_rtx);
9681 return "add{<imodesuffix>}\t%0, %0";
9682
9683 default:
9684 if (operands[2] == const1_rtx
9685 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9686 return "sal{<imodesuffix>}\t%0";
9687 else
9688 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9689 }
9690 }
9691 [(set (attr "type")
9692 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9693 (match_operand 0 "register_operand"))
9694 (match_operand 2 "const1_operand"))
9695 (const_string "alu")
9696 ]
9697 (const_string "ishift")))
9698 (set (attr "length_immediate")
9699 (if_then_else
9700 (ior (eq_attr "type" "alu")
9701 (and (eq_attr "type" "ishift")
9702 (and (match_operand 2 "const1_operand")
9703 (ior (match_test "TARGET_SHIFT1")
9704 (match_test "optimize_function_for_size_p (cfun)")))))
9705 (const_string "0")
9706 (const_string "*")))
9707 (set_attr "mode" "<MODE>")])
9708
9709 ;; See comment above `ashl<mode>3' about how this works.
9710
9711 (define_expand "<shift_insn><mode>3"
9712 [(set (match_operand:SDWIM 0 "<shift_operand>")
9713 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9714 (match_operand:QI 2 "nonmemory_operand")))]
9715 ""
9716 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9717
9718 ;; Avoid useless masking of count operand.
9719 (define_insn "*<shift_insn><mode>3_mask"
9720 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9721 (any_shiftrt:SWI48
9722 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9723 (subreg:QI
9724 (and:SI
9725 (match_operand:SI 2 "register_operand" "c")
9726 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9727 (clobber (reg:CC FLAGS_REG))]
9728 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9729 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9730 == GET_MODE_BITSIZE (<MODE>mode)-1"
9731 {
9732 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9733 }
9734 [(set_attr "type" "ishift")
9735 (set_attr "mode" "<MODE>")])
9736
9737 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9738 [(set (match_operand:DWI 0 "register_operand" "=r")
9739 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9740 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9741 (clobber (reg:CC FLAGS_REG))]
9742 ""
9743 "#"
9744 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9745 [(const_int 0)]
9746 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9747 [(set_attr "type" "multi")])
9748
9749 ;; By default we don't ask for a scratch register, because when DWImode
9750 ;; values are manipulated, registers are already at a premium. But if
9751 ;; we have one handy, we won't turn it away.
9752
9753 (define_peephole2
9754 [(match_scratch:DWIH 3 "r")
9755 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9756 (any_shiftrt:<DWI>
9757 (match_operand:<DWI> 1 "register_operand")
9758 (match_operand:QI 2 "nonmemory_operand")))
9759 (clobber (reg:CC FLAGS_REG))])
9760 (match_dup 3)]
9761 "TARGET_CMOVE"
9762 [(const_int 0)]
9763 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9764
9765 (define_insn "x86_64_shrd"
9766 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9767 (ior:DI (lshiftrt:DI (match_dup 0)
9768 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9769 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9770 (minus:QI (const_int 64) (match_dup 2)))))
9771 (clobber (reg:CC FLAGS_REG))]
9772 "TARGET_64BIT"
9773 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9774 [(set_attr "type" "ishift")
9775 (set_attr "prefix_0f" "1")
9776 (set_attr "mode" "DI")
9777 (set_attr "athlon_decode" "vector")
9778 (set_attr "amdfam10_decode" "vector")
9779 (set_attr "bdver1_decode" "vector")])
9780
9781 (define_insn "x86_shrd"
9782 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9783 (ior:SI (lshiftrt:SI (match_dup 0)
9784 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9785 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9786 (minus:QI (const_int 32) (match_dup 2)))))
9787 (clobber (reg:CC FLAGS_REG))]
9788 ""
9789 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9790 [(set_attr "type" "ishift")
9791 (set_attr "prefix_0f" "1")
9792 (set_attr "mode" "SI")
9793 (set_attr "pent_pair" "np")
9794 (set_attr "athlon_decode" "vector")
9795 (set_attr "amdfam10_decode" "vector")
9796 (set_attr "bdver1_decode" "vector")])
9797
9798 (define_insn "ashrdi3_cvt"
9799 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9800 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9801 (match_operand:QI 2 "const_int_operand")))
9802 (clobber (reg:CC FLAGS_REG))]
9803 "TARGET_64BIT && INTVAL (operands[2]) == 63
9804 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9805 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9806 "@
9807 {cqto|cqo}
9808 sar{q}\t{%2, %0|%0, %2}"
9809 [(set_attr "type" "imovx,ishift")
9810 (set_attr "prefix_0f" "0,*")
9811 (set_attr "length_immediate" "0,*")
9812 (set_attr "modrm" "0,1")
9813 (set_attr "mode" "DI")])
9814
9815 (define_insn "ashrsi3_cvt"
9816 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9817 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9818 (match_operand:QI 2 "const_int_operand")))
9819 (clobber (reg:CC FLAGS_REG))]
9820 "INTVAL (operands[2]) == 31
9821 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9822 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9823 "@
9824 {cltd|cdq}
9825 sar{l}\t{%2, %0|%0, %2}"
9826 [(set_attr "type" "imovx,ishift")
9827 (set_attr "prefix_0f" "0,*")
9828 (set_attr "length_immediate" "0,*")
9829 (set_attr "modrm" "0,1")
9830 (set_attr "mode" "SI")])
9831
9832 (define_insn "*ashrsi3_cvt_zext"
9833 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9834 (zero_extend:DI
9835 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9836 (match_operand:QI 2 "const_int_operand"))))
9837 (clobber (reg:CC FLAGS_REG))]
9838 "TARGET_64BIT && INTVAL (operands[2]) == 31
9839 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9840 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9841 "@
9842 {cltd|cdq}
9843 sar{l}\t{%2, %k0|%k0, %2}"
9844 [(set_attr "type" "imovx,ishift")
9845 (set_attr "prefix_0f" "0,*")
9846 (set_attr "length_immediate" "0,*")
9847 (set_attr "modrm" "0,1")
9848 (set_attr "mode" "SI")])
9849
9850 (define_expand "x86_shift<mode>_adj_3"
9851 [(use (match_operand:SWI48 0 "register_operand"))
9852 (use (match_operand:SWI48 1 "register_operand"))
9853 (use (match_operand:QI 2 "register_operand"))]
9854 ""
9855 {
9856 rtx_code_label *label = gen_label_rtx ();
9857 rtx tmp;
9858
9859 emit_insn (gen_testqi_ccz_1 (operands[2],
9860 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9861
9862 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9863 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9864 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9865 gen_rtx_LABEL_REF (VOIDmode, label),
9866 pc_rtx);
9867 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9868 JUMP_LABEL (tmp) = label;
9869
9870 emit_move_insn (operands[0], operands[1]);
9871 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9872 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9873 emit_label (label);
9874 LABEL_NUSES (label) = 1;
9875
9876 DONE;
9877 })
9878
9879 (define_insn "*bmi2_<shift_insn><mode>3_1"
9880 [(set (match_operand:SWI48 0 "register_operand" "=r")
9881 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9882 (match_operand:SWI48 2 "register_operand" "r")))]
9883 "TARGET_BMI2"
9884 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9885 [(set_attr "type" "ishiftx")
9886 (set_attr "mode" "<MODE>")])
9887
9888 (define_insn "*<shift_insn><mode>3_1"
9889 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9890 (any_shiftrt:SWI48
9891 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9892 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9893 (clobber (reg:CC FLAGS_REG))]
9894 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9895 {
9896 switch (get_attr_type (insn))
9897 {
9898 case TYPE_ISHIFTX:
9899 return "#";
9900
9901 default:
9902 if (operands[2] == const1_rtx
9903 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9904 return "<shift>{<imodesuffix>}\t%0";
9905 else
9906 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9907 }
9908 }
9909 [(set_attr "isa" "*,bmi2")
9910 (set_attr "type" "ishift,ishiftx")
9911 (set (attr "length_immediate")
9912 (if_then_else
9913 (and (match_operand 2 "const1_operand")
9914 (ior (match_test "TARGET_SHIFT1")
9915 (match_test "optimize_function_for_size_p (cfun)")))
9916 (const_string "0")
9917 (const_string "*")))
9918 (set_attr "mode" "<MODE>")])
9919
9920 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9921 (define_split
9922 [(set (match_operand:SWI48 0 "register_operand")
9923 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9924 (match_operand:QI 2 "register_operand")))
9925 (clobber (reg:CC FLAGS_REG))]
9926 "TARGET_BMI2 && reload_completed"
9927 [(set (match_dup 0)
9928 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9929 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9930
9931 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9932 [(set (match_operand:DI 0 "register_operand" "=r")
9933 (zero_extend:DI
9934 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9935 (match_operand:SI 2 "register_operand" "r"))))]
9936 "TARGET_64BIT && TARGET_BMI2"
9937 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9938 [(set_attr "type" "ishiftx")
9939 (set_attr "mode" "SI")])
9940
9941 (define_insn "*<shift_insn>si3_1_zext"
9942 [(set (match_operand:DI 0 "register_operand" "=r,r")
9943 (zero_extend:DI
9944 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9945 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9946 (clobber (reg:CC FLAGS_REG))]
9947 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9948 {
9949 switch (get_attr_type (insn))
9950 {
9951 case TYPE_ISHIFTX:
9952 return "#";
9953
9954 default:
9955 if (operands[2] == const1_rtx
9956 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9957 return "<shift>{l}\t%k0";
9958 else
9959 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9960 }
9961 }
9962 [(set_attr "isa" "*,bmi2")
9963 (set_attr "type" "ishift,ishiftx")
9964 (set (attr "length_immediate")
9965 (if_then_else
9966 (and (match_operand 2 "const1_operand")
9967 (ior (match_test "TARGET_SHIFT1")
9968 (match_test "optimize_function_for_size_p (cfun)")))
9969 (const_string "0")
9970 (const_string "*")))
9971 (set_attr "mode" "SI")])
9972
9973 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9974 (define_split
9975 [(set (match_operand:DI 0 "register_operand")
9976 (zero_extend:DI
9977 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9978 (match_operand:QI 2 "register_operand"))))
9979 (clobber (reg:CC FLAGS_REG))]
9980 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9981 [(set (match_dup 0)
9982 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9983 "operands[2] = gen_lowpart (SImode, operands[2]);")
9984
9985 (define_insn "*<shift_insn><mode>3_1"
9986 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9987 (any_shiftrt:SWI12
9988 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9989 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9990 (clobber (reg:CC FLAGS_REG))]
9991 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9992 {
9993 if (operands[2] == const1_rtx
9994 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9995 return "<shift>{<imodesuffix>}\t%0";
9996 else
9997 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9998 }
9999 [(set_attr "type" "ishift")
10000 (set (attr "length_immediate")
10001 (if_then_else
10002 (and (match_operand 2 "const1_operand")
10003 (ior (match_test "TARGET_SHIFT1")
10004 (match_test "optimize_function_for_size_p (cfun)")))
10005 (const_string "0")
10006 (const_string "*")))
10007 (set_attr "mode" "<MODE>")])
10008
10009 (define_insn "*<shift_insn>qi3_1_slp"
10010 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10011 (any_shiftrt:QI (match_dup 0)
10012 (match_operand:QI 1 "nonmemory_operand" "cI")))
10013 (clobber (reg:CC FLAGS_REG))]
10014 "(optimize_function_for_size_p (cfun)
10015 || !TARGET_PARTIAL_REG_STALL
10016 || (operands[1] == const1_rtx
10017 && TARGET_SHIFT1))"
10018 {
10019 if (operands[1] == const1_rtx
10020 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10021 return "<shift>{b}\t%0";
10022 else
10023 return "<shift>{b}\t{%1, %0|%0, %1}";
10024 }
10025 [(set_attr "type" "ishift1")
10026 (set (attr "length_immediate")
10027 (if_then_else
10028 (and (match_operand 1 "const1_operand")
10029 (ior (match_test "TARGET_SHIFT1")
10030 (match_test "optimize_function_for_size_p (cfun)")))
10031 (const_string "0")
10032 (const_string "*")))
10033 (set_attr "mode" "QI")])
10034
10035 ;; This pattern can't accept a variable shift count, since shifts by
10036 ;; zero don't affect the flags. We assume that shifts by constant
10037 ;; zero are optimized away.
10038 (define_insn "*<shift_insn><mode>3_cmp"
10039 [(set (reg FLAGS_REG)
10040 (compare
10041 (any_shiftrt:SWI
10042 (match_operand:SWI 1 "nonimmediate_operand" "0")
10043 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10044 (const_int 0)))
10045 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10046 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10047 "(optimize_function_for_size_p (cfun)
10048 || !TARGET_PARTIAL_FLAG_REG_STALL
10049 || (operands[2] == const1_rtx
10050 && TARGET_SHIFT1))
10051 && ix86_match_ccmode (insn, CCGOCmode)
10052 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10053 {
10054 if (operands[2] == const1_rtx
10055 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10056 return "<shift>{<imodesuffix>}\t%0";
10057 else
10058 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10059 }
10060 [(set_attr "type" "ishift")
10061 (set (attr "length_immediate")
10062 (if_then_else
10063 (and (match_operand 2 "const1_operand")
10064 (ior (match_test "TARGET_SHIFT1")
10065 (match_test "optimize_function_for_size_p (cfun)")))
10066 (const_string "0")
10067 (const_string "*")))
10068 (set_attr "mode" "<MODE>")])
10069
10070 (define_insn "*<shift_insn>si3_cmp_zext"
10071 [(set (reg FLAGS_REG)
10072 (compare
10073 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10074 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10075 (const_int 0)))
10076 (set (match_operand:DI 0 "register_operand" "=r")
10077 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10078 "TARGET_64BIT
10079 && (optimize_function_for_size_p (cfun)
10080 || !TARGET_PARTIAL_FLAG_REG_STALL
10081 || (operands[2] == const1_rtx
10082 && TARGET_SHIFT1))
10083 && ix86_match_ccmode (insn, CCGOCmode)
10084 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10085 {
10086 if (operands[2] == const1_rtx
10087 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10088 return "<shift>{l}\t%k0";
10089 else
10090 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10091 }
10092 [(set_attr "type" "ishift")
10093 (set (attr "length_immediate")
10094 (if_then_else
10095 (and (match_operand 2 "const1_operand")
10096 (ior (match_test "TARGET_SHIFT1")
10097 (match_test "optimize_function_for_size_p (cfun)")))
10098 (const_string "0")
10099 (const_string "*")))
10100 (set_attr "mode" "SI")])
10101
10102 (define_insn "*<shift_insn><mode>3_cconly"
10103 [(set (reg FLAGS_REG)
10104 (compare
10105 (any_shiftrt:SWI
10106 (match_operand:SWI 1 "register_operand" "0")
10107 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10108 (const_int 0)))
10109 (clobber (match_scratch:SWI 0 "=<r>"))]
10110 "(optimize_function_for_size_p (cfun)
10111 || !TARGET_PARTIAL_FLAG_REG_STALL
10112 || (operands[2] == const1_rtx
10113 && TARGET_SHIFT1))
10114 && ix86_match_ccmode (insn, CCGOCmode)"
10115 {
10116 if (operands[2] == const1_rtx
10117 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10118 return "<shift>{<imodesuffix>}\t%0";
10119 else
10120 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10121 }
10122 [(set_attr "type" "ishift")
10123 (set (attr "length_immediate")
10124 (if_then_else
10125 (and (match_operand 2 "const1_operand")
10126 (ior (match_test "TARGET_SHIFT1")
10127 (match_test "optimize_function_for_size_p (cfun)")))
10128 (const_string "0")
10129 (const_string "*")))
10130 (set_attr "mode" "<MODE>")])
10131 \f
10132 ;; Rotate instructions
10133
10134 (define_expand "<rotate_insn>ti3"
10135 [(set (match_operand:TI 0 "register_operand")
10136 (any_rotate:TI (match_operand:TI 1 "register_operand")
10137 (match_operand:QI 2 "nonmemory_operand")))]
10138 "TARGET_64BIT"
10139 {
10140 if (const_1_to_63_operand (operands[2], VOIDmode))
10141 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10142 (operands[0], operands[1], operands[2]));
10143 else
10144 FAIL;
10145
10146 DONE;
10147 })
10148
10149 (define_expand "<rotate_insn>di3"
10150 [(set (match_operand:DI 0 "shiftdi_operand")
10151 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10152 (match_operand:QI 2 "nonmemory_operand")))]
10153 ""
10154 {
10155 if (TARGET_64BIT)
10156 ix86_expand_binary_operator (<CODE>, DImode, operands);
10157 else if (const_1_to_31_operand (operands[2], VOIDmode))
10158 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10159 (operands[0], operands[1], operands[2]));
10160 else
10161 FAIL;
10162
10163 DONE;
10164 })
10165
10166 (define_expand "<rotate_insn><mode>3"
10167 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10168 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10169 (match_operand:QI 2 "nonmemory_operand")))]
10170 ""
10171 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10172
10173 ;; Avoid useless masking of count operand.
10174 (define_insn "*<rotate_insn><mode>3_mask"
10175 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10176 (any_rotate:SWI48
10177 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10178 (subreg:QI
10179 (and:SI
10180 (match_operand:SI 2 "register_operand" "c")
10181 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10182 (clobber (reg:CC FLAGS_REG))]
10183 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10184 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10185 == GET_MODE_BITSIZE (<MODE>mode)-1"
10186 {
10187 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10188 }
10189 [(set_attr "type" "rotate")
10190 (set_attr "mode" "<MODE>")])
10191
10192 ;; Implement rotation using two double-precision
10193 ;; shift instructions and a scratch register.
10194
10195 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10196 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10197 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10198 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10199 (clobber (reg:CC FLAGS_REG))
10200 (clobber (match_scratch:DWIH 3 "=&r"))]
10201 ""
10202 "#"
10203 "reload_completed"
10204 [(set (match_dup 3) (match_dup 4))
10205 (parallel
10206 [(set (match_dup 4)
10207 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10208 (lshiftrt:DWIH (match_dup 5)
10209 (minus:QI (match_dup 6) (match_dup 2)))))
10210 (clobber (reg:CC FLAGS_REG))])
10211 (parallel
10212 [(set (match_dup 5)
10213 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10214 (lshiftrt:DWIH (match_dup 3)
10215 (minus:QI (match_dup 6) (match_dup 2)))))
10216 (clobber (reg:CC FLAGS_REG))])]
10217 {
10218 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10219
10220 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10221 })
10222
10223 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10224 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10225 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10226 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10227 (clobber (reg:CC FLAGS_REG))
10228 (clobber (match_scratch:DWIH 3 "=&r"))]
10229 ""
10230 "#"
10231 "reload_completed"
10232 [(set (match_dup 3) (match_dup 4))
10233 (parallel
10234 [(set (match_dup 4)
10235 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10236 (ashift:DWIH (match_dup 5)
10237 (minus:QI (match_dup 6) (match_dup 2)))))
10238 (clobber (reg:CC FLAGS_REG))])
10239 (parallel
10240 [(set (match_dup 5)
10241 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10242 (ashift:DWIH (match_dup 3)
10243 (minus:QI (match_dup 6) (match_dup 2)))))
10244 (clobber (reg:CC FLAGS_REG))])]
10245 {
10246 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10247
10248 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10249 })
10250
10251 (define_insn "*bmi2_rorx<mode>3_1"
10252 [(set (match_operand:SWI48 0 "register_operand" "=r")
10253 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10254 (match_operand:QI 2 "immediate_operand" "<S>")))]
10255 "TARGET_BMI2"
10256 "rorx\t{%2, %1, %0|%0, %1, %2}"
10257 [(set_attr "type" "rotatex")
10258 (set_attr "mode" "<MODE>")])
10259
10260 (define_insn "*<rotate_insn><mode>3_1"
10261 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10262 (any_rotate:SWI48
10263 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10264 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10265 (clobber (reg:CC FLAGS_REG))]
10266 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10267 {
10268 switch (get_attr_type (insn))
10269 {
10270 case TYPE_ROTATEX:
10271 return "#";
10272
10273 default:
10274 if (operands[2] == const1_rtx
10275 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10276 return "<rotate>{<imodesuffix>}\t%0";
10277 else
10278 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10279 }
10280 }
10281 [(set_attr "isa" "*,bmi2")
10282 (set_attr "type" "rotate,rotatex")
10283 (set (attr "length_immediate")
10284 (if_then_else
10285 (and (eq_attr "type" "rotate")
10286 (and (match_operand 2 "const1_operand")
10287 (ior (match_test "TARGET_SHIFT1")
10288 (match_test "optimize_function_for_size_p (cfun)"))))
10289 (const_string "0")
10290 (const_string "*")))
10291 (set_attr "mode" "<MODE>")])
10292
10293 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10294 (define_split
10295 [(set (match_operand:SWI48 0 "register_operand")
10296 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10297 (match_operand:QI 2 "immediate_operand")))
10298 (clobber (reg:CC FLAGS_REG))]
10299 "TARGET_BMI2 && reload_completed"
10300 [(set (match_dup 0)
10301 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10302 {
10303 operands[2]
10304 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10305 })
10306
10307 (define_split
10308 [(set (match_operand:SWI48 0 "register_operand")
10309 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10310 (match_operand:QI 2 "immediate_operand")))
10311 (clobber (reg:CC FLAGS_REG))]
10312 "TARGET_BMI2 && reload_completed"
10313 [(set (match_dup 0)
10314 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10315
10316 (define_insn "*bmi2_rorxsi3_1_zext"
10317 [(set (match_operand:DI 0 "register_operand" "=r")
10318 (zero_extend:DI
10319 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10320 (match_operand:QI 2 "immediate_operand" "I"))))]
10321 "TARGET_64BIT && TARGET_BMI2"
10322 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10323 [(set_attr "type" "rotatex")
10324 (set_attr "mode" "SI")])
10325
10326 (define_insn "*<rotate_insn>si3_1_zext"
10327 [(set (match_operand:DI 0 "register_operand" "=r,r")
10328 (zero_extend:DI
10329 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10330 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10331 (clobber (reg:CC FLAGS_REG))]
10332 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10333 {
10334 switch (get_attr_type (insn))
10335 {
10336 case TYPE_ROTATEX:
10337 return "#";
10338
10339 default:
10340 if (operands[2] == const1_rtx
10341 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10342 return "<rotate>{l}\t%k0";
10343 else
10344 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10345 }
10346 }
10347 [(set_attr "isa" "*,bmi2")
10348 (set_attr "type" "rotate,rotatex")
10349 (set (attr "length_immediate")
10350 (if_then_else
10351 (and (eq_attr "type" "rotate")
10352 (and (match_operand 2 "const1_operand")
10353 (ior (match_test "TARGET_SHIFT1")
10354 (match_test "optimize_function_for_size_p (cfun)"))))
10355 (const_string "0")
10356 (const_string "*")))
10357 (set_attr "mode" "SI")])
10358
10359 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10360 (define_split
10361 [(set (match_operand:DI 0 "register_operand")
10362 (zero_extend:DI
10363 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10364 (match_operand:QI 2 "immediate_operand"))))
10365 (clobber (reg:CC FLAGS_REG))]
10366 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10367 [(set (match_dup 0)
10368 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10369 {
10370 operands[2]
10371 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10372 })
10373
10374 (define_split
10375 [(set (match_operand:DI 0 "register_operand")
10376 (zero_extend:DI
10377 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10378 (match_operand:QI 2 "immediate_operand"))))
10379 (clobber (reg:CC FLAGS_REG))]
10380 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10381 [(set (match_dup 0)
10382 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10383
10384 (define_insn "*<rotate_insn><mode>3_1"
10385 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10386 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10387 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10388 (clobber (reg:CC FLAGS_REG))]
10389 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10390 {
10391 if (operands[2] == const1_rtx
10392 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10393 return "<rotate>{<imodesuffix>}\t%0";
10394 else
10395 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10396 }
10397 [(set_attr "type" "rotate")
10398 (set (attr "length_immediate")
10399 (if_then_else
10400 (and (match_operand 2 "const1_operand")
10401 (ior (match_test "TARGET_SHIFT1")
10402 (match_test "optimize_function_for_size_p (cfun)")))
10403 (const_string "0")
10404 (const_string "*")))
10405 (set_attr "mode" "<MODE>")])
10406
10407 (define_insn "*<rotate_insn>qi3_1_slp"
10408 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10409 (any_rotate:QI (match_dup 0)
10410 (match_operand:QI 1 "nonmemory_operand" "cI")))
10411 (clobber (reg:CC FLAGS_REG))]
10412 "(optimize_function_for_size_p (cfun)
10413 || !TARGET_PARTIAL_REG_STALL
10414 || (operands[1] == const1_rtx
10415 && TARGET_SHIFT1))"
10416 {
10417 if (operands[1] == const1_rtx
10418 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10419 return "<rotate>{b}\t%0";
10420 else
10421 return "<rotate>{b}\t{%1, %0|%0, %1}";
10422 }
10423 [(set_attr "type" "rotate1")
10424 (set (attr "length_immediate")
10425 (if_then_else
10426 (and (match_operand 1 "const1_operand")
10427 (ior (match_test "TARGET_SHIFT1")
10428 (match_test "optimize_function_for_size_p (cfun)")))
10429 (const_string "0")
10430 (const_string "*")))
10431 (set_attr "mode" "QI")])
10432
10433 (define_split
10434 [(set (match_operand:HI 0 "register_operand")
10435 (any_rotate:HI (match_dup 0) (const_int 8)))
10436 (clobber (reg:CC FLAGS_REG))]
10437 "reload_completed
10438 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10439 [(parallel [(set (strict_low_part (match_dup 0))
10440 (bswap:HI (match_dup 0)))
10441 (clobber (reg:CC FLAGS_REG))])])
10442 \f
10443 ;; Bit set / bit test instructions
10444
10445 (define_expand "extv"
10446 [(set (match_operand:SI 0 "register_operand")
10447 (sign_extract:SI (match_operand:SI 1 "register_operand")
10448 (match_operand:SI 2 "const8_operand")
10449 (match_operand:SI 3 "const8_operand")))]
10450 ""
10451 {
10452 /* Handle extractions from %ah et al. */
10453 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10454 FAIL;
10455
10456 /* From mips.md: extract_bit_field doesn't verify that our source
10457 matches the predicate, so check it again here. */
10458 if (! ext_register_operand (operands[1], VOIDmode))
10459 FAIL;
10460 })
10461
10462 (define_expand "extzv"
10463 [(set (match_operand:SI 0 "register_operand")
10464 (zero_extract:SI (match_operand 1 "ext_register_operand")
10465 (match_operand:SI 2 "const8_operand")
10466 (match_operand:SI 3 "const8_operand")))]
10467 ""
10468 {
10469 /* Handle extractions from %ah et al. */
10470 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10471 FAIL;
10472
10473 /* From mips.md: extract_bit_field doesn't verify that our source
10474 matches the predicate, so check it again here. */
10475 if (! ext_register_operand (operands[1], VOIDmode))
10476 FAIL;
10477 })
10478
10479 (define_expand "insv"
10480 [(set (zero_extract (match_operand 0 "register_operand")
10481 (match_operand 1 "const_int_operand")
10482 (match_operand 2 "const_int_operand"))
10483 (match_operand 3 "register_operand"))]
10484 ""
10485 {
10486 rtx (*gen_mov_insv_1) (rtx, rtx);
10487
10488 if (ix86_expand_pinsr (operands))
10489 DONE;
10490
10491 /* Handle insertions to %ah et al. */
10492 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10493 FAIL;
10494
10495 /* From mips.md: insert_bit_field doesn't verify that our source
10496 matches the predicate, so check it again here. */
10497 if (! ext_register_operand (operands[0], VOIDmode))
10498 FAIL;
10499
10500 gen_mov_insv_1 = (TARGET_64BIT
10501 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10502
10503 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10504 DONE;
10505 })
10506
10507 ;; %%% bts, btr, btc, bt.
10508 ;; In general these instructions are *slow* when applied to memory,
10509 ;; since they enforce atomic operation. When applied to registers,
10510 ;; it depends on the cpu implementation. They're never faster than
10511 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10512 ;; no point. But in 64-bit, we can't hold the relevant immediates
10513 ;; within the instruction itself, so operating on bits in the high
10514 ;; 32-bits of a register becomes easier.
10515 ;;
10516 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10517 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10518 ;; negdf respectively, so they can never be disabled entirely.
10519
10520 (define_insn "*btsq"
10521 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10522 (const_int 1)
10523 (match_operand:DI 1 "const_0_to_63_operand"))
10524 (const_int 1))
10525 (clobber (reg:CC FLAGS_REG))]
10526 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10527 "bts{q}\t{%1, %0|%0, %1}"
10528 [(set_attr "type" "alu1")
10529 (set_attr "prefix_0f" "1")
10530 (set_attr "mode" "DI")])
10531
10532 (define_insn "*btrq"
10533 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10534 (const_int 1)
10535 (match_operand:DI 1 "const_0_to_63_operand"))
10536 (const_int 0))
10537 (clobber (reg:CC FLAGS_REG))]
10538 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10539 "btr{q}\t{%1, %0|%0, %1}"
10540 [(set_attr "type" "alu1")
10541 (set_attr "prefix_0f" "1")
10542 (set_attr "mode" "DI")])
10543
10544 (define_insn "*btcq"
10545 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10546 (const_int 1)
10547 (match_operand:DI 1 "const_0_to_63_operand"))
10548 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10549 (clobber (reg:CC FLAGS_REG))]
10550 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10551 "btc{q}\t{%1, %0|%0, %1}"
10552 [(set_attr "type" "alu1")
10553 (set_attr "prefix_0f" "1")
10554 (set_attr "mode" "DI")])
10555
10556 ;; Allow Nocona to avoid these instructions if a register is available.
10557
10558 (define_peephole2
10559 [(match_scratch:DI 2 "r")
10560 (parallel [(set (zero_extract:DI
10561 (match_operand:DI 0 "register_operand")
10562 (const_int 1)
10563 (match_operand:DI 1 "const_0_to_63_operand"))
10564 (const_int 1))
10565 (clobber (reg:CC FLAGS_REG))])]
10566 "TARGET_64BIT && !TARGET_USE_BT"
10567 [(const_int 0)]
10568 {
10569 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10570 rtx op1;
10571
10572 if (HOST_BITS_PER_WIDE_INT >= 64)
10573 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10574 else if (i < HOST_BITS_PER_WIDE_INT)
10575 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10576 else
10577 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10578
10579 op1 = immed_double_const (lo, hi, DImode);
10580 if (i >= 31)
10581 {
10582 emit_move_insn (operands[2], op1);
10583 op1 = operands[2];
10584 }
10585
10586 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10587 DONE;
10588 })
10589
10590 (define_peephole2
10591 [(match_scratch:DI 2 "r")
10592 (parallel [(set (zero_extract:DI
10593 (match_operand:DI 0 "register_operand")
10594 (const_int 1)
10595 (match_operand:DI 1 "const_0_to_63_operand"))
10596 (const_int 0))
10597 (clobber (reg:CC FLAGS_REG))])]
10598 "TARGET_64BIT && !TARGET_USE_BT"
10599 [(const_int 0)]
10600 {
10601 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10602 rtx op1;
10603
10604 if (HOST_BITS_PER_WIDE_INT >= 64)
10605 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10606 else if (i < HOST_BITS_PER_WIDE_INT)
10607 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10608 else
10609 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10610
10611 op1 = immed_double_const (~lo, ~hi, DImode);
10612 if (i >= 32)
10613 {
10614 emit_move_insn (operands[2], op1);
10615 op1 = operands[2];
10616 }
10617
10618 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10619 DONE;
10620 })
10621
10622 (define_peephole2
10623 [(match_scratch:DI 2 "r")
10624 (parallel [(set (zero_extract:DI
10625 (match_operand:DI 0 "register_operand")
10626 (const_int 1)
10627 (match_operand:DI 1 "const_0_to_63_operand"))
10628 (not:DI (zero_extract:DI
10629 (match_dup 0) (const_int 1) (match_dup 1))))
10630 (clobber (reg:CC FLAGS_REG))])]
10631 "TARGET_64BIT && !TARGET_USE_BT"
10632 [(const_int 0)]
10633 {
10634 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10635 rtx op1;
10636
10637 if (HOST_BITS_PER_WIDE_INT >= 64)
10638 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10639 else if (i < HOST_BITS_PER_WIDE_INT)
10640 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10641 else
10642 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10643
10644 op1 = immed_double_const (lo, hi, DImode);
10645 if (i >= 31)
10646 {
10647 emit_move_insn (operands[2], op1);
10648 op1 = operands[2];
10649 }
10650
10651 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10652 DONE;
10653 })
10654
10655 (define_insn "*bt<mode>"
10656 [(set (reg:CCC FLAGS_REG)
10657 (compare:CCC
10658 (zero_extract:SWI48
10659 (match_operand:SWI48 0 "register_operand" "r")
10660 (const_int 1)
10661 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10662 (const_int 0)))]
10663 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10664 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10665 [(set_attr "type" "alu1")
10666 (set_attr "prefix_0f" "1")
10667 (set_attr "mode" "<MODE>")])
10668 \f
10669 ;; Store-flag instructions.
10670
10671 ;; For all sCOND expanders, also expand the compare or test insn that
10672 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10673
10674 (define_insn_and_split "*setcc_di_1"
10675 [(set (match_operand:DI 0 "register_operand" "=q")
10676 (match_operator:DI 1 "ix86_comparison_operator"
10677 [(reg FLAGS_REG) (const_int 0)]))]
10678 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10679 "#"
10680 "&& reload_completed"
10681 [(set (match_dup 2) (match_dup 1))
10682 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10683 {
10684 PUT_MODE (operands[1], QImode);
10685 operands[2] = gen_lowpart (QImode, operands[0]);
10686 })
10687
10688 (define_insn_and_split "*setcc_si_1_and"
10689 [(set (match_operand:SI 0 "register_operand" "=q")
10690 (match_operator:SI 1 "ix86_comparison_operator"
10691 [(reg FLAGS_REG) (const_int 0)]))
10692 (clobber (reg:CC FLAGS_REG))]
10693 "!TARGET_PARTIAL_REG_STALL
10694 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10695 "#"
10696 "&& reload_completed"
10697 [(set (match_dup 2) (match_dup 1))
10698 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10699 (clobber (reg:CC FLAGS_REG))])]
10700 {
10701 PUT_MODE (operands[1], QImode);
10702 operands[2] = gen_lowpart (QImode, operands[0]);
10703 })
10704
10705 (define_insn_and_split "*setcc_si_1_movzbl"
10706 [(set (match_operand:SI 0 "register_operand" "=q")
10707 (match_operator:SI 1 "ix86_comparison_operator"
10708 [(reg FLAGS_REG) (const_int 0)]))]
10709 "!TARGET_PARTIAL_REG_STALL
10710 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10711 "#"
10712 "&& reload_completed"
10713 [(set (match_dup 2) (match_dup 1))
10714 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10715 {
10716 PUT_MODE (operands[1], QImode);
10717 operands[2] = gen_lowpart (QImode, operands[0]);
10718 })
10719
10720 (define_insn "*setcc_qi"
10721 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10722 (match_operator:QI 1 "ix86_comparison_operator"
10723 [(reg FLAGS_REG) (const_int 0)]))]
10724 ""
10725 "set%C1\t%0"
10726 [(set_attr "type" "setcc")
10727 (set_attr "mode" "QI")])
10728
10729 (define_insn "*setcc_qi_slp"
10730 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10731 (match_operator:QI 1 "ix86_comparison_operator"
10732 [(reg FLAGS_REG) (const_int 0)]))]
10733 ""
10734 "set%C1\t%0"
10735 [(set_attr "type" "setcc")
10736 (set_attr "mode" "QI")])
10737
10738 ;; In general it is not safe to assume too much about CCmode registers,
10739 ;; so simplify-rtx stops when it sees a second one. Under certain
10740 ;; conditions this is safe on x86, so help combine not create
10741 ;;
10742 ;; seta %al
10743 ;; testb %al, %al
10744 ;; sete %al
10745
10746 (define_split
10747 [(set (match_operand:QI 0 "nonimmediate_operand")
10748 (ne:QI (match_operator 1 "ix86_comparison_operator"
10749 [(reg FLAGS_REG) (const_int 0)])
10750 (const_int 0)))]
10751 ""
10752 [(set (match_dup 0) (match_dup 1))]
10753 "PUT_MODE (operands[1], QImode);")
10754
10755 (define_split
10756 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10757 (ne:QI (match_operator 1 "ix86_comparison_operator"
10758 [(reg FLAGS_REG) (const_int 0)])
10759 (const_int 0)))]
10760 ""
10761 [(set (match_dup 0) (match_dup 1))]
10762 "PUT_MODE (operands[1], QImode);")
10763
10764 (define_split
10765 [(set (match_operand:QI 0 "nonimmediate_operand")
10766 (eq:QI (match_operator 1 "ix86_comparison_operator"
10767 [(reg FLAGS_REG) (const_int 0)])
10768 (const_int 0)))]
10769 ""
10770 [(set (match_dup 0) (match_dup 1))]
10771 {
10772 rtx new_op1 = copy_rtx (operands[1]);
10773 operands[1] = new_op1;
10774 PUT_MODE (new_op1, QImode);
10775 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10776 GET_MODE (XEXP (new_op1, 0))));
10777
10778 /* Make sure that (a) the CCmode we have for the flags is strong
10779 enough for the reversed compare or (b) we have a valid FP compare. */
10780 if (! ix86_comparison_operator (new_op1, VOIDmode))
10781 FAIL;
10782 })
10783
10784 (define_split
10785 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10786 (eq:QI (match_operator 1 "ix86_comparison_operator"
10787 [(reg FLAGS_REG) (const_int 0)])
10788 (const_int 0)))]
10789 ""
10790 [(set (match_dup 0) (match_dup 1))]
10791 {
10792 rtx new_op1 = copy_rtx (operands[1]);
10793 operands[1] = new_op1;
10794 PUT_MODE (new_op1, QImode);
10795 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10796 GET_MODE (XEXP (new_op1, 0))));
10797
10798 /* Make sure that (a) the CCmode we have for the flags is strong
10799 enough for the reversed compare or (b) we have a valid FP compare. */
10800 if (! ix86_comparison_operator (new_op1, VOIDmode))
10801 FAIL;
10802 })
10803
10804 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10805 ;; subsequent logical operations are used to imitate conditional moves.
10806 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10807 ;; it directly.
10808
10809 (define_insn "setcc_<mode>_sse"
10810 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10811 (match_operator:MODEF 3 "sse_comparison_operator"
10812 [(match_operand:MODEF 1 "register_operand" "0,x")
10813 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10814 "SSE_FLOAT_MODE_P (<MODE>mode)"
10815 "@
10816 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10817 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10818 [(set_attr "isa" "noavx,avx")
10819 (set_attr "type" "ssecmp")
10820 (set_attr "length_immediate" "1")
10821 (set_attr "prefix" "orig,vex")
10822 (set_attr "mode" "<MODE>")])
10823 \f
10824 ;; Basic conditional jump instructions.
10825 ;; We ignore the overflow flag for signed branch instructions.
10826
10827 (define_insn "*jcc_1"
10828 [(set (pc)
10829 (if_then_else (match_operator 1 "ix86_comparison_operator"
10830 [(reg FLAGS_REG) (const_int 0)])
10831 (label_ref (match_operand 0))
10832 (pc)))]
10833 ""
10834 "%!%+j%C1\t%l0"
10835 [(set_attr "type" "ibr")
10836 (set_attr "modrm" "0")
10837 (set (attr "length_nobnd")
10838 (if_then_else (and (ge (minus (match_dup 0) (pc))
10839 (const_int -126))
10840 (lt (minus (match_dup 0) (pc))
10841 (const_int 128)))
10842 (const_int 2)
10843 (const_int 6)))])
10844
10845 (define_insn "*jcc_2"
10846 [(set (pc)
10847 (if_then_else (match_operator 1 "ix86_comparison_operator"
10848 [(reg FLAGS_REG) (const_int 0)])
10849 (pc)
10850 (label_ref (match_operand 0))))]
10851 ""
10852 "%!%+j%c1\t%l0"
10853 [(set_attr "type" "ibr")
10854 (set_attr "modrm" "0")
10855 (set (attr "length_nobnd")
10856 (if_then_else (and (ge (minus (match_dup 0) (pc))
10857 (const_int -126))
10858 (lt (minus (match_dup 0) (pc))
10859 (const_int 128)))
10860 (const_int 2)
10861 (const_int 6)))])
10862
10863 ;; In general it is not safe to assume too much about CCmode registers,
10864 ;; so simplify-rtx stops when it sees a second one. Under certain
10865 ;; conditions this is safe on x86, so help combine not create
10866 ;;
10867 ;; seta %al
10868 ;; testb %al, %al
10869 ;; je Lfoo
10870
10871 (define_split
10872 [(set (pc)
10873 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10874 [(reg FLAGS_REG) (const_int 0)])
10875 (const_int 0))
10876 (label_ref (match_operand 1))
10877 (pc)))]
10878 ""
10879 [(set (pc)
10880 (if_then_else (match_dup 0)
10881 (label_ref (match_dup 1))
10882 (pc)))]
10883 "PUT_MODE (operands[0], VOIDmode);")
10884
10885 (define_split
10886 [(set (pc)
10887 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10888 [(reg FLAGS_REG) (const_int 0)])
10889 (const_int 0))
10890 (label_ref (match_operand 1))
10891 (pc)))]
10892 ""
10893 [(set (pc)
10894 (if_then_else (match_dup 0)
10895 (label_ref (match_dup 1))
10896 (pc)))]
10897 {
10898 rtx new_op0 = copy_rtx (operands[0]);
10899 operands[0] = new_op0;
10900 PUT_MODE (new_op0, VOIDmode);
10901 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10902 GET_MODE (XEXP (new_op0, 0))));
10903
10904 /* Make sure that (a) the CCmode we have for the flags is strong
10905 enough for the reversed compare or (b) we have a valid FP compare. */
10906 if (! ix86_comparison_operator (new_op0, VOIDmode))
10907 FAIL;
10908 })
10909
10910 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10911 ;; pass generates from shift insn with QImode operand. Actually, the mode
10912 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10913 ;; appropriate modulo of the bit offset value.
10914
10915 (define_insn_and_split "*jcc_bt<mode>"
10916 [(set (pc)
10917 (if_then_else (match_operator 0 "bt_comparison_operator"
10918 [(zero_extract:SWI48
10919 (match_operand:SWI48 1 "register_operand" "r")
10920 (const_int 1)
10921 (zero_extend:SI
10922 (match_operand:QI 2 "register_operand" "r")))
10923 (const_int 0)])
10924 (label_ref (match_operand 3))
10925 (pc)))
10926 (clobber (reg:CC FLAGS_REG))]
10927 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10928 "#"
10929 "&& 1"
10930 [(set (reg:CCC FLAGS_REG)
10931 (compare:CCC
10932 (zero_extract:SWI48
10933 (match_dup 1)
10934 (const_int 1)
10935 (match_dup 2))
10936 (const_int 0)))
10937 (set (pc)
10938 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10939 (label_ref (match_dup 3))
10940 (pc)))]
10941 {
10942 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10943
10944 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10945 })
10946
10947 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10948 ;; zero extended to SImode.
10949 (define_insn_and_split "*jcc_bt<mode>_1"
10950 [(set (pc)
10951 (if_then_else (match_operator 0 "bt_comparison_operator"
10952 [(zero_extract:SWI48
10953 (match_operand:SWI48 1 "register_operand" "r")
10954 (const_int 1)
10955 (match_operand:SI 2 "register_operand" "r"))
10956 (const_int 0)])
10957 (label_ref (match_operand 3))
10958 (pc)))
10959 (clobber (reg:CC FLAGS_REG))]
10960 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10961 "#"
10962 "&& 1"
10963 [(set (reg:CCC FLAGS_REG)
10964 (compare:CCC
10965 (zero_extract:SWI48
10966 (match_dup 1)
10967 (const_int 1)
10968 (match_dup 2))
10969 (const_int 0)))
10970 (set (pc)
10971 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10972 (label_ref (match_dup 3))
10973 (pc)))]
10974 {
10975 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10976
10977 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10978 })
10979
10980 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10981 ;; also for DImode, this is what combine produces.
10982 (define_insn_and_split "*jcc_bt<mode>_mask"
10983 [(set (pc)
10984 (if_then_else (match_operator 0 "bt_comparison_operator"
10985 [(zero_extract:SWI48
10986 (match_operand:SWI48 1 "register_operand" "r")
10987 (const_int 1)
10988 (and:SI
10989 (match_operand:SI 2 "register_operand" "r")
10990 (match_operand:SI 3 "const_int_operand" "n")))])
10991 (label_ref (match_operand 4))
10992 (pc)))
10993 (clobber (reg:CC FLAGS_REG))]
10994 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10995 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10996 == GET_MODE_BITSIZE (<MODE>mode)-1"
10997 "#"
10998 "&& 1"
10999 [(set (reg:CCC FLAGS_REG)
11000 (compare:CCC
11001 (zero_extract:SWI48
11002 (match_dup 1)
11003 (const_int 1)
11004 (match_dup 2))
11005 (const_int 0)))
11006 (set (pc)
11007 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11008 (label_ref (match_dup 4))
11009 (pc)))]
11010 {
11011 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11012
11013 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11014 })
11015
11016 (define_insn_and_split "*jcc_btsi_1"
11017 [(set (pc)
11018 (if_then_else (match_operator 0 "bt_comparison_operator"
11019 [(and:SI
11020 (lshiftrt:SI
11021 (match_operand:SI 1 "register_operand" "r")
11022 (match_operand:QI 2 "register_operand" "r"))
11023 (const_int 1))
11024 (const_int 0)])
11025 (label_ref (match_operand 3))
11026 (pc)))
11027 (clobber (reg:CC FLAGS_REG))]
11028 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11029 "#"
11030 "&& 1"
11031 [(set (reg:CCC FLAGS_REG)
11032 (compare:CCC
11033 (zero_extract:SI
11034 (match_dup 1)
11035 (const_int 1)
11036 (match_dup 2))
11037 (const_int 0)))
11038 (set (pc)
11039 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11040 (label_ref (match_dup 3))
11041 (pc)))]
11042 {
11043 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11044
11045 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11046 })
11047
11048 ;; avoid useless masking of bit offset operand
11049 (define_insn_and_split "*jcc_btsi_mask_1"
11050 [(set (pc)
11051 (if_then_else
11052 (match_operator 0 "bt_comparison_operator"
11053 [(and:SI
11054 (lshiftrt:SI
11055 (match_operand:SI 1 "register_operand" "r")
11056 (subreg:QI
11057 (and:SI
11058 (match_operand:SI 2 "register_operand" "r")
11059 (match_operand:SI 3 "const_int_operand" "n")) 0))
11060 (const_int 1))
11061 (const_int 0)])
11062 (label_ref (match_operand 4))
11063 (pc)))
11064 (clobber (reg:CC FLAGS_REG))]
11065 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11066 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11067 "#"
11068 "&& 1"
11069 [(set (reg:CCC FLAGS_REG)
11070 (compare:CCC
11071 (zero_extract:SI
11072 (match_dup 1)
11073 (const_int 1)
11074 (match_dup 2))
11075 (const_int 0)))
11076 (set (pc)
11077 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11078 (label_ref (match_dup 4))
11079 (pc)))]
11080 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11081
11082 ;; Define combination compare-and-branch fp compare instructions to help
11083 ;; combine.
11084
11085 (define_insn "*jcc<mode>_0_i387"
11086 [(set (pc)
11087 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11088 [(match_operand:X87MODEF 1 "register_operand" "f")
11089 (match_operand:X87MODEF 2 "const0_operand")])
11090 (label_ref (match_operand 3))
11091 (pc)))
11092 (clobber (reg:CCFP FPSR_REG))
11093 (clobber (reg:CCFP FLAGS_REG))
11094 (clobber (match_scratch:HI 4 "=a"))]
11095 "TARGET_80387 && !TARGET_CMOVE"
11096 "#")
11097
11098 (define_insn "*jcc<mode>_0_r_i387"
11099 [(set (pc)
11100 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11101 [(match_operand:X87MODEF 1 "register_operand" "f")
11102 (match_operand:X87MODEF 2 "const0_operand")])
11103 (pc)
11104 (label_ref (match_operand 3))))
11105 (clobber (reg:CCFP FPSR_REG))
11106 (clobber (reg:CCFP FLAGS_REG))
11107 (clobber (match_scratch:HI 4 "=a"))]
11108 "TARGET_80387 && !TARGET_CMOVE"
11109 "#")
11110
11111 (define_insn "*jccxf_i387"
11112 [(set (pc)
11113 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11114 [(match_operand:XF 1 "register_operand" "f")
11115 (match_operand:XF 2 "register_operand" "f")])
11116 (label_ref (match_operand 3))
11117 (pc)))
11118 (clobber (reg:CCFP FPSR_REG))
11119 (clobber (reg:CCFP FLAGS_REG))
11120 (clobber (match_scratch:HI 4 "=a"))]
11121 "TARGET_80387 && !TARGET_CMOVE"
11122 "#")
11123
11124 (define_insn "*jccxf_r_i387"
11125 [(set (pc)
11126 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11127 [(match_operand:XF 1 "register_operand" "f")
11128 (match_operand:XF 2 "register_operand" "f")])
11129 (pc)
11130 (label_ref (match_operand 3))))
11131 (clobber (reg:CCFP FPSR_REG))
11132 (clobber (reg:CCFP FLAGS_REG))
11133 (clobber (match_scratch:HI 4 "=a"))]
11134 "TARGET_80387 && !TARGET_CMOVE"
11135 "#")
11136
11137 (define_insn "*jcc<mode>_i387"
11138 [(set (pc)
11139 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11140 [(match_operand:MODEF 1 "register_operand" "f")
11141 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11142 (label_ref (match_operand 3))
11143 (pc)))
11144 (clobber (reg:CCFP FPSR_REG))
11145 (clobber (reg:CCFP FLAGS_REG))
11146 (clobber (match_scratch:HI 4 "=a"))]
11147 "TARGET_80387 && !TARGET_CMOVE"
11148 "#")
11149
11150 (define_insn "*jcc<mode>_r_i387"
11151 [(set (pc)
11152 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11153 [(match_operand:MODEF 1 "register_operand" "f")
11154 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11155 (pc)
11156 (label_ref (match_operand 3))))
11157 (clobber (reg:CCFP FPSR_REG))
11158 (clobber (reg:CCFP FLAGS_REG))
11159 (clobber (match_scratch:HI 4 "=a"))]
11160 "TARGET_80387 && !TARGET_CMOVE"
11161 "#")
11162
11163 (define_insn "*jccu<mode>_i387"
11164 [(set (pc)
11165 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11166 [(match_operand:X87MODEF 1 "register_operand" "f")
11167 (match_operand:X87MODEF 2 "register_operand" "f")])
11168 (label_ref (match_operand 3))
11169 (pc)))
11170 (clobber (reg:CCFP FPSR_REG))
11171 (clobber (reg:CCFP FLAGS_REG))
11172 (clobber (match_scratch:HI 4 "=a"))]
11173 "TARGET_80387 && !TARGET_CMOVE"
11174 "#")
11175
11176 (define_insn "*jccu<mode>_r_i387"
11177 [(set (pc)
11178 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11179 [(match_operand:X87MODEF 1 "register_operand" "f")
11180 (match_operand:X87MODEF 2 "register_operand" "f")])
11181 (pc)
11182 (label_ref (match_operand 3))))
11183 (clobber (reg:CCFP FPSR_REG))
11184 (clobber (reg:CCFP FLAGS_REG))
11185 (clobber (match_scratch:HI 4 "=a"))]
11186 "TARGET_80387 && !TARGET_CMOVE"
11187 "#")
11188
11189 (define_split
11190 [(set (pc)
11191 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11192 [(match_operand:X87MODEF 1 "register_operand")
11193 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11194 (match_operand 3)
11195 (match_operand 4)))
11196 (clobber (reg:CCFP FPSR_REG))
11197 (clobber (reg:CCFP FLAGS_REG))]
11198 "TARGET_80387 && !TARGET_CMOVE
11199 && reload_completed"
11200 [(const_int 0)]
11201 {
11202 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11203 operands[3], operands[4], NULL_RTX);
11204 DONE;
11205 })
11206
11207 (define_split
11208 [(set (pc)
11209 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11210 [(match_operand:X87MODEF 1 "register_operand")
11211 (match_operand:X87MODEF 2 "general_operand")])
11212 (match_operand 3)
11213 (match_operand 4)))
11214 (clobber (reg:CCFP FPSR_REG))
11215 (clobber (reg:CCFP FLAGS_REG))
11216 (clobber (match_scratch:HI 5))]
11217 "TARGET_80387 && !TARGET_CMOVE
11218 && reload_completed"
11219 [(const_int 0)]
11220 {
11221 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11222 operands[3], operands[4], operands[5]);
11223 DONE;
11224 })
11225
11226 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11227 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11228 ;; with a precedence over other operators and is always put in the first
11229 ;; place. Swap condition and operands to match ficom instruction.
11230
11231 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11232 [(set (pc)
11233 (if_then_else
11234 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11235 [(match_operator:X87MODEF 1 "float_operator"
11236 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11237 (match_operand:X87MODEF 3 "register_operand" "f")])
11238 (label_ref (match_operand 4))
11239 (pc)))
11240 (clobber (reg:CCFP FPSR_REG))
11241 (clobber (reg:CCFP FLAGS_REG))
11242 (clobber (match_scratch:HI 5 "=a"))]
11243 "TARGET_80387 && !TARGET_CMOVE
11244 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11245 || optimize_function_for_size_p (cfun))"
11246 "#")
11247
11248 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11249 [(set (pc)
11250 (if_then_else
11251 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11252 [(match_operator:X87MODEF 1 "float_operator"
11253 [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11254 (match_operand:X87MODEF 3 "register_operand" "f")])
11255 (pc)
11256 (label_ref (match_operand 4))))
11257 (clobber (reg:CCFP FPSR_REG))
11258 (clobber (reg:CCFP FLAGS_REG))
11259 (clobber (match_scratch:HI 5 "=a"))]
11260 "TARGET_80387 && !TARGET_CMOVE
11261 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11262 || optimize_function_for_size_p (cfun))"
11263 "#")
11264
11265 (define_split
11266 [(set (pc)
11267 (if_then_else
11268 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11269 [(match_operator:X87MODEF 1 "float_operator"
11270 [(match_operand:SWI24 2 "memory_operand")])
11271 (match_operand:X87MODEF 3 "register_operand")])
11272 (match_operand 4)
11273 (match_operand 5)))
11274 (clobber (reg:CCFP FPSR_REG))
11275 (clobber (reg:CCFP FLAGS_REG))
11276 (clobber (match_scratch:HI 6))]
11277 "TARGET_80387 && !TARGET_CMOVE
11278 && reload_completed"
11279 [(const_int 0)]
11280 {
11281 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11282 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11283 operands[4], operands[5], operands[6]);
11284 DONE;
11285 })
11286 \f
11287 ;; Unconditional and other jump instructions
11288
11289 (define_insn "jump"
11290 [(set (pc)
11291 (label_ref (match_operand 0)))]
11292 ""
11293 "%!jmp\t%l0"
11294 [(set_attr "type" "ibr")
11295 (set (attr "length_nobnd")
11296 (if_then_else (and (ge (minus (match_dup 0) (pc))
11297 (const_int -126))
11298 (lt (minus (match_dup 0) (pc))
11299 (const_int 128)))
11300 (const_int 2)
11301 (const_int 5)))
11302 (set_attr "modrm" "0")])
11303
11304 (define_expand "indirect_jump"
11305 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11306 ""
11307 {
11308 if (TARGET_X32)
11309 operands[0] = convert_memory_address (word_mode, operands[0]);
11310 })
11311
11312 (define_insn "*indirect_jump"
11313 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11314 ""
11315 "%!jmp\t%A0"
11316 [(set_attr "type" "ibr")
11317 (set_attr "length_immediate" "0")])
11318
11319 (define_expand "tablejump"
11320 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11321 (use (label_ref (match_operand 1)))])]
11322 ""
11323 {
11324 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11325 relative. Convert the relative address to an absolute address. */
11326 if (flag_pic)
11327 {
11328 rtx op0, op1;
11329 enum rtx_code code;
11330
11331 /* We can't use @GOTOFF for text labels on VxWorks;
11332 see gotoff_operand. */
11333 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11334 {
11335 code = PLUS;
11336 op0 = operands[0];
11337 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11338 }
11339 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11340 {
11341 code = PLUS;
11342 op0 = operands[0];
11343 op1 = pic_offset_table_rtx;
11344 }
11345 else
11346 {
11347 code = MINUS;
11348 op0 = pic_offset_table_rtx;
11349 op1 = operands[0];
11350 }
11351
11352 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11353 OPTAB_DIRECT);
11354 }
11355
11356 if (TARGET_X32)
11357 operands[0] = convert_memory_address (word_mode, operands[0]);
11358 })
11359
11360 (define_insn "*tablejump_1"
11361 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11362 (use (label_ref (match_operand 1)))]
11363 ""
11364 "%!jmp\t%A0"
11365 [(set_attr "type" "ibr")
11366 (set_attr "length_immediate" "0")])
11367 \f
11368 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11369
11370 (define_peephole2
11371 [(set (reg FLAGS_REG) (match_operand 0))
11372 (set (match_operand:QI 1 "register_operand")
11373 (match_operator:QI 2 "ix86_comparison_operator"
11374 [(reg FLAGS_REG) (const_int 0)]))
11375 (set (match_operand 3 "q_regs_operand")
11376 (zero_extend (match_dup 1)))]
11377 "(peep2_reg_dead_p (3, operands[1])
11378 || operands_match_p (operands[1], operands[3]))
11379 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11380 [(set (match_dup 4) (match_dup 0))
11381 (set (strict_low_part (match_dup 5))
11382 (match_dup 2))]
11383 {
11384 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11385 operands[5] = gen_lowpart (QImode, operands[3]);
11386 ix86_expand_clear (operands[3]);
11387 })
11388
11389 (define_peephole2
11390 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11391 (match_operand 4)])
11392 (set (match_operand:QI 1 "register_operand")
11393 (match_operator:QI 2 "ix86_comparison_operator"
11394 [(reg FLAGS_REG) (const_int 0)]))
11395 (set (match_operand 3 "q_regs_operand")
11396 (zero_extend (match_dup 1)))]
11397 "(peep2_reg_dead_p (3, operands[1])
11398 || operands_match_p (operands[1], operands[3]))
11399 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11400 [(parallel [(set (match_dup 5) (match_dup 0))
11401 (match_dup 4)])
11402 (set (strict_low_part (match_dup 6))
11403 (match_dup 2))]
11404 {
11405 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11406 operands[6] = gen_lowpart (QImode, operands[3]);
11407 ix86_expand_clear (operands[3]);
11408 })
11409
11410 ;; Similar, but match zero extend with andsi3.
11411
11412 (define_peephole2
11413 [(set (reg FLAGS_REG) (match_operand 0))
11414 (set (match_operand:QI 1 "register_operand")
11415 (match_operator:QI 2 "ix86_comparison_operator"
11416 [(reg FLAGS_REG) (const_int 0)]))
11417 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11418 (and:SI (match_dup 3) (const_int 255)))
11419 (clobber (reg:CC FLAGS_REG))])]
11420 "REGNO (operands[1]) == REGNO (operands[3])
11421 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11422 [(set (match_dup 4) (match_dup 0))
11423 (set (strict_low_part (match_dup 5))
11424 (match_dup 2))]
11425 {
11426 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11427 operands[5] = gen_lowpart (QImode, operands[3]);
11428 ix86_expand_clear (operands[3]);
11429 })
11430
11431 (define_peephole2
11432 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11433 (match_operand 4)])
11434 (set (match_operand:QI 1 "register_operand")
11435 (match_operator:QI 2 "ix86_comparison_operator"
11436 [(reg FLAGS_REG) (const_int 0)]))
11437 (parallel [(set (match_operand 3 "q_regs_operand")
11438 (zero_extend (match_dup 1)))
11439 (clobber (reg:CC FLAGS_REG))])]
11440 "(peep2_reg_dead_p (3, operands[1])
11441 || operands_match_p (operands[1], operands[3]))
11442 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11443 [(parallel [(set (match_dup 5) (match_dup 0))
11444 (match_dup 4)])
11445 (set (strict_low_part (match_dup 6))
11446 (match_dup 2))]
11447 {
11448 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11449 operands[6] = gen_lowpart (QImode, operands[3]);
11450 ix86_expand_clear (operands[3]);
11451 })
11452 \f
11453 ;; Call instructions.
11454
11455 ;; The predicates normally associated with named expanders are not properly
11456 ;; checked for calls. This is a bug in the generic code, but it isn't that
11457 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11458
11459 ;; P6 processors will jump to the address after the decrement when %esp
11460 ;; is used as a call operand, so they will execute return address as a code.
11461 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11462
11463 ;; Register constraint for call instruction.
11464 (define_mode_attr c [(SI "l") (DI "r")])
11465
11466 ;; Call subroutine returning no value.
11467
11468 (define_expand "call"
11469 [(call (match_operand:QI 0)
11470 (match_operand 1))
11471 (use (match_operand 2))]
11472 ""
11473 {
11474 ix86_expand_call (NULL, operands[0], operands[1],
11475 operands[2], NULL, false);
11476 DONE;
11477 })
11478
11479 (define_expand "sibcall"
11480 [(call (match_operand:QI 0)
11481 (match_operand 1))
11482 (use (match_operand 2))]
11483 ""
11484 {
11485 ix86_expand_call (NULL, operands[0], operands[1],
11486 operands[2], NULL, true);
11487 DONE;
11488 })
11489
11490 (define_insn "*call"
11491 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11492 (match_operand 1))]
11493 "!SIBLING_CALL_P (insn)"
11494 "* return ix86_output_call_insn (insn, operands[0]);"
11495 [(set_attr "type" "call")])
11496
11497 (define_insn "*sibcall"
11498 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11499 (match_operand 1))]
11500 "SIBLING_CALL_P (insn)"
11501 "* return ix86_output_call_insn (insn, operands[0]);"
11502 [(set_attr "type" "call")])
11503
11504 (define_insn "*sibcall_memory"
11505 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11506 (match_operand 1))
11507 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11508 "!TARGET_X32"
11509 "* return ix86_output_call_insn (insn, operands[0]);"
11510 [(set_attr "type" "call")])
11511
11512 (define_peephole2
11513 [(set (match_operand:W 0 "register_operand")
11514 (match_operand:W 1 "memory_operand"))
11515 (call (mem:QI (match_dup 0))
11516 (match_operand 3))]
11517 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11518 && peep2_reg_dead_p (2, operands[0])"
11519 [(parallel [(call (mem:QI (match_dup 1))
11520 (match_dup 3))
11521 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11522
11523 (define_peephole2
11524 [(set (match_operand:W 0 "register_operand")
11525 (match_operand:W 1 "memory_operand"))
11526 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11527 (call (mem:QI (match_dup 0))
11528 (match_operand 3))]
11529 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11530 && peep2_reg_dead_p (3, operands[0])"
11531 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11532 (parallel [(call (mem:QI (match_dup 1))
11533 (match_dup 3))
11534 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11535
11536 (define_expand "call_pop"
11537 [(parallel [(call (match_operand:QI 0)
11538 (match_operand:SI 1))
11539 (set (reg:SI SP_REG)
11540 (plus:SI (reg:SI SP_REG)
11541 (match_operand:SI 3)))])]
11542 "!TARGET_64BIT"
11543 {
11544 ix86_expand_call (NULL, operands[0], operands[1],
11545 operands[2], operands[3], false);
11546 DONE;
11547 })
11548
11549 (define_insn "*call_pop"
11550 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11551 (match_operand 1))
11552 (set (reg:SI SP_REG)
11553 (plus:SI (reg:SI SP_REG)
11554 (match_operand:SI 2 "immediate_operand" "i")))]
11555 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11556 "* return ix86_output_call_insn (insn, operands[0]);"
11557 [(set_attr "type" "call")])
11558
11559 (define_insn "*sibcall_pop"
11560 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11561 (match_operand 1))
11562 (set (reg:SI SP_REG)
11563 (plus:SI (reg:SI SP_REG)
11564 (match_operand:SI 2 "immediate_operand" "i")))]
11565 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11566 "* return ix86_output_call_insn (insn, operands[0]);"
11567 [(set_attr "type" "call")])
11568
11569 (define_insn "*sibcall_pop_memory"
11570 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11571 (match_operand 1))
11572 (set (reg:SI SP_REG)
11573 (plus:SI (reg:SI SP_REG)
11574 (match_operand:SI 2 "immediate_operand" "i")))
11575 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11576 "!TARGET_64BIT"
11577 "* return ix86_output_call_insn (insn, operands[0]);"
11578 [(set_attr "type" "call")])
11579
11580 (define_peephole2
11581 [(set (match_operand:SI 0 "register_operand")
11582 (match_operand:SI 1 "memory_operand"))
11583 (parallel [(call (mem:QI (match_dup 0))
11584 (match_operand 3))
11585 (set (reg:SI SP_REG)
11586 (plus:SI (reg:SI SP_REG)
11587 (match_operand:SI 4 "immediate_operand")))])]
11588 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11589 && peep2_reg_dead_p (2, operands[0])"
11590 [(parallel [(call (mem:QI (match_dup 1))
11591 (match_dup 3))
11592 (set (reg:SI SP_REG)
11593 (plus:SI (reg:SI SP_REG)
11594 (match_dup 4)))
11595 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11596
11597 (define_peephole2
11598 [(set (match_operand:SI 0 "register_operand")
11599 (match_operand:SI 1 "memory_operand"))
11600 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11601 (parallel [(call (mem:QI (match_dup 0))
11602 (match_operand 3))
11603 (set (reg:SI SP_REG)
11604 (plus:SI (reg:SI SP_REG)
11605 (match_operand:SI 4 "immediate_operand")))])]
11606 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11607 && peep2_reg_dead_p (3, operands[0])"
11608 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11609 (parallel [(call (mem:QI (match_dup 1))
11610 (match_dup 3))
11611 (set (reg:SI SP_REG)
11612 (plus:SI (reg:SI SP_REG)
11613 (match_dup 4)))
11614 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11615
11616 ;; Combining simple memory jump instruction
11617
11618 (define_peephole2
11619 [(set (match_operand:W 0 "register_operand")
11620 (match_operand:W 1 "memory_operand"))
11621 (set (pc) (match_dup 0))]
11622 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11623 [(set (pc) (match_dup 1))])
11624
11625 ;; Call subroutine, returning value in operand 0
11626
11627 (define_expand "call_value"
11628 [(set (match_operand 0)
11629 (call (match_operand:QI 1)
11630 (match_operand 2)))
11631 (use (match_operand 3))]
11632 ""
11633 {
11634 ix86_expand_call (operands[0], operands[1], operands[2],
11635 operands[3], NULL, false);
11636 DONE;
11637 })
11638
11639 (define_expand "sibcall_value"
11640 [(set (match_operand 0)
11641 (call (match_operand:QI 1)
11642 (match_operand 2)))
11643 (use (match_operand 3))]
11644 ""
11645 {
11646 ix86_expand_call (operands[0], operands[1], operands[2],
11647 operands[3], NULL, true);
11648 DONE;
11649 })
11650
11651 (define_insn "*call_value"
11652 [(set (match_operand 0)
11653 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11654 (match_operand 2)))]
11655 "!SIBLING_CALL_P (insn)"
11656 "* return ix86_output_call_insn (insn, operands[1]);"
11657 [(set_attr "type" "callv")])
11658
11659 (define_insn "*sibcall_value"
11660 [(set (match_operand 0)
11661 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11662 (match_operand 2)))]
11663 "SIBLING_CALL_P (insn)"
11664 "* return ix86_output_call_insn (insn, operands[1]);"
11665 [(set_attr "type" "callv")])
11666
11667 (define_insn "*sibcall_value_memory"
11668 [(set (match_operand 0)
11669 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11670 (match_operand 2)))
11671 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11672 "!TARGET_X32"
11673 "* return ix86_output_call_insn (insn, operands[1]);"
11674 [(set_attr "type" "callv")])
11675
11676 (define_peephole2
11677 [(set (match_operand:W 0 "register_operand")
11678 (match_operand:W 1 "memory_operand"))
11679 (set (match_operand 2)
11680 (call (mem:QI (match_dup 0))
11681 (match_operand 3)))]
11682 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11683 && peep2_reg_dead_p (2, operands[0])"
11684 [(parallel [(set (match_dup 2)
11685 (call (mem:QI (match_dup 1))
11686 (match_dup 3)))
11687 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11688
11689 (define_peephole2
11690 [(set (match_operand:W 0 "register_operand")
11691 (match_operand:W 1 "memory_operand"))
11692 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11693 (set (match_operand 2)
11694 (call (mem:QI (match_dup 0))
11695 (match_operand 3)))]
11696 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11697 && peep2_reg_dead_p (3, operands[0])"
11698 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11699 (parallel [(set (match_dup 2)
11700 (call (mem:QI (match_dup 1))
11701 (match_dup 3)))
11702 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11703
11704 (define_expand "call_value_pop"
11705 [(parallel [(set (match_operand 0)
11706 (call (match_operand:QI 1)
11707 (match_operand:SI 2)))
11708 (set (reg:SI SP_REG)
11709 (plus:SI (reg:SI SP_REG)
11710 (match_operand:SI 4)))])]
11711 "!TARGET_64BIT"
11712 {
11713 ix86_expand_call (operands[0], operands[1], operands[2],
11714 operands[3], operands[4], false);
11715 DONE;
11716 })
11717
11718 (define_insn "*call_value_pop"
11719 [(set (match_operand 0)
11720 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11721 (match_operand 2)))
11722 (set (reg:SI SP_REG)
11723 (plus:SI (reg:SI SP_REG)
11724 (match_operand:SI 3 "immediate_operand" "i")))]
11725 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11726 "* return ix86_output_call_insn (insn, operands[1]);"
11727 [(set_attr "type" "callv")])
11728
11729 (define_insn "*sibcall_value_pop"
11730 [(set (match_operand 0)
11731 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11732 (match_operand 2)))
11733 (set (reg:SI SP_REG)
11734 (plus:SI (reg:SI SP_REG)
11735 (match_operand:SI 3 "immediate_operand" "i")))]
11736 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11737 "* return ix86_output_call_insn (insn, operands[1]);"
11738 [(set_attr "type" "callv")])
11739
11740 (define_insn "*sibcall_value_pop_memory"
11741 [(set (match_operand 0)
11742 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11743 (match_operand 2)))
11744 (set (reg:SI SP_REG)
11745 (plus:SI (reg:SI SP_REG)
11746 (match_operand:SI 3 "immediate_operand" "i")))
11747 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11748 "!TARGET_64BIT"
11749 "* return ix86_output_call_insn (insn, operands[1]);"
11750 [(set_attr "type" "callv")])
11751
11752 (define_peephole2
11753 [(set (match_operand:SI 0 "register_operand")
11754 (match_operand:SI 1 "memory_operand"))
11755 (parallel [(set (match_operand 2)
11756 (call (mem:QI (match_dup 0))
11757 (match_operand 3)))
11758 (set (reg:SI SP_REG)
11759 (plus:SI (reg:SI SP_REG)
11760 (match_operand:SI 4 "immediate_operand")))])]
11761 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11762 && peep2_reg_dead_p (2, operands[0])"
11763 [(parallel [(set (match_dup 2)
11764 (call (mem:QI (match_dup 1))
11765 (match_dup 3)))
11766 (set (reg:SI SP_REG)
11767 (plus:SI (reg:SI SP_REG)
11768 (match_dup 4)))
11769 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11770
11771 (define_peephole2
11772 [(set (match_operand:SI 0 "register_operand")
11773 (match_operand:SI 1 "memory_operand"))
11774 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11775 (parallel [(set (match_operand 2)
11776 (call (mem:QI (match_dup 0))
11777 (match_operand 3)))
11778 (set (reg:SI SP_REG)
11779 (plus:SI (reg:SI SP_REG)
11780 (match_operand:SI 4 "immediate_operand")))])]
11781 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11782 && peep2_reg_dead_p (3, operands[0])"
11783 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11784 (parallel [(set (match_dup 2)
11785 (call (mem:QI (match_dup 1))
11786 (match_dup 3)))
11787 (set (reg:SI SP_REG)
11788 (plus:SI (reg:SI SP_REG)
11789 (match_dup 4)))
11790 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11791
11792 ;; Call subroutine returning any type.
11793
11794 (define_expand "untyped_call"
11795 [(parallel [(call (match_operand 0)
11796 (const_int 0))
11797 (match_operand 1)
11798 (match_operand 2)])]
11799 ""
11800 {
11801 int i;
11802
11803 /* In order to give reg-stack an easier job in validating two
11804 coprocessor registers as containing a possible return value,
11805 simply pretend the untyped call returns a complex long double
11806 value.
11807
11808 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11809 and should have the default ABI. */
11810
11811 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11812 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11813 operands[0], const0_rtx,
11814 GEN_INT ((TARGET_64BIT
11815 ? (ix86_abi == SYSV_ABI
11816 ? X86_64_SSE_REGPARM_MAX
11817 : X86_64_MS_SSE_REGPARM_MAX)
11818 : X86_32_SSE_REGPARM_MAX)
11819 - 1),
11820 NULL, false);
11821
11822 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11823 {
11824 rtx set = XVECEXP (operands[2], 0, i);
11825 emit_move_insn (SET_DEST (set), SET_SRC (set));
11826 }
11827
11828 /* The optimizer does not know that the call sets the function value
11829 registers we stored in the result block. We avoid problems by
11830 claiming that all hard registers are used and clobbered at this
11831 point. */
11832 emit_insn (gen_blockage ());
11833
11834 DONE;
11835 })
11836 \f
11837 ;; Prologue and epilogue instructions
11838
11839 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11840 ;; all of memory. This blocks insns from being moved across this point.
11841
11842 (define_insn "blockage"
11843 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11844 ""
11845 ""
11846 [(set_attr "length" "0")])
11847
11848 ;; Do not schedule instructions accessing memory across this point.
11849
11850 (define_expand "memory_blockage"
11851 [(set (match_dup 0)
11852 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11853 ""
11854 {
11855 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11856 MEM_VOLATILE_P (operands[0]) = 1;
11857 })
11858
11859 (define_insn "*memory_blockage"
11860 [(set (match_operand:BLK 0)
11861 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11862 ""
11863 ""
11864 [(set_attr "length" "0")])
11865
11866 ;; As USE insns aren't meaningful after reload, this is used instead
11867 ;; to prevent deleting instructions setting registers for PIC code
11868 (define_insn "prologue_use"
11869 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11870 ""
11871 ""
11872 [(set_attr "length" "0")])
11873
11874 ;; Insn emitted into the body of a function to return from a function.
11875 ;; This is only done if the function's epilogue is known to be simple.
11876 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11877
11878 (define_expand "return"
11879 [(simple_return)]
11880 "ix86_can_use_return_insn_p ()"
11881 {
11882 if (crtl->args.pops_args)
11883 {
11884 rtx popc = GEN_INT (crtl->args.pops_args);
11885 emit_jump_insn (gen_simple_return_pop_internal (popc));
11886 DONE;
11887 }
11888 })
11889
11890 ;; We need to disable this for TARGET_SEH, as otherwise
11891 ;; shrink-wrapped prologue gets enabled too. This might exceed
11892 ;; the maximum size of prologue in unwind information.
11893
11894 (define_expand "simple_return"
11895 [(simple_return)]
11896 "!TARGET_SEH"
11897 {
11898 if (crtl->args.pops_args)
11899 {
11900 rtx popc = GEN_INT (crtl->args.pops_args);
11901 emit_jump_insn (gen_simple_return_pop_internal (popc));
11902 DONE;
11903 }
11904 })
11905
11906 (define_insn "simple_return_internal"
11907 [(simple_return)]
11908 "reload_completed"
11909 "%!ret"
11910 [(set_attr "length_nobnd" "1")
11911 (set_attr "atom_unit" "jeu")
11912 (set_attr "length_immediate" "0")
11913 (set_attr "modrm" "0")])
11914
11915 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11916 ;; instruction Athlon and K8 have.
11917
11918 (define_insn "simple_return_internal_long"
11919 [(simple_return)
11920 (unspec [(const_int 0)] UNSPEC_REP)]
11921 "reload_completed"
11922 {
11923 if (ix86_bnd_prefixed_insn_p (insn))
11924 return "%!ret";
11925
11926 return "rep%; ret";
11927 }
11928 [(set_attr "length" "2")
11929 (set_attr "atom_unit" "jeu")
11930 (set_attr "length_immediate" "0")
11931 (set_attr "prefix_rep" "1")
11932 (set_attr "modrm" "0")])
11933
11934 (define_insn "simple_return_pop_internal"
11935 [(simple_return)
11936 (use (match_operand:SI 0 "const_int_operand"))]
11937 "reload_completed"
11938 "%!ret\t%0"
11939 [(set_attr "length_nobnd" "3")
11940 (set_attr "atom_unit" "jeu")
11941 (set_attr "length_immediate" "2")
11942 (set_attr "modrm" "0")])
11943
11944 (define_insn "simple_return_indirect_internal"
11945 [(simple_return)
11946 (use (match_operand:SI 0 "register_operand" "r"))]
11947 "reload_completed"
11948 "%!jmp\t%A0"
11949 [(set_attr "type" "ibr")
11950 (set_attr "length_immediate" "0")])
11951
11952 (define_insn "nop"
11953 [(const_int 0)]
11954 ""
11955 "nop"
11956 [(set_attr "length" "1")
11957 (set_attr "length_immediate" "0")
11958 (set_attr "modrm" "0")])
11959
11960 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11961 (define_insn "nops"
11962 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11963 UNSPECV_NOPS)]
11964 "reload_completed"
11965 {
11966 int num = INTVAL (operands[0]);
11967
11968 gcc_assert (IN_RANGE (num, 1, 8));
11969
11970 while (num--)
11971 fputs ("\tnop\n", asm_out_file);
11972
11973 return "";
11974 }
11975 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11976 (set_attr "length_immediate" "0")
11977 (set_attr "modrm" "0")])
11978
11979 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11980 ;; branch prediction penalty for the third jump in a 16-byte
11981 ;; block on K8.
11982
11983 (define_insn "pad"
11984 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11985 ""
11986 {
11987 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11988 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11989 #else
11990 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11991 The align insn is used to avoid 3 jump instructions in the row to improve
11992 branch prediction and the benefits hardly outweigh the cost of extra 8
11993 nops on the average inserted by full alignment pseudo operation. */
11994 #endif
11995 return "";
11996 }
11997 [(set_attr "length" "16")])
11998
11999 (define_expand "prologue"
12000 [(const_int 0)]
12001 ""
12002 "ix86_expand_prologue (); DONE;")
12003
12004 (define_insn "set_got"
12005 [(set (match_operand:SI 0 "register_operand" "=r")
12006 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12007 (clobber (reg:CC FLAGS_REG))]
12008 "!TARGET_64BIT"
12009 "* return output_set_got (operands[0], NULL_RTX);"
12010 [(set_attr "type" "multi")
12011 (set_attr "length" "12")])
12012
12013 (define_insn "set_got_labelled"
12014 [(set (match_operand:SI 0 "register_operand" "=r")
12015 (unspec:SI [(label_ref (match_operand 1))]
12016 UNSPEC_SET_GOT))
12017 (clobber (reg:CC FLAGS_REG))]
12018 "!TARGET_64BIT"
12019 "* return output_set_got (operands[0], operands[1]);"
12020 [(set_attr "type" "multi")
12021 (set_attr "length" "12")])
12022
12023 (define_insn "set_got_rex64"
12024 [(set (match_operand:DI 0 "register_operand" "=r")
12025 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12026 "TARGET_64BIT"
12027 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12028 [(set_attr "type" "lea")
12029 (set_attr "length_address" "4")
12030 (set_attr "mode" "DI")])
12031
12032 (define_insn "set_rip_rex64"
12033 [(set (match_operand:DI 0 "register_operand" "=r")
12034 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12035 "TARGET_64BIT"
12036 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12037 [(set_attr "type" "lea")
12038 (set_attr "length_address" "4")
12039 (set_attr "mode" "DI")])
12040
12041 (define_insn "set_got_offset_rex64"
12042 [(set (match_operand:DI 0 "register_operand" "=r")
12043 (unspec:DI
12044 [(label_ref (match_operand 1))]
12045 UNSPEC_SET_GOT_OFFSET))]
12046 "TARGET_LP64"
12047 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12048 [(set_attr "type" "imov")
12049 (set_attr "length_immediate" "0")
12050 (set_attr "length_address" "8")
12051 (set_attr "mode" "DI")])
12052
12053 (define_expand "epilogue"
12054 [(const_int 0)]
12055 ""
12056 "ix86_expand_epilogue (1); DONE;")
12057
12058 (define_expand "sibcall_epilogue"
12059 [(const_int 0)]
12060 ""
12061 "ix86_expand_epilogue (0); DONE;")
12062
12063 (define_expand "eh_return"
12064 [(use (match_operand 0 "register_operand"))]
12065 ""
12066 {
12067 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12068
12069 /* Tricky bit: we write the address of the handler to which we will
12070 be returning into someone else's stack frame, one word below the
12071 stack address we wish to restore. */
12072 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12073 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12074 tmp = gen_rtx_MEM (Pmode, tmp);
12075 emit_move_insn (tmp, ra);
12076
12077 emit_jump_insn (gen_eh_return_internal ());
12078 emit_barrier ();
12079 DONE;
12080 })
12081
12082 (define_insn_and_split "eh_return_internal"
12083 [(eh_return)]
12084 ""
12085 "#"
12086 "epilogue_completed"
12087 [(const_int 0)]
12088 "ix86_expand_epilogue (2); DONE;")
12089
12090 (define_insn "leave"
12091 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12092 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12093 (clobber (mem:BLK (scratch)))]
12094 "!TARGET_64BIT"
12095 "leave"
12096 [(set_attr "type" "leave")])
12097
12098 (define_insn "leave_rex64"
12099 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12100 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12101 (clobber (mem:BLK (scratch)))]
12102 "TARGET_64BIT"
12103 "leave"
12104 [(set_attr "type" "leave")])
12105 \f
12106 ;; Handle -fsplit-stack.
12107
12108 (define_expand "split_stack_prologue"
12109 [(const_int 0)]
12110 ""
12111 {
12112 ix86_expand_split_stack_prologue ();
12113 DONE;
12114 })
12115
12116 ;; In order to support the call/return predictor, we use a return
12117 ;; instruction which the middle-end doesn't see.
12118 (define_insn "split_stack_return"
12119 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12120 UNSPECV_SPLIT_STACK_RETURN)]
12121 ""
12122 {
12123 if (operands[0] == const0_rtx)
12124 return "ret";
12125 else
12126 return "ret\t%0";
12127 }
12128 [(set_attr "atom_unit" "jeu")
12129 (set_attr "modrm" "0")
12130 (set (attr "length")
12131 (if_then_else (match_operand:SI 0 "const0_operand")
12132 (const_int 1)
12133 (const_int 3)))
12134 (set (attr "length_immediate")
12135 (if_then_else (match_operand:SI 0 "const0_operand")
12136 (const_int 0)
12137 (const_int 2)))])
12138
12139 ;; If there are operand 0 bytes available on the stack, jump to
12140 ;; operand 1.
12141
12142 (define_expand "split_stack_space_check"
12143 [(set (pc) (if_then_else
12144 (ltu (minus (reg SP_REG)
12145 (match_operand 0 "register_operand"))
12146 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12147 (label_ref (match_operand 1))
12148 (pc)))]
12149 ""
12150 {
12151 rtx reg, size, limit;
12152
12153 reg = gen_reg_rtx (Pmode);
12154 size = force_reg (Pmode, operands[0]);
12155 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12156 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12157 UNSPEC_STACK_CHECK);
12158 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12159 ix86_expand_branch (GEU, reg, limit, operands[1]);
12160
12161 DONE;
12162 })
12163 \f
12164 ;; Bit manipulation instructions.
12165
12166 (define_expand "ffs<mode>2"
12167 [(set (match_dup 2) (const_int -1))
12168 (parallel [(set (match_dup 3) (match_dup 4))
12169 (set (match_operand:SWI48 0 "register_operand")
12170 (ctz:SWI48
12171 (match_operand:SWI48 1 "nonimmediate_operand")))])
12172 (set (match_dup 0) (if_then_else:SWI48
12173 (eq (match_dup 3) (const_int 0))
12174 (match_dup 2)
12175 (match_dup 0)))
12176 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12177 (clobber (reg:CC FLAGS_REG))])]
12178 ""
12179 {
12180 machine_mode flags_mode;
12181
12182 if (<MODE>mode == SImode && !TARGET_CMOVE)
12183 {
12184 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12185 DONE;
12186 }
12187
12188 flags_mode
12189 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12190
12191 operands[2] = gen_reg_rtx (<MODE>mode);
12192 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12193 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12194 })
12195
12196 (define_insn_and_split "ffssi2_no_cmove"
12197 [(set (match_operand:SI 0 "register_operand" "=r")
12198 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12199 (clobber (match_scratch:SI 2 "=&q"))
12200 (clobber (reg:CC FLAGS_REG))]
12201 "!TARGET_CMOVE"
12202 "#"
12203 "&& reload_completed"
12204 [(parallel [(set (match_dup 4) (match_dup 5))
12205 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12206 (set (strict_low_part (match_dup 3))
12207 (eq:QI (match_dup 4) (const_int 0)))
12208 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12209 (clobber (reg:CC FLAGS_REG))])
12210 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12211 (clobber (reg:CC FLAGS_REG))])
12212 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12213 (clobber (reg:CC FLAGS_REG))])]
12214 {
12215 machine_mode flags_mode
12216 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12217
12218 operands[3] = gen_lowpart (QImode, operands[2]);
12219 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12220 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12221
12222 ix86_expand_clear (operands[2]);
12223 })
12224
12225 (define_insn "*tzcnt<mode>_1"
12226 [(set (reg:CCC FLAGS_REG)
12227 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12228 (const_int 0)))
12229 (set (match_operand:SWI48 0 "register_operand" "=r")
12230 (ctz:SWI48 (match_dup 1)))]
12231 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12232 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12233 [(set_attr "type" "alu1")
12234 (set_attr "prefix_0f" "1")
12235 (set_attr "prefix_rep" "1")
12236 (set_attr "btver2_decode" "double")
12237 (set_attr "mode" "<MODE>")])
12238
12239 (define_insn "*bsf<mode>_1"
12240 [(set (reg:CCZ FLAGS_REG)
12241 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12242 (const_int 0)))
12243 (set (match_operand:SWI48 0 "register_operand" "=r")
12244 (ctz:SWI48 (match_dup 1)))]
12245 ""
12246 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12247 [(set_attr "type" "alu1")
12248 (set_attr "prefix_0f" "1")
12249 (set_attr "btver2_decode" "double")
12250 (set_attr "mode" "<MODE>")])
12251
12252 (define_expand "ctz<mode>2"
12253 [(parallel
12254 [(set (match_operand:SWI248 0 "register_operand")
12255 (ctz:SWI248
12256 (match_operand:SWI248 1 "nonimmediate_operand")))
12257 (clobber (reg:CC FLAGS_REG))])])
12258
12259 ; False dependency happens when destination is only updated by tzcnt,
12260 ; lzcnt or popcnt. There is no false dependency when destination is
12261 ; also used in source.
12262 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12263 [(set (match_operand:SWI48 0 "register_operand" "=r")
12264 (ctz:SWI48
12265 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12266 (clobber (reg:CC FLAGS_REG))]
12267 "(TARGET_BMI || TARGET_GENERIC)
12268 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12269 "#"
12270 "&& reload_completed"
12271 [(parallel
12272 [(set (match_dup 0)
12273 (ctz:SWI48 (match_dup 1)))
12274 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12275 (clobber (reg:CC FLAGS_REG))])]
12276 {
12277 if (!reg_mentioned_p (operands[0], operands[1]))
12278 ix86_expand_clear (operands[0]);
12279 })
12280
12281 (define_insn "*ctz<mode>2_falsedep"
12282 [(set (match_operand:SWI48 0 "register_operand" "=r")
12283 (ctz:SWI48
12284 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12285 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12286 UNSPEC_INSN_FALSE_DEP)
12287 (clobber (reg:CC FLAGS_REG))]
12288 ""
12289 {
12290 if (TARGET_BMI)
12291 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12292 else if (TARGET_GENERIC)
12293 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12294 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12295 else
12296 gcc_unreachable ();
12297 }
12298 [(set_attr "type" "alu1")
12299 (set_attr "prefix_0f" "1")
12300 (set_attr "prefix_rep" "1")
12301 (set_attr "mode" "<MODE>")])
12302
12303 (define_insn "*ctz<mode>2"
12304 [(set (match_operand:SWI248 0 "register_operand" "=r")
12305 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12306 (clobber (reg:CC FLAGS_REG))]
12307 ""
12308 {
12309 if (TARGET_BMI)
12310 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12311 else if (optimize_function_for_size_p (cfun))
12312 ;
12313 else if (TARGET_GENERIC)
12314 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12315 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12316
12317 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12318 }
12319 [(set_attr "type" "alu1")
12320 (set_attr "prefix_0f" "1")
12321 (set (attr "prefix_rep")
12322 (if_then_else
12323 (ior (match_test "TARGET_BMI")
12324 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12325 (match_test "TARGET_GENERIC")))
12326 (const_string "1")
12327 (const_string "0")))
12328 (set_attr "mode" "<MODE>")])
12329
12330 (define_expand "clz<mode>2"
12331 [(parallel
12332 [(set (match_operand:SWI248 0 "register_operand")
12333 (minus:SWI248
12334 (match_dup 2)
12335 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12336 (clobber (reg:CC FLAGS_REG))])
12337 (parallel
12338 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12339 (clobber (reg:CC FLAGS_REG))])]
12340 ""
12341 {
12342 if (TARGET_LZCNT)
12343 {
12344 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12345 DONE;
12346 }
12347 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12348 })
12349
12350 (define_expand "clz<mode>2_lzcnt"
12351 [(parallel
12352 [(set (match_operand:SWI248 0 "register_operand")
12353 (clz:SWI248
12354 (match_operand:SWI248 1 "nonimmediate_operand")))
12355 (clobber (reg:CC FLAGS_REG))])]
12356 "TARGET_LZCNT")
12357
12358 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12359 [(set (match_operand:SWI48 0 "register_operand" "=r")
12360 (clz:SWI48
12361 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12362 (clobber (reg:CC FLAGS_REG))]
12363 "TARGET_LZCNT
12364 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12365 "#"
12366 "&& reload_completed"
12367 [(parallel
12368 [(set (match_dup 0)
12369 (clz:SWI48 (match_dup 1)))
12370 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12371 (clobber (reg:CC FLAGS_REG))])]
12372 {
12373 if (!reg_mentioned_p (operands[0], operands[1]))
12374 ix86_expand_clear (operands[0]);
12375 })
12376
12377 (define_insn "*clz<mode>2_lzcnt_falsedep"
12378 [(set (match_operand:SWI48 0 "register_operand" "=r")
12379 (clz:SWI48
12380 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12381 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12382 UNSPEC_INSN_FALSE_DEP)
12383 (clobber (reg:CC FLAGS_REG))]
12384 "TARGET_LZCNT"
12385 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12386 [(set_attr "prefix_rep" "1")
12387 (set_attr "type" "bitmanip")
12388 (set_attr "mode" "<MODE>")])
12389
12390 (define_insn "*clz<mode>2_lzcnt"
12391 [(set (match_operand:SWI248 0 "register_operand" "=r")
12392 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12393 (clobber (reg:CC FLAGS_REG))]
12394 "TARGET_LZCNT"
12395 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12396 [(set_attr "prefix_rep" "1")
12397 (set_attr "type" "bitmanip")
12398 (set_attr "mode" "<MODE>")])
12399
12400 ;; BMI instructions.
12401 (define_insn "*bmi_andn_<mode>"
12402 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12403 (and:SWI48
12404 (not:SWI48
12405 (match_operand:SWI48 1 "register_operand" "r,r"))
12406 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12407 (clobber (reg:CC FLAGS_REG))]
12408 "TARGET_BMI"
12409 "andn\t{%2, %1, %0|%0, %1, %2}"
12410 [(set_attr "type" "bitmanip")
12411 (set_attr "btver2_decode" "direct, double")
12412 (set_attr "mode" "<MODE>")])
12413
12414 (define_insn "bmi_bextr_<mode>"
12415 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12416 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12417 (match_operand:SWI48 2 "register_operand" "r,r")]
12418 UNSPEC_BEXTR))
12419 (clobber (reg:CC FLAGS_REG))]
12420 "TARGET_BMI"
12421 "bextr\t{%2, %1, %0|%0, %1, %2}"
12422 [(set_attr "type" "bitmanip")
12423 (set_attr "btver2_decode" "direct, double")
12424 (set_attr "mode" "<MODE>")])
12425
12426 (define_insn "*bmi_blsi_<mode>"
12427 [(set (match_operand:SWI48 0 "register_operand" "=r")
12428 (and:SWI48
12429 (neg:SWI48
12430 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12431 (match_dup 1)))
12432 (clobber (reg:CC FLAGS_REG))]
12433 "TARGET_BMI"
12434 "blsi\t{%1, %0|%0, %1}"
12435 [(set_attr "type" "bitmanip")
12436 (set_attr "btver2_decode" "double")
12437 (set_attr "mode" "<MODE>")])
12438
12439 (define_insn "*bmi_blsmsk_<mode>"
12440 [(set (match_operand:SWI48 0 "register_operand" "=r")
12441 (xor:SWI48
12442 (plus:SWI48
12443 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12444 (const_int -1))
12445 (match_dup 1)))
12446 (clobber (reg:CC FLAGS_REG))]
12447 "TARGET_BMI"
12448 "blsmsk\t{%1, %0|%0, %1}"
12449 [(set_attr "type" "bitmanip")
12450 (set_attr "btver2_decode" "double")
12451 (set_attr "mode" "<MODE>")])
12452
12453 (define_insn "*bmi_blsr_<mode>"
12454 [(set (match_operand:SWI48 0 "register_operand" "=r")
12455 (and:SWI48
12456 (plus:SWI48
12457 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12458 (const_int -1))
12459 (match_dup 1)))
12460 (clobber (reg:CC FLAGS_REG))]
12461 "TARGET_BMI"
12462 "blsr\t{%1, %0|%0, %1}"
12463 [(set_attr "type" "bitmanip")
12464 (set_attr "btver2_decode" "double")
12465 (set_attr "mode" "<MODE>")])
12466
12467 ;; BMI2 instructions.
12468 (define_insn "bmi2_bzhi_<mode>3"
12469 [(set (match_operand:SWI48 0 "register_operand" "=r")
12470 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12471 (match_operand:SWI48 2 "register_operand" "r"))
12472 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12473 (clobber (reg:CC FLAGS_REG))]
12474 "TARGET_BMI2"
12475 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12476 [(set_attr "type" "bitmanip")
12477 (set_attr "prefix" "vex")
12478 (set_attr "mode" "<MODE>")])
12479
12480 (define_insn "bmi2_pdep_<mode>3"
12481 [(set (match_operand:SWI48 0 "register_operand" "=r")
12482 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12483 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12484 UNSPEC_PDEP))]
12485 "TARGET_BMI2"
12486 "pdep\t{%2, %1, %0|%0, %1, %2}"
12487 [(set_attr "type" "bitmanip")
12488 (set_attr "prefix" "vex")
12489 (set_attr "mode" "<MODE>")])
12490
12491 (define_insn "bmi2_pext_<mode>3"
12492 [(set (match_operand:SWI48 0 "register_operand" "=r")
12493 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12494 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12495 UNSPEC_PEXT))]
12496 "TARGET_BMI2"
12497 "pext\t{%2, %1, %0|%0, %1, %2}"
12498 [(set_attr "type" "bitmanip")
12499 (set_attr "prefix" "vex")
12500 (set_attr "mode" "<MODE>")])
12501
12502 ;; TBM instructions.
12503 (define_insn "tbm_bextri_<mode>"
12504 [(set (match_operand:SWI48 0 "register_operand" "=r")
12505 (zero_extract:SWI48
12506 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12507 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12508 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12509 (clobber (reg:CC FLAGS_REG))]
12510 "TARGET_TBM"
12511 {
12512 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12513 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12514 }
12515 [(set_attr "type" "bitmanip")
12516 (set_attr "mode" "<MODE>")])
12517
12518 (define_insn "*tbm_blcfill_<mode>"
12519 [(set (match_operand:SWI48 0 "register_operand" "=r")
12520 (and:SWI48
12521 (plus:SWI48
12522 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12523 (const_int 1))
12524 (match_dup 1)))
12525 (clobber (reg:CC FLAGS_REG))]
12526 "TARGET_TBM"
12527 "blcfill\t{%1, %0|%0, %1}"
12528 [(set_attr "type" "bitmanip")
12529 (set_attr "mode" "<MODE>")])
12530
12531 (define_insn "*tbm_blci_<mode>"
12532 [(set (match_operand:SWI48 0 "register_operand" "=r")
12533 (ior:SWI48
12534 (not:SWI48
12535 (plus:SWI48
12536 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12537 (const_int 1)))
12538 (match_dup 1)))
12539 (clobber (reg:CC FLAGS_REG))]
12540 "TARGET_TBM"
12541 "blci\t{%1, %0|%0, %1}"
12542 [(set_attr "type" "bitmanip")
12543 (set_attr "mode" "<MODE>")])
12544
12545 (define_insn "*tbm_blcic_<mode>"
12546 [(set (match_operand:SWI48 0 "register_operand" "=r")
12547 (and:SWI48
12548 (plus:SWI48
12549 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12550 (const_int 1))
12551 (not:SWI48
12552 (match_dup 1))))
12553 (clobber (reg:CC FLAGS_REG))]
12554 "TARGET_TBM"
12555 "blcic\t{%1, %0|%0, %1}"
12556 [(set_attr "type" "bitmanip")
12557 (set_attr "mode" "<MODE>")])
12558
12559 (define_insn "*tbm_blcmsk_<mode>"
12560 [(set (match_operand:SWI48 0 "register_operand" "=r")
12561 (xor:SWI48
12562 (plus:SWI48
12563 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12564 (const_int 1))
12565 (match_dup 1)))
12566 (clobber (reg:CC FLAGS_REG))]
12567 "TARGET_TBM"
12568 "blcmsk\t{%1, %0|%0, %1}"
12569 [(set_attr "type" "bitmanip")
12570 (set_attr "mode" "<MODE>")])
12571
12572 (define_insn "*tbm_blcs_<mode>"
12573 [(set (match_operand:SWI48 0 "register_operand" "=r")
12574 (ior:SWI48
12575 (plus:SWI48
12576 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12577 (const_int 1))
12578 (match_dup 1)))
12579 (clobber (reg:CC FLAGS_REG))]
12580 "TARGET_TBM"
12581 "blcs\t{%1, %0|%0, %1}"
12582 [(set_attr "type" "bitmanip")
12583 (set_attr "mode" "<MODE>")])
12584
12585 (define_insn "*tbm_blsfill_<mode>"
12586 [(set (match_operand:SWI48 0 "register_operand" "=r")
12587 (ior:SWI48
12588 (plus:SWI48
12589 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12590 (const_int -1))
12591 (match_dup 1)))
12592 (clobber (reg:CC FLAGS_REG))]
12593 "TARGET_TBM"
12594 "blsfill\t{%1, %0|%0, %1}"
12595 [(set_attr "type" "bitmanip")
12596 (set_attr "mode" "<MODE>")])
12597
12598 (define_insn "*tbm_blsic_<mode>"
12599 [(set (match_operand:SWI48 0 "register_operand" "=r")
12600 (ior:SWI48
12601 (plus:SWI48
12602 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12603 (const_int -1))
12604 (not:SWI48
12605 (match_dup 1))))
12606 (clobber (reg:CC FLAGS_REG))]
12607 "TARGET_TBM"
12608 "blsic\t{%1, %0|%0, %1}"
12609 [(set_attr "type" "bitmanip")
12610 (set_attr "mode" "<MODE>")])
12611
12612 (define_insn "*tbm_t1mskc_<mode>"
12613 [(set (match_operand:SWI48 0 "register_operand" "=r")
12614 (ior:SWI48
12615 (plus:SWI48
12616 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12617 (const_int 1))
12618 (not:SWI48
12619 (match_dup 1))))
12620 (clobber (reg:CC FLAGS_REG))]
12621 "TARGET_TBM"
12622 "t1mskc\t{%1, %0|%0, %1}"
12623 [(set_attr "type" "bitmanip")
12624 (set_attr "mode" "<MODE>")])
12625
12626 (define_insn "*tbm_tzmsk_<mode>"
12627 [(set (match_operand:SWI48 0 "register_operand" "=r")
12628 (and:SWI48
12629 (plus:SWI48
12630 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12631 (const_int -1))
12632 (not:SWI48
12633 (match_dup 1))))
12634 (clobber (reg:CC FLAGS_REG))]
12635 "TARGET_TBM"
12636 "tzmsk\t{%1, %0|%0, %1}"
12637 [(set_attr "type" "bitmanip")
12638 (set_attr "mode" "<MODE>")])
12639
12640 (define_insn "bsr_rex64"
12641 [(set (match_operand:DI 0 "register_operand" "=r")
12642 (minus:DI (const_int 63)
12643 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12644 (clobber (reg:CC FLAGS_REG))]
12645 "TARGET_64BIT"
12646 "bsr{q}\t{%1, %0|%0, %1}"
12647 [(set_attr "type" "alu1")
12648 (set_attr "prefix_0f" "1")
12649 (set_attr "mode" "DI")])
12650
12651 (define_insn "bsr"
12652 [(set (match_operand:SI 0 "register_operand" "=r")
12653 (minus:SI (const_int 31)
12654 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12655 (clobber (reg:CC FLAGS_REG))]
12656 ""
12657 "bsr{l}\t{%1, %0|%0, %1}"
12658 [(set_attr "type" "alu1")
12659 (set_attr "prefix_0f" "1")
12660 (set_attr "mode" "SI")])
12661
12662 (define_insn "*bsrhi"
12663 [(set (match_operand:HI 0 "register_operand" "=r")
12664 (minus:HI (const_int 15)
12665 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12666 (clobber (reg:CC FLAGS_REG))]
12667 ""
12668 "bsr{w}\t{%1, %0|%0, %1}"
12669 [(set_attr "type" "alu1")
12670 (set_attr "prefix_0f" "1")
12671 (set_attr "mode" "HI")])
12672
12673 (define_expand "popcount<mode>2"
12674 [(parallel
12675 [(set (match_operand:SWI248 0 "register_operand")
12676 (popcount:SWI248
12677 (match_operand:SWI248 1 "nonimmediate_operand")))
12678 (clobber (reg:CC FLAGS_REG))])]
12679 "TARGET_POPCNT")
12680
12681 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12682 [(set (match_operand:SWI48 0 "register_operand" "=r")
12683 (popcount:SWI48
12684 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12685 (clobber (reg:CC FLAGS_REG))]
12686 "TARGET_POPCNT
12687 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12688 "#"
12689 "&& reload_completed"
12690 [(parallel
12691 [(set (match_dup 0)
12692 (popcount:SWI48 (match_dup 1)))
12693 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12694 (clobber (reg:CC FLAGS_REG))])]
12695 {
12696 if (!reg_mentioned_p (operands[0], operands[1]))
12697 ix86_expand_clear (operands[0]);
12698 })
12699
12700 (define_insn "*popcount<mode>2_falsedep"
12701 [(set (match_operand:SWI48 0 "register_operand" "=r")
12702 (popcount:SWI48
12703 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12704 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12705 UNSPEC_INSN_FALSE_DEP)
12706 (clobber (reg:CC FLAGS_REG))]
12707 "TARGET_POPCNT"
12708 {
12709 #if TARGET_MACHO
12710 return "popcnt\t{%1, %0|%0, %1}";
12711 #else
12712 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12713 #endif
12714 }
12715 [(set_attr "prefix_rep" "1")
12716 (set_attr "type" "bitmanip")
12717 (set_attr "mode" "<MODE>")])
12718
12719 (define_insn "*popcount<mode>2"
12720 [(set (match_operand:SWI248 0 "register_operand" "=r")
12721 (popcount:SWI248
12722 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12723 (clobber (reg:CC FLAGS_REG))]
12724 "TARGET_POPCNT"
12725 {
12726 #if TARGET_MACHO
12727 return "popcnt\t{%1, %0|%0, %1}";
12728 #else
12729 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12730 #endif
12731 }
12732 [(set_attr "prefix_rep" "1")
12733 (set_attr "type" "bitmanip")
12734 (set_attr "mode" "<MODE>")])
12735
12736 (define_expand "bswapdi2"
12737 [(set (match_operand:DI 0 "register_operand")
12738 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12739 "TARGET_64BIT"
12740 {
12741 if (!TARGET_MOVBE)
12742 operands[1] = force_reg (DImode, operands[1]);
12743 })
12744
12745 (define_expand "bswapsi2"
12746 [(set (match_operand:SI 0 "register_operand")
12747 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12748 ""
12749 {
12750 if (TARGET_MOVBE)
12751 ;
12752 else if (TARGET_BSWAP)
12753 operands[1] = force_reg (SImode, operands[1]);
12754 else
12755 {
12756 rtx x = operands[0];
12757
12758 emit_move_insn (x, operands[1]);
12759 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12760 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12761 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12762 DONE;
12763 }
12764 })
12765
12766 (define_insn "*bswap<mode>2_movbe"
12767 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12768 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12769 "TARGET_MOVBE
12770 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12771 "@
12772 bswap\t%0
12773 movbe\t{%1, %0|%0, %1}
12774 movbe\t{%1, %0|%0, %1}"
12775 [(set_attr "type" "bitmanip,imov,imov")
12776 (set_attr "modrm" "0,1,1")
12777 (set_attr "prefix_0f" "*,1,1")
12778 (set_attr "prefix_extra" "*,1,1")
12779 (set_attr "mode" "<MODE>")])
12780
12781 (define_insn "*bswap<mode>2"
12782 [(set (match_operand:SWI48 0 "register_operand" "=r")
12783 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12784 "TARGET_BSWAP"
12785 "bswap\t%0"
12786 [(set_attr "type" "bitmanip")
12787 (set_attr "modrm" "0")
12788 (set_attr "mode" "<MODE>")])
12789
12790 (define_insn "*bswaphi_lowpart_1"
12791 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12792 (bswap:HI (match_dup 0)))
12793 (clobber (reg:CC FLAGS_REG))]
12794 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12795 "@
12796 xchg{b}\t{%h0, %b0|%b0, %h0}
12797 rol{w}\t{$8, %0|%0, 8}"
12798 [(set_attr "length" "2,4")
12799 (set_attr "mode" "QI,HI")])
12800
12801 (define_insn "bswaphi_lowpart"
12802 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12803 (bswap:HI (match_dup 0)))
12804 (clobber (reg:CC FLAGS_REG))]
12805 ""
12806 "rol{w}\t{$8, %0|%0, 8}"
12807 [(set_attr "length" "4")
12808 (set_attr "mode" "HI")])
12809
12810 (define_expand "paritydi2"
12811 [(set (match_operand:DI 0 "register_operand")
12812 (parity:DI (match_operand:DI 1 "register_operand")))]
12813 "! TARGET_POPCNT"
12814 {
12815 rtx scratch = gen_reg_rtx (QImode);
12816 rtx cond;
12817
12818 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12819 NULL_RTX, operands[1]));
12820
12821 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12822 gen_rtx_REG (CCmode, FLAGS_REG),
12823 const0_rtx);
12824 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12825
12826 if (TARGET_64BIT)
12827 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12828 else
12829 {
12830 rtx tmp = gen_reg_rtx (SImode);
12831
12832 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12833 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12834 }
12835 DONE;
12836 })
12837
12838 (define_expand "paritysi2"
12839 [(set (match_operand:SI 0 "register_operand")
12840 (parity:SI (match_operand:SI 1 "register_operand")))]
12841 "! TARGET_POPCNT"
12842 {
12843 rtx scratch = gen_reg_rtx (QImode);
12844 rtx cond;
12845
12846 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12847
12848 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12849 gen_rtx_REG (CCmode, FLAGS_REG),
12850 const0_rtx);
12851 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12852
12853 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12854 DONE;
12855 })
12856
12857 (define_insn_and_split "paritydi2_cmp"
12858 [(set (reg:CC FLAGS_REG)
12859 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12860 UNSPEC_PARITY))
12861 (clobber (match_scratch:DI 0 "=r"))
12862 (clobber (match_scratch:SI 1 "=&r"))
12863 (clobber (match_scratch:HI 2 "=Q"))]
12864 "! TARGET_POPCNT"
12865 "#"
12866 "&& reload_completed"
12867 [(parallel
12868 [(set (match_dup 1)
12869 (xor:SI (match_dup 1) (match_dup 4)))
12870 (clobber (reg:CC FLAGS_REG))])
12871 (parallel
12872 [(set (reg:CC FLAGS_REG)
12873 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12874 (clobber (match_dup 1))
12875 (clobber (match_dup 2))])]
12876 {
12877 operands[4] = gen_lowpart (SImode, operands[3]);
12878
12879 if (TARGET_64BIT)
12880 {
12881 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12882 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12883 }
12884 else
12885 operands[1] = gen_highpart (SImode, operands[3]);
12886 })
12887
12888 (define_insn_and_split "paritysi2_cmp"
12889 [(set (reg:CC FLAGS_REG)
12890 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12891 UNSPEC_PARITY))
12892 (clobber (match_scratch:SI 0 "=r"))
12893 (clobber (match_scratch:HI 1 "=&Q"))]
12894 "! TARGET_POPCNT"
12895 "#"
12896 "&& reload_completed"
12897 [(parallel
12898 [(set (match_dup 1)
12899 (xor:HI (match_dup 1) (match_dup 3)))
12900 (clobber (reg:CC FLAGS_REG))])
12901 (parallel
12902 [(set (reg:CC FLAGS_REG)
12903 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12904 (clobber (match_dup 1))])]
12905 {
12906 operands[3] = gen_lowpart (HImode, operands[2]);
12907
12908 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12909 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12910 })
12911
12912 (define_insn "*parityhi2_cmp"
12913 [(set (reg:CC FLAGS_REG)
12914 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12915 UNSPEC_PARITY))
12916 (clobber (match_scratch:HI 0 "=Q"))]
12917 "! TARGET_POPCNT"
12918 "xor{b}\t{%h0, %b0|%b0, %h0}"
12919 [(set_attr "length" "2")
12920 (set_attr "mode" "HI")])
12921
12922 \f
12923 ;; Thread-local storage patterns for ELF.
12924 ;;
12925 ;; Note that these code sequences must appear exactly as shown
12926 ;; in order to allow linker relaxation.
12927
12928 (define_insn "*tls_global_dynamic_32_gnu"
12929 [(set (match_operand:SI 0 "register_operand" "=a")
12930 (unspec:SI
12931 [(match_operand:SI 1 "register_operand" "b")
12932 (match_operand 2 "tls_symbolic_operand")
12933 (match_operand 3 "constant_call_address_operand" "Bz")
12934 (reg:SI SP_REG)]
12935 UNSPEC_TLS_GD))
12936 (clobber (match_scratch:SI 4 "=d"))
12937 (clobber (match_scratch:SI 5 "=c"))
12938 (clobber (reg:CC FLAGS_REG))]
12939 "!TARGET_64BIT && TARGET_GNU_TLS"
12940 {
12941 output_asm_insn
12942 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12943 if (TARGET_SUN_TLS)
12944 #ifdef HAVE_AS_IX86_TLSGDPLT
12945 return "call\t%a2@tlsgdplt";
12946 #else
12947 return "call\t%p3@plt";
12948 #endif
12949 return "call\t%P3";
12950 }
12951 [(set_attr "type" "multi")
12952 (set_attr "length" "12")])
12953
12954 (define_expand "tls_global_dynamic_32"
12955 [(parallel
12956 [(set (match_operand:SI 0 "register_operand")
12957 (unspec:SI [(match_operand:SI 2 "register_operand")
12958 (match_operand 1 "tls_symbolic_operand")
12959 (match_operand 3 "constant_call_address_operand")
12960 (reg:SI SP_REG)]
12961 UNSPEC_TLS_GD))
12962 (clobber (match_scratch:SI 4))
12963 (clobber (match_scratch:SI 5))
12964 (clobber (reg:CC FLAGS_REG))])]
12965 ""
12966 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12967
12968 (define_insn "*tls_global_dynamic_64_<mode>"
12969 [(set (match_operand:P 0 "register_operand" "=a")
12970 (call:P
12971 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
12972 (match_operand 3)))
12973 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12974 UNSPEC_TLS_GD)]
12975 "TARGET_64BIT"
12976 {
12977 if (!TARGET_X32)
12978 fputs (ASM_BYTE "0x66\n", asm_out_file);
12979 output_asm_insn
12980 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12981 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12982 fputs ("\trex64\n", asm_out_file);
12983 if (TARGET_SUN_TLS)
12984 return "call\t%p2@plt";
12985 return "call\t%P2";
12986 }
12987 [(set_attr "type" "multi")
12988 (set (attr "length")
12989 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12990
12991 (define_insn "*tls_global_dynamic_64_largepic"
12992 [(set (match_operand:DI 0 "register_operand" "=a")
12993 (call:DI
12994 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12995 (match_operand:DI 3 "immediate_operand" "i")))
12996 (match_operand 4)))
12997 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12998 UNSPEC_TLS_GD)]
12999 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13000 && GET_CODE (operands[3]) == CONST
13001 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13002 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13003 {
13004 output_asm_insn
13005 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13006 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13007 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13008 return "call\t{*%%rax|rax}";
13009 }
13010 [(set_attr "type" "multi")
13011 (set_attr "length" "22")])
13012
13013 (define_expand "tls_global_dynamic_64_<mode>"
13014 [(parallel
13015 [(set (match_operand:P 0 "register_operand")
13016 (call:P
13017 (mem:QI (match_operand 2))
13018 (const_int 0)))
13019 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13020 UNSPEC_TLS_GD)])]
13021 "TARGET_64BIT"
13022 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13023
13024 (define_insn "*tls_local_dynamic_base_32_gnu"
13025 [(set (match_operand:SI 0 "register_operand" "=a")
13026 (unspec:SI
13027 [(match_operand:SI 1 "register_operand" "b")
13028 (match_operand 2 "constant_call_address_operand" "Bz")
13029 (reg:SI SP_REG)]
13030 UNSPEC_TLS_LD_BASE))
13031 (clobber (match_scratch:SI 3 "=d"))
13032 (clobber (match_scratch:SI 4 "=c"))
13033 (clobber (reg:CC FLAGS_REG))]
13034 "!TARGET_64BIT && TARGET_GNU_TLS"
13035 {
13036 output_asm_insn
13037 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13038 if (TARGET_SUN_TLS)
13039 {
13040 if (HAVE_AS_IX86_TLSLDMPLT)
13041 return "call\t%&@tlsldmplt";
13042 else
13043 return "call\t%p2@plt";
13044 }
13045 return "call\t%P2";
13046 }
13047 [(set_attr "type" "multi")
13048 (set_attr "length" "11")])
13049
13050 (define_expand "tls_local_dynamic_base_32"
13051 [(parallel
13052 [(set (match_operand:SI 0 "register_operand")
13053 (unspec:SI
13054 [(match_operand:SI 1 "register_operand")
13055 (match_operand 2 "constant_call_address_operand")
13056 (reg:SI SP_REG)]
13057 UNSPEC_TLS_LD_BASE))
13058 (clobber (match_scratch:SI 3))
13059 (clobber (match_scratch:SI 4))
13060 (clobber (reg:CC FLAGS_REG))])]
13061 ""
13062 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13063
13064 (define_insn "*tls_local_dynamic_base_64_<mode>"
13065 [(set (match_operand:P 0 "register_operand" "=a")
13066 (call:P
13067 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13068 (match_operand 2)))
13069 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13070 "TARGET_64BIT"
13071 {
13072 output_asm_insn
13073 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13074 if (TARGET_SUN_TLS)
13075 return "call\t%p1@plt";
13076 return "call\t%P1";
13077 }
13078 [(set_attr "type" "multi")
13079 (set_attr "length" "12")])
13080
13081 (define_insn "*tls_local_dynamic_base_64_largepic"
13082 [(set (match_operand:DI 0 "register_operand" "=a")
13083 (call:DI
13084 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13085 (match_operand:DI 2 "immediate_operand" "i")))
13086 (match_operand 3)))
13087 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13088 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13089 && GET_CODE (operands[2]) == CONST
13090 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13091 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13092 {
13093 output_asm_insn
13094 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13095 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13096 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13097 return "call\t{*%%rax|rax}";
13098 }
13099 [(set_attr "type" "multi")
13100 (set_attr "length" "22")])
13101
13102 (define_expand "tls_local_dynamic_base_64_<mode>"
13103 [(parallel
13104 [(set (match_operand:P 0 "register_operand")
13105 (call:P
13106 (mem:QI (match_operand 1))
13107 (const_int 0)))
13108 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13109 "TARGET_64BIT"
13110 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13111
13112 ;; Local dynamic of a single variable is a lose. Show combine how
13113 ;; to convert that back to global dynamic.
13114
13115 (define_insn_and_split "*tls_local_dynamic_32_once"
13116 [(set (match_operand:SI 0 "register_operand" "=a")
13117 (plus:SI
13118 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13119 (match_operand 2 "constant_call_address_operand" "Bz")
13120 (reg:SI SP_REG)]
13121 UNSPEC_TLS_LD_BASE)
13122 (const:SI (unspec:SI
13123 [(match_operand 3 "tls_symbolic_operand")]
13124 UNSPEC_DTPOFF))))
13125 (clobber (match_scratch:SI 4 "=d"))
13126 (clobber (match_scratch:SI 5 "=c"))
13127 (clobber (reg:CC FLAGS_REG))]
13128 ""
13129 "#"
13130 ""
13131 [(parallel
13132 [(set (match_dup 0)
13133 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13134 (reg:SI SP_REG)]
13135 UNSPEC_TLS_GD))
13136 (clobber (match_dup 4))
13137 (clobber (match_dup 5))
13138 (clobber (reg:CC FLAGS_REG))])])
13139
13140 ;; Segment register for the thread base ptr load
13141 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13142
13143 ;; Load and add the thread base pointer from %<tp_seg>:0.
13144 (define_insn "*load_tp_x32"
13145 [(set (match_operand:SI 0 "register_operand" "=r")
13146 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13147 "TARGET_X32"
13148 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13149 [(set_attr "type" "imov")
13150 (set_attr "modrm" "0")
13151 (set_attr "length" "7")
13152 (set_attr "memory" "load")
13153 (set_attr "imm_disp" "false")])
13154
13155 (define_insn "*load_tp_x32_zext"
13156 [(set (match_operand:DI 0 "register_operand" "=r")
13157 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13158 "TARGET_X32"
13159 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13160 [(set_attr "type" "imov")
13161 (set_attr "modrm" "0")
13162 (set_attr "length" "7")
13163 (set_attr "memory" "load")
13164 (set_attr "imm_disp" "false")])
13165
13166 (define_insn "*load_tp_<mode>"
13167 [(set (match_operand:P 0 "register_operand" "=r")
13168 (unspec:P [(const_int 0)] UNSPEC_TP))]
13169 "!TARGET_X32"
13170 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13171 [(set_attr "type" "imov")
13172 (set_attr "modrm" "0")
13173 (set_attr "length" "7")
13174 (set_attr "memory" "load")
13175 (set_attr "imm_disp" "false")])
13176
13177 (define_insn "*add_tp_x32"
13178 [(set (match_operand:SI 0 "register_operand" "=r")
13179 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13180 (match_operand:SI 1 "register_operand" "0")))
13181 (clobber (reg:CC FLAGS_REG))]
13182 "TARGET_X32"
13183 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13184 [(set_attr "type" "alu")
13185 (set_attr "modrm" "0")
13186 (set_attr "length" "7")
13187 (set_attr "memory" "load")
13188 (set_attr "imm_disp" "false")])
13189
13190 (define_insn "*add_tp_x32_zext"
13191 [(set (match_operand:DI 0 "register_operand" "=r")
13192 (zero_extend:DI
13193 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13194 (match_operand:SI 1 "register_operand" "0"))))
13195 (clobber (reg:CC FLAGS_REG))]
13196 "TARGET_X32"
13197 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13198 [(set_attr "type" "alu")
13199 (set_attr "modrm" "0")
13200 (set_attr "length" "7")
13201 (set_attr "memory" "load")
13202 (set_attr "imm_disp" "false")])
13203
13204 (define_insn "*add_tp_<mode>"
13205 [(set (match_operand:P 0 "register_operand" "=r")
13206 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13207 (match_operand:P 1 "register_operand" "0")))
13208 (clobber (reg:CC FLAGS_REG))]
13209 "!TARGET_X32"
13210 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13211 [(set_attr "type" "alu")
13212 (set_attr "modrm" "0")
13213 (set_attr "length" "7")
13214 (set_attr "memory" "load")
13215 (set_attr "imm_disp" "false")])
13216
13217 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13218 ;; %rax as destination of the initial executable code sequence.
13219 (define_insn "tls_initial_exec_64_sun"
13220 [(set (match_operand:DI 0 "register_operand" "=a")
13221 (unspec:DI
13222 [(match_operand 1 "tls_symbolic_operand")]
13223 UNSPEC_TLS_IE_SUN))
13224 (clobber (reg:CC FLAGS_REG))]
13225 "TARGET_64BIT && TARGET_SUN_TLS"
13226 {
13227 output_asm_insn
13228 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13229 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13230 }
13231 [(set_attr "type" "multi")])
13232
13233 ;; GNU2 TLS patterns can be split.
13234
13235 (define_expand "tls_dynamic_gnu2_32"
13236 [(set (match_dup 3)
13237 (plus:SI (match_operand:SI 2 "register_operand")
13238 (const:SI
13239 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13240 UNSPEC_TLSDESC))))
13241 (parallel
13242 [(set (match_operand:SI 0 "register_operand")
13243 (unspec:SI [(match_dup 1) (match_dup 3)
13244 (match_dup 2) (reg:SI SP_REG)]
13245 UNSPEC_TLSDESC))
13246 (clobber (reg:CC FLAGS_REG))])]
13247 "!TARGET_64BIT && TARGET_GNU2_TLS"
13248 {
13249 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13250 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13251 })
13252
13253 (define_insn "*tls_dynamic_gnu2_lea_32"
13254 [(set (match_operand:SI 0 "register_operand" "=r")
13255 (plus:SI (match_operand:SI 1 "register_operand" "b")
13256 (const:SI
13257 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13258 UNSPEC_TLSDESC))))]
13259 "!TARGET_64BIT && TARGET_GNU2_TLS"
13260 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13261 [(set_attr "type" "lea")
13262 (set_attr "mode" "SI")
13263 (set_attr "length" "6")
13264 (set_attr "length_address" "4")])
13265
13266 (define_insn "*tls_dynamic_gnu2_call_32"
13267 [(set (match_operand:SI 0 "register_operand" "=a")
13268 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13269 (match_operand:SI 2 "register_operand" "0")
13270 ;; we have to make sure %ebx still points to the GOT
13271 (match_operand:SI 3 "register_operand" "b")
13272 (reg:SI SP_REG)]
13273 UNSPEC_TLSDESC))
13274 (clobber (reg:CC FLAGS_REG))]
13275 "!TARGET_64BIT && TARGET_GNU2_TLS"
13276 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13277 [(set_attr "type" "call")
13278 (set_attr "length" "2")
13279 (set_attr "length_address" "0")])
13280
13281 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13282 [(set (match_operand:SI 0 "register_operand" "=&a")
13283 (plus:SI
13284 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13285 (match_operand:SI 4)
13286 (match_operand:SI 2 "register_operand" "b")
13287 (reg:SI SP_REG)]
13288 UNSPEC_TLSDESC)
13289 (const:SI (unspec:SI
13290 [(match_operand 1 "tls_symbolic_operand")]
13291 UNSPEC_DTPOFF))))
13292 (clobber (reg:CC FLAGS_REG))]
13293 "!TARGET_64BIT && TARGET_GNU2_TLS"
13294 "#"
13295 ""
13296 [(set (match_dup 0) (match_dup 5))]
13297 {
13298 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13299 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13300 })
13301
13302 (define_expand "tls_dynamic_gnu2_64"
13303 [(set (match_dup 2)
13304 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13305 UNSPEC_TLSDESC))
13306 (parallel
13307 [(set (match_operand:DI 0 "register_operand")
13308 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13309 UNSPEC_TLSDESC))
13310 (clobber (reg:CC FLAGS_REG))])]
13311 "TARGET_64BIT && TARGET_GNU2_TLS"
13312 {
13313 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13314 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13315 })
13316
13317 (define_insn "*tls_dynamic_gnu2_lea_64"
13318 [(set (match_operand:DI 0 "register_operand" "=r")
13319 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13320 UNSPEC_TLSDESC))]
13321 "TARGET_64BIT && TARGET_GNU2_TLS"
13322 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13323 [(set_attr "type" "lea")
13324 (set_attr "mode" "DI")
13325 (set_attr "length" "7")
13326 (set_attr "length_address" "4")])
13327
13328 (define_insn "*tls_dynamic_gnu2_call_64"
13329 [(set (match_operand:DI 0 "register_operand" "=a")
13330 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13331 (match_operand:DI 2 "register_operand" "0")
13332 (reg:DI SP_REG)]
13333 UNSPEC_TLSDESC))
13334 (clobber (reg:CC FLAGS_REG))]
13335 "TARGET_64BIT && TARGET_GNU2_TLS"
13336 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13337 [(set_attr "type" "call")
13338 (set_attr "length" "2")
13339 (set_attr "length_address" "0")])
13340
13341 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13342 [(set (match_operand:DI 0 "register_operand" "=&a")
13343 (plus:DI
13344 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13345 (match_operand:DI 3)
13346 (reg:DI SP_REG)]
13347 UNSPEC_TLSDESC)
13348 (const:DI (unspec:DI
13349 [(match_operand 1 "tls_symbolic_operand")]
13350 UNSPEC_DTPOFF))))
13351 (clobber (reg:CC FLAGS_REG))]
13352 "TARGET_64BIT && TARGET_GNU2_TLS"
13353 "#"
13354 ""
13355 [(set (match_dup 0) (match_dup 4))]
13356 {
13357 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13358 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13359 })
13360 \f
13361 ;; These patterns match the binary 387 instructions for addM3, subM3,
13362 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13363 ;; SFmode. The first is the normal insn, the second the same insn but
13364 ;; with one operand a conversion, and the third the same insn but with
13365 ;; the other operand a conversion. The conversion may be SFmode or
13366 ;; SImode if the target mode DFmode, but only SImode if the target mode
13367 ;; is SFmode.
13368
13369 ;; Gcc is slightly more smart about handling normal two address instructions
13370 ;; so use special patterns for add and mull.
13371
13372 (define_insn "*fop_<mode>_comm_mixed"
13373 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13374 (match_operator:MODEF 3 "binary_fp_operator"
13375 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13376 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13377 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13378 && COMMUTATIVE_ARITH_P (operands[3])
13379 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13380 "* return output_387_binary_op (insn, operands);"
13381 [(set (attr "type")
13382 (if_then_else (eq_attr "alternative" "1,2")
13383 (if_then_else (match_operand:MODEF 3 "mult_operator")
13384 (const_string "ssemul")
13385 (const_string "sseadd"))
13386 (if_then_else (match_operand:MODEF 3 "mult_operator")
13387 (const_string "fmul")
13388 (const_string "fop"))))
13389 (set_attr "isa" "*,noavx,avx")
13390 (set_attr "prefix" "orig,orig,vex")
13391 (set_attr "mode" "<MODE>")])
13392
13393 (define_insn "*fop_<mode>_comm_sse"
13394 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13395 (match_operator:MODEF 3 "binary_fp_operator"
13396 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13397 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13398 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13399 && COMMUTATIVE_ARITH_P (operands[3])
13400 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13401 "* return output_387_binary_op (insn, operands);"
13402 [(set (attr "type")
13403 (if_then_else (match_operand:MODEF 3 "mult_operator")
13404 (const_string "ssemul")
13405 (const_string "sseadd")))
13406 (set_attr "isa" "noavx,avx")
13407 (set_attr "prefix" "orig,vex")
13408 (set_attr "mode" "<MODE>")])
13409
13410 (define_insn "*fop_<mode>_comm_i387"
13411 [(set (match_operand:MODEF 0 "register_operand" "=f")
13412 (match_operator:MODEF 3 "binary_fp_operator"
13413 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13414 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13415 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13416 && COMMUTATIVE_ARITH_P (operands[3])
13417 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13418 "* return output_387_binary_op (insn, operands);"
13419 [(set (attr "type")
13420 (if_then_else (match_operand:MODEF 3 "mult_operator")
13421 (const_string "fmul")
13422 (const_string "fop")))
13423 (set_attr "mode" "<MODE>")])
13424
13425 (define_insn "*fop_<mode>_1_mixed"
13426 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13427 (match_operator:MODEF 3 "binary_fp_operator"
13428 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13429 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13430 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13431 && !COMMUTATIVE_ARITH_P (operands[3])
13432 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13433 "* return output_387_binary_op (insn, operands);"
13434 [(set (attr "type")
13435 (cond [(and (eq_attr "alternative" "2,3")
13436 (match_operand:MODEF 3 "mult_operator"))
13437 (const_string "ssemul")
13438 (and (eq_attr "alternative" "2,3")
13439 (match_operand:MODEF 3 "div_operator"))
13440 (const_string "ssediv")
13441 (eq_attr "alternative" "2,3")
13442 (const_string "sseadd")
13443 (match_operand:MODEF 3 "mult_operator")
13444 (const_string "fmul")
13445 (match_operand:MODEF 3 "div_operator")
13446 (const_string "fdiv")
13447 ]
13448 (const_string "fop")))
13449 (set_attr "isa" "*,*,noavx,avx")
13450 (set_attr "prefix" "orig,orig,orig,vex")
13451 (set_attr "mode" "<MODE>")])
13452
13453 (define_insn "*rcpsf2_sse"
13454 [(set (match_operand:SF 0 "register_operand" "=x")
13455 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13456 UNSPEC_RCP))]
13457 "TARGET_SSE_MATH"
13458 "%vrcpss\t{%1, %d0|%d0, %1}"
13459 [(set_attr "type" "sse")
13460 (set_attr "atom_sse_attr" "rcp")
13461 (set_attr "btver2_sse_attr" "rcp")
13462 (set_attr "prefix" "maybe_vex")
13463 (set_attr "mode" "SF")])
13464
13465 (define_insn "*fop_<mode>_1_sse"
13466 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13467 (match_operator:MODEF 3 "binary_fp_operator"
13468 [(match_operand:MODEF 1 "register_operand" "0,x")
13469 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13470 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13471 && !COMMUTATIVE_ARITH_P (operands[3])"
13472 "* return output_387_binary_op (insn, operands);"
13473 [(set (attr "type")
13474 (cond [(match_operand:MODEF 3 "mult_operator")
13475 (const_string "ssemul")
13476 (match_operand:MODEF 3 "div_operator")
13477 (const_string "ssediv")
13478 ]
13479 (const_string "sseadd")))
13480 (set_attr "isa" "noavx,avx")
13481 (set_attr "prefix" "orig,vex")
13482 (set_attr "mode" "<MODE>")])
13483
13484 ;; This pattern is not fully shadowed by the pattern above.
13485 (define_insn "*fop_<mode>_1_i387"
13486 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13487 (match_operator:MODEF 3 "binary_fp_operator"
13488 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13489 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13490 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13491 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13492 && !COMMUTATIVE_ARITH_P (operands[3])
13493 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13494 "* return output_387_binary_op (insn, operands);"
13495 [(set (attr "type")
13496 (cond [(match_operand:MODEF 3 "mult_operator")
13497 (const_string "fmul")
13498 (match_operand:MODEF 3 "div_operator")
13499 (const_string "fdiv")
13500 ]
13501 (const_string "fop")))
13502 (set_attr "mode" "<MODE>")])
13503
13504 ;; ??? Add SSE splitters for these!
13505 (define_insn "*fop_<MODEF:mode>_2_i387"
13506 [(set (match_operand:MODEF 0 "register_operand" "=f")
13507 (match_operator:MODEF 3 "binary_fp_operator"
13508 [(float:MODEF
13509 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13510 (match_operand:MODEF 2 "register_operand" "0")]))]
13511 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13512 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13513 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13514 || optimize_function_for_size_p (cfun))"
13515 { return output_387_binary_op (insn, operands); }
13516 [(set (attr "type")
13517 (cond [(match_operand:MODEF 3 "mult_operator")
13518 (const_string "fmul")
13519 (match_operand:MODEF 3 "div_operator")
13520 (const_string "fdiv")
13521 ]
13522 (const_string "fop")))
13523 (set_attr "fp_int_src" "true")
13524 (set_attr "mode" "<SWI24:MODE>")])
13525
13526 (define_insn "*fop_<MODEF:mode>_3_i387"
13527 [(set (match_operand:MODEF 0 "register_operand" "=f")
13528 (match_operator:MODEF 3 "binary_fp_operator"
13529 [(match_operand:MODEF 1 "register_operand" "0")
13530 (float:MODEF
13531 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13532 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13533 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13534 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13535 || optimize_function_for_size_p (cfun))"
13536 { return output_387_binary_op (insn, operands); }
13537 [(set (attr "type")
13538 (cond [(match_operand:MODEF 3 "mult_operator")
13539 (const_string "fmul")
13540 (match_operand:MODEF 3 "div_operator")
13541 (const_string "fdiv")
13542 ]
13543 (const_string "fop")))
13544 (set_attr "fp_int_src" "true")
13545 (set_attr "mode" "<MODE>")])
13546
13547 (define_insn "*fop_df_4_i387"
13548 [(set (match_operand:DF 0 "register_operand" "=f,f")
13549 (match_operator:DF 3 "binary_fp_operator"
13550 [(float_extend:DF
13551 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13552 (match_operand:DF 2 "register_operand" "0,f")]))]
13553 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13554 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13555 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13556 "* return output_387_binary_op (insn, operands);"
13557 [(set (attr "type")
13558 (cond [(match_operand:DF 3 "mult_operator")
13559 (const_string "fmul")
13560 (match_operand:DF 3 "div_operator")
13561 (const_string "fdiv")
13562 ]
13563 (const_string "fop")))
13564 (set_attr "mode" "SF")])
13565
13566 (define_insn "*fop_df_5_i387"
13567 [(set (match_operand:DF 0 "register_operand" "=f,f")
13568 (match_operator:DF 3 "binary_fp_operator"
13569 [(match_operand:DF 1 "register_operand" "0,f")
13570 (float_extend:DF
13571 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13572 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13573 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13574 "* return output_387_binary_op (insn, operands);"
13575 [(set (attr "type")
13576 (cond [(match_operand:DF 3 "mult_operator")
13577 (const_string "fmul")
13578 (match_operand:DF 3 "div_operator")
13579 (const_string "fdiv")
13580 ]
13581 (const_string "fop")))
13582 (set_attr "mode" "SF")])
13583
13584 (define_insn "*fop_df_6_i387"
13585 [(set (match_operand:DF 0 "register_operand" "=f,f")
13586 (match_operator:DF 3 "binary_fp_operator"
13587 [(float_extend:DF
13588 (match_operand:SF 1 "register_operand" "0,f"))
13589 (float_extend:DF
13590 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13591 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13592 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13593 "* return output_387_binary_op (insn, operands);"
13594 [(set (attr "type")
13595 (cond [(match_operand:DF 3 "mult_operator")
13596 (const_string "fmul")
13597 (match_operand:DF 3 "div_operator")
13598 (const_string "fdiv")
13599 ]
13600 (const_string "fop")))
13601 (set_attr "mode" "SF")])
13602
13603 (define_insn "*fop_xf_comm_i387"
13604 [(set (match_operand:XF 0 "register_operand" "=f")
13605 (match_operator:XF 3 "binary_fp_operator"
13606 [(match_operand:XF 1 "register_operand" "%0")
13607 (match_operand:XF 2 "register_operand" "f")]))]
13608 "TARGET_80387
13609 && COMMUTATIVE_ARITH_P (operands[3])"
13610 "* return output_387_binary_op (insn, operands);"
13611 [(set (attr "type")
13612 (if_then_else (match_operand:XF 3 "mult_operator")
13613 (const_string "fmul")
13614 (const_string "fop")))
13615 (set_attr "mode" "XF")])
13616
13617 (define_insn "*fop_xf_1_i387"
13618 [(set (match_operand:XF 0 "register_operand" "=f,f")
13619 (match_operator:XF 3 "binary_fp_operator"
13620 [(match_operand:XF 1 "register_operand" "0,f")
13621 (match_operand:XF 2 "register_operand" "f,0")]))]
13622 "TARGET_80387
13623 && !COMMUTATIVE_ARITH_P (operands[3])"
13624 "* return output_387_binary_op (insn, operands);"
13625 [(set (attr "type")
13626 (cond [(match_operand:XF 3 "mult_operator")
13627 (const_string "fmul")
13628 (match_operand:XF 3 "div_operator")
13629 (const_string "fdiv")
13630 ]
13631 (const_string "fop")))
13632 (set_attr "mode" "XF")])
13633
13634 (define_insn "*fop_xf_2_i387"
13635 [(set (match_operand:XF 0 "register_operand" "=f")
13636 (match_operator:XF 3 "binary_fp_operator"
13637 [(float:XF
13638 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13639 (match_operand:XF 2 "register_operand" "0")]))]
13640 "TARGET_80387
13641 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13642 { return output_387_binary_op (insn, operands); }
13643 [(set (attr "type")
13644 (cond [(match_operand:XF 3 "mult_operator")
13645 (const_string "fmul")
13646 (match_operand:XF 3 "div_operator")
13647 (const_string "fdiv")
13648 ]
13649 (const_string "fop")))
13650 (set_attr "fp_int_src" "true")
13651 (set_attr "mode" "<MODE>")])
13652
13653 (define_insn "*fop_xf_3_i387"
13654 [(set (match_operand:XF 0 "register_operand" "=f")
13655 (match_operator:XF 3 "binary_fp_operator"
13656 [(match_operand:XF 1 "register_operand" "0")
13657 (float:XF
13658 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13659 "TARGET_80387
13660 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13661 { return output_387_binary_op (insn, operands); }
13662 [(set (attr "type")
13663 (cond [(match_operand:XF 3 "mult_operator")
13664 (const_string "fmul")
13665 (match_operand:XF 3 "div_operator")
13666 (const_string "fdiv")
13667 ]
13668 (const_string "fop")))
13669 (set_attr "fp_int_src" "true")
13670 (set_attr "mode" "<MODE>")])
13671
13672 (define_insn "*fop_xf_4_i387"
13673 [(set (match_operand:XF 0 "register_operand" "=f,f")
13674 (match_operator:XF 3 "binary_fp_operator"
13675 [(float_extend:XF
13676 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13677 (match_operand:XF 2 "register_operand" "0,f")]))]
13678 "TARGET_80387"
13679 "* return output_387_binary_op (insn, operands);"
13680 [(set (attr "type")
13681 (cond [(match_operand:XF 3 "mult_operator")
13682 (const_string "fmul")
13683 (match_operand:XF 3 "div_operator")
13684 (const_string "fdiv")
13685 ]
13686 (const_string "fop")))
13687 (set_attr "mode" "<MODE>")])
13688
13689 (define_insn "*fop_xf_5_i387"
13690 [(set (match_operand:XF 0 "register_operand" "=f,f")
13691 (match_operator:XF 3 "binary_fp_operator"
13692 [(match_operand:XF 1 "register_operand" "0,f")
13693 (float_extend:XF
13694 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13695 "TARGET_80387"
13696 "* return output_387_binary_op (insn, operands);"
13697 [(set (attr "type")
13698 (cond [(match_operand:XF 3 "mult_operator")
13699 (const_string "fmul")
13700 (match_operand:XF 3 "div_operator")
13701 (const_string "fdiv")
13702 ]
13703 (const_string "fop")))
13704 (set_attr "mode" "<MODE>")])
13705
13706 (define_insn "*fop_xf_6_i387"
13707 [(set (match_operand:XF 0 "register_operand" "=f,f")
13708 (match_operator:XF 3 "binary_fp_operator"
13709 [(float_extend:XF
13710 (match_operand:MODEF 1 "register_operand" "0,f"))
13711 (float_extend:XF
13712 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13713 "TARGET_80387"
13714 "* return output_387_binary_op (insn, operands);"
13715 [(set (attr "type")
13716 (cond [(match_operand:XF 3 "mult_operator")
13717 (const_string "fmul")
13718 (match_operand:XF 3 "div_operator")
13719 (const_string "fdiv")
13720 ]
13721 (const_string "fop")))
13722 (set_attr "mode" "<MODE>")])
13723 \f
13724 ;; FPU special functions.
13725
13726 ;; This pattern implements a no-op XFmode truncation for
13727 ;; all fancy i386 XFmode math functions.
13728
13729 (define_insn "truncxf<mode>2_i387_noop_unspec"
13730 [(set (match_operand:MODEF 0 "register_operand" "=f")
13731 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13732 UNSPEC_TRUNC_NOOP))]
13733 "TARGET_USE_FANCY_MATH_387"
13734 "* return output_387_reg_move (insn, operands);"
13735 [(set_attr "type" "fmov")
13736 (set_attr "mode" "<MODE>")])
13737
13738 (define_insn "sqrtxf2"
13739 [(set (match_operand:XF 0 "register_operand" "=f")
13740 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13741 "TARGET_USE_FANCY_MATH_387"
13742 "fsqrt"
13743 [(set_attr "type" "fpspc")
13744 (set_attr "mode" "XF")
13745 (set_attr "athlon_decode" "direct")
13746 (set_attr "amdfam10_decode" "direct")
13747 (set_attr "bdver1_decode" "direct")])
13748
13749 (define_insn "sqrt_extend<mode>xf2_i387"
13750 [(set (match_operand:XF 0 "register_operand" "=f")
13751 (sqrt:XF
13752 (float_extend:XF
13753 (match_operand:MODEF 1 "register_operand" "0"))))]
13754 "TARGET_USE_FANCY_MATH_387"
13755 "fsqrt"
13756 [(set_attr "type" "fpspc")
13757 (set_attr "mode" "XF")
13758 (set_attr "athlon_decode" "direct")
13759 (set_attr "amdfam10_decode" "direct")
13760 (set_attr "bdver1_decode" "direct")])
13761
13762 (define_insn "*rsqrtsf2_sse"
13763 [(set (match_operand:SF 0 "register_operand" "=x")
13764 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13765 UNSPEC_RSQRT))]
13766 "TARGET_SSE_MATH"
13767 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13768 [(set_attr "type" "sse")
13769 (set_attr "atom_sse_attr" "rcp")
13770 (set_attr "btver2_sse_attr" "rcp")
13771 (set_attr "prefix" "maybe_vex")
13772 (set_attr "mode" "SF")])
13773
13774 (define_expand "rsqrtsf2"
13775 [(set (match_operand:SF 0 "register_operand")
13776 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13777 UNSPEC_RSQRT))]
13778 "TARGET_SSE_MATH"
13779 {
13780 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13781 DONE;
13782 })
13783
13784 (define_insn "*sqrt<mode>2_sse"
13785 [(set (match_operand:MODEF 0 "register_operand" "=x")
13786 (sqrt:MODEF
13787 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13788 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13789 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13790 [(set_attr "type" "sse")
13791 (set_attr "atom_sse_attr" "sqrt")
13792 (set_attr "btver2_sse_attr" "sqrt")
13793 (set_attr "prefix" "maybe_vex")
13794 (set_attr "mode" "<MODE>")
13795 (set_attr "athlon_decode" "*")
13796 (set_attr "amdfam10_decode" "*")
13797 (set_attr "bdver1_decode" "*")])
13798
13799 (define_expand "sqrt<mode>2"
13800 [(set (match_operand:MODEF 0 "register_operand")
13801 (sqrt:MODEF
13802 (match_operand:MODEF 1 "nonimmediate_operand")))]
13803 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13804 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13805 {
13806 if (<MODE>mode == SFmode
13807 && TARGET_SSE_MATH
13808 && TARGET_RECIP_SQRT
13809 && !optimize_function_for_size_p (cfun)
13810 && flag_finite_math_only && !flag_trapping_math
13811 && flag_unsafe_math_optimizations)
13812 {
13813 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13814 DONE;
13815 }
13816
13817 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13818 {
13819 rtx op0 = gen_reg_rtx (XFmode);
13820 rtx op1 = force_reg (<MODE>mode, operands[1]);
13821
13822 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13823 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13824 DONE;
13825 }
13826 })
13827
13828 (define_insn "fpremxf4_i387"
13829 [(set (match_operand:XF 0 "register_operand" "=f")
13830 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13831 (match_operand:XF 3 "register_operand" "1")]
13832 UNSPEC_FPREM_F))
13833 (set (match_operand:XF 1 "register_operand" "=u")
13834 (unspec:XF [(match_dup 2) (match_dup 3)]
13835 UNSPEC_FPREM_U))
13836 (set (reg:CCFP FPSR_REG)
13837 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13838 UNSPEC_C2_FLAG))]
13839 "TARGET_USE_FANCY_MATH_387
13840 && flag_finite_math_only"
13841 "fprem"
13842 [(set_attr "type" "fpspc")
13843 (set_attr "mode" "XF")])
13844
13845 (define_expand "fmodxf3"
13846 [(use (match_operand:XF 0 "register_operand"))
13847 (use (match_operand:XF 1 "general_operand"))
13848 (use (match_operand:XF 2 "general_operand"))]
13849 "TARGET_USE_FANCY_MATH_387
13850 && flag_finite_math_only"
13851 {
13852 rtx_code_label *label = gen_label_rtx ();
13853
13854 rtx op1 = gen_reg_rtx (XFmode);
13855 rtx op2 = gen_reg_rtx (XFmode);
13856
13857 emit_move_insn (op2, operands[2]);
13858 emit_move_insn (op1, operands[1]);
13859
13860 emit_label (label);
13861 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13862 ix86_emit_fp_unordered_jump (label);
13863 LABEL_NUSES (label) = 1;
13864
13865 emit_move_insn (operands[0], op1);
13866 DONE;
13867 })
13868
13869 (define_expand "fmod<mode>3"
13870 [(use (match_operand:MODEF 0 "register_operand"))
13871 (use (match_operand:MODEF 1 "general_operand"))
13872 (use (match_operand:MODEF 2 "general_operand"))]
13873 "TARGET_USE_FANCY_MATH_387
13874 && flag_finite_math_only"
13875 {
13876 rtx (*gen_truncxf) (rtx, rtx);
13877
13878 rtx_code_label *label = gen_label_rtx ();
13879
13880 rtx op1 = gen_reg_rtx (XFmode);
13881 rtx op2 = gen_reg_rtx (XFmode);
13882
13883 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13884 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13885
13886 emit_label (label);
13887 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13888 ix86_emit_fp_unordered_jump (label);
13889 LABEL_NUSES (label) = 1;
13890
13891 /* Truncate the result properly for strict SSE math. */
13892 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13893 && !TARGET_MIX_SSE_I387)
13894 gen_truncxf = gen_truncxf<mode>2;
13895 else
13896 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13897
13898 emit_insn (gen_truncxf (operands[0], op1));
13899 DONE;
13900 })
13901
13902 (define_insn "fprem1xf4_i387"
13903 [(set (match_operand:XF 0 "register_operand" "=f")
13904 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13905 (match_operand:XF 3 "register_operand" "1")]
13906 UNSPEC_FPREM1_F))
13907 (set (match_operand:XF 1 "register_operand" "=u")
13908 (unspec:XF [(match_dup 2) (match_dup 3)]
13909 UNSPEC_FPREM1_U))
13910 (set (reg:CCFP FPSR_REG)
13911 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13912 UNSPEC_C2_FLAG))]
13913 "TARGET_USE_FANCY_MATH_387
13914 && flag_finite_math_only"
13915 "fprem1"
13916 [(set_attr "type" "fpspc")
13917 (set_attr "mode" "XF")])
13918
13919 (define_expand "remainderxf3"
13920 [(use (match_operand:XF 0 "register_operand"))
13921 (use (match_operand:XF 1 "general_operand"))
13922 (use (match_operand:XF 2 "general_operand"))]
13923 "TARGET_USE_FANCY_MATH_387
13924 && flag_finite_math_only"
13925 {
13926 rtx_code_label *label = gen_label_rtx ();
13927
13928 rtx op1 = gen_reg_rtx (XFmode);
13929 rtx op2 = gen_reg_rtx (XFmode);
13930
13931 emit_move_insn (op2, operands[2]);
13932 emit_move_insn (op1, operands[1]);
13933
13934 emit_label (label);
13935 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13936 ix86_emit_fp_unordered_jump (label);
13937 LABEL_NUSES (label) = 1;
13938
13939 emit_move_insn (operands[0], op1);
13940 DONE;
13941 })
13942
13943 (define_expand "remainder<mode>3"
13944 [(use (match_operand:MODEF 0 "register_operand"))
13945 (use (match_operand:MODEF 1 "general_operand"))
13946 (use (match_operand:MODEF 2 "general_operand"))]
13947 "TARGET_USE_FANCY_MATH_387
13948 && flag_finite_math_only"
13949 {
13950 rtx (*gen_truncxf) (rtx, rtx);
13951
13952 rtx_code_label *label = gen_label_rtx ();
13953
13954 rtx op1 = gen_reg_rtx (XFmode);
13955 rtx op2 = gen_reg_rtx (XFmode);
13956
13957 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13958 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13959
13960 emit_label (label);
13961
13962 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13963 ix86_emit_fp_unordered_jump (label);
13964 LABEL_NUSES (label) = 1;
13965
13966 /* Truncate the result properly for strict SSE math. */
13967 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13968 && !TARGET_MIX_SSE_I387)
13969 gen_truncxf = gen_truncxf<mode>2;
13970 else
13971 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13972
13973 emit_insn (gen_truncxf (operands[0], op1));
13974 DONE;
13975 })
13976
13977 (define_int_iterator SINCOS
13978 [UNSPEC_SIN
13979 UNSPEC_COS])
13980
13981 (define_int_attr sincos
13982 [(UNSPEC_SIN "sin")
13983 (UNSPEC_COS "cos")])
13984
13985 (define_insn "*<sincos>xf2_i387"
13986 [(set (match_operand:XF 0 "register_operand" "=f")
13987 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13988 SINCOS))]
13989 "TARGET_USE_FANCY_MATH_387
13990 && flag_unsafe_math_optimizations"
13991 "f<sincos>"
13992 [(set_attr "type" "fpspc")
13993 (set_attr "mode" "XF")])
13994
13995 (define_insn "*<sincos>_extend<mode>xf2_i387"
13996 [(set (match_operand:XF 0 "register_operand" "=f")
13997 (unspec:XF [(float_extend:XF
13998 (match_operand:MODEF 1 "register_operand" "0"))]
13999 SINCOS))]
14000 "TARGET_USE_FANCY_MATH_387
14001 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14002 || TARGET_MIX_SSE_I387)
14003 && flag_unsafe_math_optimizations"
14004 "f<sincos>"
14005 [(set_attr "type" "fpspc")
14006 (set_attr "mode" "XF")])
14007
14008 ;; When sincos pattern is defined, sin and cos builtin functions will be
14009 ;; expanded to sincos pattern with one of its outputs left unused.
14010 ;; CSE pass will figure out if two sincos patterns can be combined,
14011 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14012 ;; depending on the unused output.
14013
14014 (define_insn "sincosxf3"
14015 [(set (match_operand:XF 0 "register_operand" "=f")
14016 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14017 UNSPEC_SINCOS_COS))
14018 (set (match_operand:XF 1 "register_operand" "=u")
14019 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14020 "TARGET_USE_FANCY_MATH_387
14021 && flag_unsafe_math_optimizations"
14022 "fsincos"
14023 [(set_attr "type" "fpspc")
14024 (set_attr "mode" "XF")])
14025
14026 (define_split
14027 [(set (match_operand:XF 0 "register_operand")
14028 (unspec:XF [(match_operand:XF 2 "register_operand")]
14029 UNSPEC_SINCOS_COS))
14030 (set (match_operand:XF 1 "register_operand")
14031 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14032 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14033 && can_create_pseudo_p ()"
14034 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14035
14036 (define_split
14037 [(set (match_operand:XF 0 "register_operand")
14038 (unspec:XF [(match_operand:XF 2 "register_operand")]
14039 UNSPEC_SINCOS_COS))
14040 (set (match_operand:XF 1 "register_operand")
14041 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14042 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14043 && can_create_pseudo_p ()"
14044 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14045
14046 (define_insn "sincos_extend<mode>xf3_i387"
14047 [(set (match_operand:XF 0 "register_operand" "=f")
14048 (unspec:XF [(float_extend:XF
14049 (match_operand:MODEF 2 "register_operand" "0"))]
14050 UNSPEC_SINCOS_COS))
14051 (set (match_operand:XF 1 "register_operand" "=u")
14052 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14053 "TARGET_USE_FANCY_MATH_387
14054 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14055 || TARGET_MIX_SSE_I387)
14056 && flag_unsafe_math_optimizations"
14057 "fsincos"
14058 [(set_attr "type" "fpspc")
14059 (set_attr "mode" "XF")])
14060
14061 (define_split
14062 [(set (match_operand:XF 0 "register_operand")
14063 (unspec:XF [(float_extend:XF
14064 (match_operand:MODEF 2 "register_operand"))]
14065 UNSPEC_SINCOS_COS))
14066 (set (match_operand:XF 1 "register_operand")
14067 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14068 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14069 && can_create_pseudo_p ()"
14070 [(set (match_dup 1)
14071 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14072
14073 (define_split
14074 [(set (match_operand:XF 0 "register_operand")
14075 (unspec:XF [(float_extend:XF
14076 (match_operand:MODEF 2 "register_operand"))]
14077 UNSPEC_SINCOS_COS))
14078 (set (match_operand:XF 1 "register_operand")
14079 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14080 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14081 && can_create_pseudo_p ()"
14082 [(set (match_dup 0)
14083 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14084
14085 (define_expand "sincos<mode>3"
14086 [(use (match_operand:MODEF 0 "register_operand"))
14087 (use (match_operand:MODEF 1 "register_operand"))
14088 (use (match_operand:MODEF 2 "register_operand"))]
14089 "TARGET_USE_FANCY_MATH_387
14090 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14091 || TARGET_MIX_SSE_I387)
14092 && flag_unsafe_math_optimizations"
14093 {
14094 rtx op0 = gen_reg_rtx (XFmode);
14095 rtx op1 = gen_reg_rtx (XFmode);
14096
14097 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14098 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14099 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14100 DONE;
14101 })
14102
14103 (define_insn "fptanxf4_i387"
14104 [(set (match_operand:XF 0 "register_operand" "=f")
14105 (match_operand:XF 3 "const_double_operand" "F"))
14106 (set (match_operand:XF 1 "register_operand" "=u")
14107 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14108 UNSPEC_TAN))]
14109 "TARGET_USE_FANCY_MATH_387
14110 && flag_unsafe_math_optimizations
14111 && standard_80387_constant_p (operands[3]) == 2"
14112 "fptan"
14113 [(set_attr "type" "fpspc")
14114 (set_attr "mode" "XF")])
14115
14116 (define_insn "fptan_extend<mode>xf4_i387"
14117 [(set (match_operand:MODEF 0 "register_operand" "=f")
14118 (match_operand:MODEF 3 "const_double_operand" "F"))
14119 (set (match_operand:XF 1 "register_operand" "=u")
14120 (unspec:XF [(float_extend:XF
14121 (match_operand:MODEF 2 "register_operand" "0"))]
14122 UNSPEC_TAN))]
14123 "TARGET_USE_FANCY_MATH_387
14124 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14125 || TARGET_MIX_SSE_I387)
14126 && flag_unsafe_math_optimizations
14127 && standard_80387_constant_p (operands[3]) == 2"
14128 "fptan"
14129 [(set_attr "type" "fpspc")
14130 (set_attr "mode" "XF")])
14131
14132 (define_expand "tanxf2"
14133 [(use (match_operand:XF 0 "register_operand"))
14134 (use (match_operand:XF 1 "register_operand"))]
14135 "TARGET_USE_FANCY_MATH_387
14136 && flag_unsafe_math_optimizations"
14137 {
14138 rtx one = gen_reg_rtx (XFmode);
14139 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14140
14141 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14142 DONE;
14143 })
14144
14145 (define_expand "tan<mode>2"
14146 [(use (match_operand:MODEF 0 "register_operand"))
14147 (use (match_operand:MODEF 1 "register_operand"))]
14148 "TARGET_USE_FANCY_MATH_387
14149 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14150 || TARGET_MIX_SSE_I387)
14151 && flag_unsafe_math_optimizations"
14152 {
14153 rtx op0 = gen_reg_rtx (XFmode);
14154
14155 rtx one = gen_reg_rtx (<MODE>mode);
14156 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14157
14158 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14159 operands[1], op2));
14160 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14161 DONE;
14162 })
14163
14164 (define_insn "*fpatanxf3_i387"
14165 [(set (match_operand:XF 0 "register_operand" "=f")
14166 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14167 (match_operand:XF 2 "register_operand" "u")]
14168 UNSPEC_FPATAN))
14169 (clobber (match_scratch:XF 3 "=2"))]
14170 "TARGET_USE_FANCY_MATH_387
14171 && flag_unsafe_math_optimizations"
14172 "fpatan"
14173 [(set_attr "type" "fpspc")
14174 (set_attr "mode" "XF")])
14175
14176 (define_insn "fpatan_extend<mode>xf3_i387"
14177 [(set (match_operand:XF 0 "register_operand" "=f")
14178 (unspec:XF [(float_extend:XF
14179 (match_operand:MODEF 1 "register_operand" "0"))
14180 (float_extend:XF
14181 (match_operand:MODEF 2 "register_operand" "u"))]
14182 UNSPEC_FPATAN))
14183 (clobber (match_scratch:XF 3 "=2"))]
14184 "TARGET_USE_FANCY_MATH_387
14185 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14186 || TARGET_MIX_SSE_I387)
14187 && flag_unsafe_math_optimizations"
14188 "fpatan"
14189 [(set_attr "type" "fpspc")
14190 (set_attr "mode" "XF")])
14191
14192 (define_expand "atan2xf3"
14193 [(parallel [(set (match_operand:XF 0 "register_operand")
14194 (unspec:XF [(match_operand:XF 2 "register_operand")
14195 (match_operand:XF 1 "register_operand")]
14196 UNSPEC_FPATAN))
14197 (clobber (match_scratch:XF 3))])]
14198 "TARGET_USE_FANCY_MATH_387
14199 && flag_unsafe_math_optimizations")
14200
14201 (define_expand "atan2<mode>3"
14202 [(use (match_operand:MODEF 0 "register_operand"))
14203 (use (match_operand:MODEF 1 "register_operand"))
14204 (use (match_operand:MODEF 2 "register_operand"))]
14205 "TARGET_USE_FANCY_MATH_387
14206 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14207 || TARGET_MIX_SSE_I387)
14208 && flag_unsafe_math_optimizations"
14209 {
14210 rtx op0 = gen_reg_rtx (XFmode);
14211
14212 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14213 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14214 DONE;
14215 })
14216
14217 (define_expand "atanxf2"
14218 [(parallel [(set (match_operand:XF 0 "register_operand")
14219 (unspec:XF [(match_dup 2)
14220 (match_operand:XF 1 "register_operand")]
14221 UNSPEC_FPATAN))
14222 (clobber (match_scratch:XF 3))])]
14223 "TARGET_USE_FANCY_MATH_387
14224 && flag_unsafe_math_optimizations"
14225 {
14226 operands[2] = gen_reg_rtx (XFmode);
14227 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14228 })
14229
14230 (define_expand "atan<mode>2"
14231 [(use (match_operand:MODEF 0 "register_operand"))
14232 (use (match_operand:MODEF 1 "register_operand"))]
14233 "TARGET_USE_FANCY_MATH_387
14234 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14235 || TARGET_MIX_SSE_I387)
14236 && flag_unsafe_math_optimizations"
14237 {
14238 rtx op0 = gen_reg_rtx (XFmode);
14239
14240 rtx op2 = gen_reg_rtx (<MODE>mode);
14241 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14242
14243 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14244 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14245 DONE;
14246 })
14247
14248 (define_expand "asinxf2"
14249 [(set (match_dup 2)
14250 (mult:XF (match_operand:XF 1 "register_operand")
14251 (match_dup 1)))
14252 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14253 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14254 (parallel [(set (match_operand:XF 0 "register_operand")
14255 (unspec:XF [(match_dup 5) (match_dup 1)]
14256 UNSPEC_FPATAN))
14257 (clobber (match_scratch:XF 6))])]
14258 "TARGET_USE_FANCY_MATH_387
14259 && flag_unsafe_math_optimizations"
14260 {
14261 int i;
14262
14263 if (optimize_insn_for_size_p ())
14264 FAIL;
14265
14266 for (i = 2; i < 6; i++)
14267 operands[i] = gen_reg_rtx (XFmode);
14268
14269 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14270 })
14271
14272 (define_expand "asin<mode>2"
14273 [(use (match_operand:MODEF 0 "register_operand"))
14274 (use (match_operand:MODEF 1 "general_operand"))]
14275 "TARGET_USE_FANCY_MATH_387
14276 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14277 || TARGET_MIX_SSE_I387)
14278 && flag_unsafe_math_optimizations"
14279 {
14280 rtx op0 = gen_reg_rtx (XFmode);
14281 rtx op1 = gen_reg_rtx (XFmode);
14282
14283 if (optimize_insn_for_size_p ())
14284 FAIL;
14285
14286 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14287 emit_insn (gen_asinxf2 (op0, op1));
14288 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14289 DONE;
14290 })
14291
14292 (define_expand "acosxf2"
14293 [(set (match_dup 2)
14294 (mult:XF (match_operand:XF 1 "register_operand")
14295 (match_dup 1)))
14296 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14297 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14298 (parallel [(set (match_operand:XF 0 "register_operand")
14299 (unspec:XF [(match_dup 1) (match_dup 5)]
14300 UNSPEC_FPATAN))
14301 (clobber (match_scratch:XF 6))])]
14302 "TARGET_USE_FANCY_MATH_387
14303 && flag_unsafe_math_optimizations"
14304 {
14305 int i;
14306
14307 if (optimize_insn_for_size_p ())
14308 FAIL;
14309
14310 for (i = 2; i < 6; i++)
14311 operands[i] = gen_reg_rtx (XFmode);
14312
14313 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14314 })
14315
14316 (define_expand "acos<mode>2"
14317 [(use (match_operand:MODEF 0 "register_operand"))
14318 (use (match_operand:MODEF 1 "general_operand"))]
14319 "TARGET_USE_FANCY_MATH_387
14320 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14321 || TARGET_MIX_SSE_I387)
14322 && flag_unsafe_math_optimizations"
14323 {
14324 rtx op0 = gen_reg_rtx (XFmode);
14325 rtx op1 = gen_reg_rtx (XFmode);
14326
14327 if (optimize_insn_for_size_p ())
14328 FAIL;
14329
14330 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14331 emit_insn (gen_acosxf2 (op0, op1));
14332 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14333 DONE;
14334 })
14335
14336 (define_insn "fyl2xxf3_i387"
14337 [(set (match_operand:XF 0 "register_operand" "=f")
14338 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14339 (match_operand:XF 2 "register_operand" "u")]
14340 UNSPEC_FYL2X))
14341 (clobber (match_scratch:XF 3 "=2"))]
14342 "TARGET_USE_FANCY_MATH_387
14343 && flag_unsafe_math_optimizations"
14344 "fyl2x"
14345 [(set_attr "type" "fpspc")
14346 (set_attr "mode" "XF")])
14347
14348 (define_insn "fyl2x_extend<mode>xf3_i387"
14349 [(set (match_operand:XF 0 "register_operand" "=f")
14350 (unspec:XF [(float_extend:XF
14351 (match_operand:MODEF 1 "register_operand" "0"))
14352 (match_operand:XF 2 "register_operand" "u")]
14353 UNSPEC_FYL2X))
14354 (clobber (match_scratch:XF 3 "=2"))]
14355 "TARGET_USE_FANCY_MATH_387
14356 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14357 || TARGET_MIX_SSE_I387)
14358 && flag_unsafe_math_optimizations"
14359 "fyl2x"
14360 [(set_attr "type" "fpspc")
14361 (set_attr "mode" "XF")])
14362
14363 (define_expand "logxf2"
14364 [(parallel [(set (match_operand:XF 0 "register_operand")
14365 (unspec:XF [(match_operand:XF 1 "register_operand")
14366 (match_dup 2)] UNSPEC_FYL2X))
14367 (clobber (match_scratch:XF 3))])]
14368 "TARGET_USE_FANCY_MATH_387
14369 && flag_unsafe_math_optimizations"
14370 {
14371 operands[2] = gen_reg_rtx (XFmode);
14372 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14373 })
14374
14375 (define_expand "log<mode>2"
14376 [(use (match_operand:MODEF 0 "register_operand"))
14377 (use (match_operand:MODEF 1 "register_operand"))]
14378 "TARGET_USE_FANCY_MATH_387
14379 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380 || TARGET_MIX_SSE_I387)
14381 && flag_unsafe_math_optimizations"
14382 {
14383 rtx op0 = gen_reg_rtx (XFmode);
14384
14385 rtx op2 = gen_reg_rtx (XFmode);
14386 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14387
14388 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14389 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14390 DONE;
14391 })
14392
14393 (define_expand "log10xf2"
14394 [(parallel [(set (match_operand:XF 0 "register_operand")
14395 (unspec:XF [(match_operand:XF 1 "register_operand")
14396 (match_dup 2)] UNSPEC_FYL2X))
14397 (clobber (match_scratch:XF 3))])]
14398 "TARGET_USE_FANCY_MATH_387
14399 && flag_unsafe_math_optimizations"
14400 {
14401 operands[2] = gen_reg_rtx (XFmode);
14402 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14403 })
14404
14405 (define_expand "log10<mode>2"
14406 [(use (match_operand:MODEF 0 "register_operand"))
14407 (use (match_operand:MODEF 1 "register_operand"))]
14408 "TARGET_USE_FANCY_MATH_387
14409 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14410 || TARGET_MIX_SSE_I387)
14411 && flag_unsafe_math_optimizations"
14412 {
14413 rtx op0 = gen_reg_rtx (XFmode);
14414
14415 rtx op2 = gen_reg_rtx (XFmode);
14416 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14417
14418 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14419 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14420 DONE;
14421 })
14422
14423 (define_expand "log2xf2"
14424 [(parallel [(set (match_operand:XF 0 "register_operand")
14425 (unspec:XF [(match_operand:XF 1 "register_operand")
14426 (match_dup 2)] UNSPEC_FYL2X))
14427 (clobber (match_scratch:XF 3))])]
14428 "TARGET_USE_FANCY_MATH_387
14429 && flag_unsafe_math_optimizations"
14430 {
14431 operands[2] = gen_reg_rtx (XFmode);
14432 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14433 })
14434
14435 (define_expand "log2<mode>2"
14436 [(use (match_operand:MODEF 0 "register_operand"))
14437 (use (match_operand:MODEF 1 "register_operand"))]
14438 "TARGET_USE_FANCY_MATH_387
14439 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14440 || TARGET_MIX_SSE_I387)
14441 && flag_unsafe_math_optimizations"
14442 {
14443 rtx op0 = gen_reg_rtx (XFmode);
14444
14445 rtx op2 = gen_reg_rtx (XFmode);
14446 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14447
14448 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14449 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14450 DONE;
14451 })
14452
14453 (define_insn "fyl2xp1xf3_i387"
14454 [(set (match_operand:XF 0 "register_operand" "=f")
14455 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14456 (match_operand:XF 2 "register_operand" "u")]
14457 UNSPEC_FYL2XP1))
14458 (clobber (match_scratch:XF 3 "=2"))]
14459 "TARGET_USE_FANCY_MATH_387
14460 && flag_unsafe_math_optimizations"
14461 "fyl2xp1"
14462 [(set_attr "type" "fpspc")
14463 (set_attr "mode" "XF")])
14464
14465 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14466 [(set (match_operand:XF 0 "register_operand" "=f")
14467 (unspec:XF [(float_extend:XF
14468 (match_operand:MODEF 1 "register_operand" "0"))
14469 (match_operand:XF 2 "register_operand" "u")]
14470 UNSPEC_FYL2XP1))
14471 (clobber (match_scratch:XF 3 "=2"))]
14472 "TARGET_USE_FANCY_MATH_387
14473 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14474 || TARGET_MIX_SSE_I387)
14475 && flag_unsafe_math_optimizations"
14476 "fyl2xp1"
14477 [(set_attr "type" "fpspc")
14478 (set_attr "mode" "XF")])
14479
14480 (define_expand "log1pxf2"
14481 [(use (match_operand:XF 0 "register_operand"))
14482 (use (match_operand:XF 1 "register_operand"))]
14483 "TARGET_USE_FANCY_MATH_387
14484 && flag_unsafe_math_optimizations"
14485 {
14486 if (optimize_insn_for_size_p ())
14487 FAIL;
14488
14489 ix86_emit_i387_log1p (operands[0], operands[1]);
14490 DONE;
14491 })
14492
14493 (define_expand "log1p<mode>2"
14494 [(use (match_operand:MODEF 0 "register_operand"))
14495 (use (match_operand:MODEF 1 "register_operand"))]
14496 "TARGET_USE_FANCY_MATH_387
14497 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14498 || TARGET_MIX_SSE_I387)
14499 && flag_unsafe_math_optimizations"
14500 {
14501 rtx op0;
14502
14503 if (optimize_insn_for_size_p ())
14504 FAIL;
14505
14506 op0 = gen_reg_rtx (XFmode);
14507
14508 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14509
14510 ix86_emit_i387_log1p (op0, operands[1]);
14511 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14512 DONE;
14513 })
14514
14515 (define_insn "fxtractxf3_i387"
14516 [(set (match_operand:XF 0 "register_operand" "=f")
14517 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14518 UNSPEC_XTRACT_FRACT))
14519 (set (match_operand:XF 1 "register_operand" "=u")
14520 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14521 "TARGET_USE_FANCY_MATH_387
14522 && flag_unsafe_math_optimizations"
14523 "fxtract"
14524 [(set_attr "type" "fpspc")
14525 (set_attr "mode" "XF")])
14526
14527 (define_insn "fxtract_extend<mode>xf3_i387"
14528 [(set (match_operand:XF 0 "register_operand" "=f")
14529 (unspec:XF [(float_extend:XF
14530 (match_operand:MODEF 2 "register_operand" "0"))]
14531 UNSPEC_XTRACT_FRACT))
14532 (set (match_operand:XF 1 "register_operand" "=u")
14533 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14534 "TARGET_USE_FANCY_MATH_387
14535 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14536 || TARGET_MIX_SSE_I387)
14537 && flag_unsafe_math_optimizations"
14538 "fxtract"
14539 [(set_attr "type" "fpspc")
14540 (set_attr "mode" "XF")])
14541
14542 (define_expand "logbxf2"
14543 [(parallel [(set (match_dup 2)
14544 (unspec:XF [(match_operand:XF 1 "register_operand")]
14545 UNSPEC_XTRACT_FRACT))
14546 (set (match_operand:XF 0 "register_operand")
14547 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14548 "TARGET_USE_FANCY_MATH_387
14549 && flag_unsafe_math_optimizations"
14550 "operands[2] = gen_reg_rtx (XFmode);")
14551
14552 (define_expand "logb<mode>2"
14553 [(use (match_operand:MODEF 0 "register_operand"))
14554 (use (match_operand:MODEF 1 "register_operand"))]
14555 "TARGET_USE_FANCY_MATH_387
14556 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14557 || TARGET_MIX_SSE_I387)
14558 && flag_unsafe_math_optimizations"
14559 {
14560 rtx op0 = gen_reg_rtx (XFmode);
14561 rtx op1 = gen_reg_rtx (XFmode);
14562
14563 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14564 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14565 DONE;
14566 })
14567
14568 (define_expand "ilogbxf2"
14569 [(use (match_operand:SI 0 "register_operand"))
14570 (use (match_operand:XF 1 "register_operand"))]
14571 "TARGET_USE_FANCY_MATH_387
14572 && flag_unsafe_math_optimizations"
14573 {
14574 rtx op0, op1;
14575
14576 if (optimize_insn_for_size_p ())
14577 FAIL;
14578
14579 op0 = gen_reg_rtx (XFmode);
14580 op1 = gen_reg_rtx (XFmode);
14581
14582 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14583 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14584 DONE;
14585 })
14586
14587 (define_expand "ilogb<mode>2"
14588 [(use (match_operand:SI 0 "register_operand"))
14589 (use (match_operand:MODEF 1 "register_operand"))]
14590 "TARGET_USE_FANCY_MATH_387
14591 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14592 || TARGET_MIX_SSE_I387)
14593 && flag_unsafe_math_optimizations"
14594 {
14595 rtx op0, op1;
14596
14597 if (optimize_insn_for_size_p ())
14598 FAIL;
14599
14600 op0 = gen_reg_rtx (XFmode);
14601 op1 = gen_reg_rtx (XFmode);
14602
14603 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14604 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14605 DONE;
14606 })
14607
14608 (define_insn "*f2xm1xf2_i387"
14609 [(set (match_operand:XF 0 "register_operand" "=f")
14610 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14611 UNSPEC_F2XM1))]
14612 "TARGET_USE_FANCY_MATH_387
14613 && flag_unsafe_math_optimizations"
14614 "f2xm1"
14615 [(set_attr "type" "fpspc")
14616 (set_attr "mode" "XF")])
14617
14618 (define_insn "fscalexf4_i387"
14619 [(set (match_operand:XF 0 "register_operand" "=f")
14620 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14621 (match_operand:XF 3 "register_operand" "1")]
14622 UNSPEC_FSCALE_FRACT))
14623 (set (match_operand:XF 1 "register_operand" "=u")
14624 (unspec:XF [(match_dup 2) (match_dup 3)]
14625 UNSPEC_FSCALE_EXP))]
14626 "TARGET_USE_FANCY_MATH_387
14627 && flag_unsafe_math_optimizations"
14628 "fscale"
14629 [(set_attr "type" "fpspc")
14630 (set_attr "mode" "XF")])
14631
14632 (define_expand "expNcorexf3"
14633 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14634 (match_operand:XF 2 "register_operand")))
14635 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14636 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14637 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14638 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14639 (parallel [(set (match_operand:XF 0 "register_operand")
14640 (unspec:XF [(match_dup 8) (match_dup 4)]
14641 UNSPEC_FSCALE_FRACT))
14642 (set (match_dup 9)
14643 (unspec:XF [(match_dup 8) (match_dup 4)]
14644 UNSPEC_FSCALE_EXP))])]
14645 "TARGET_USE_FANCY_MATH_387
14646 && flag_unsafe_math_optimizations"
14647 {
14648 int i;
14649
14650 if (optimize_insn_for_size_p ())
14651 FAIL;
14652
14653 for (i = 3; i < 10; i++)
14654 operands[i] = gen_reg_rtx (XFmode);
14655
14656 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14657 })
14658
14659 (define_expand "expxf2"
14660 [(use (match_operand:XF 0 "register_operand"))
14661 (use (match_operand:XF 1 "register_operand"))]
14662 "TARGET_USE_FANCY_MATH_387
14663 && flag_unsafe_math_optimizations"
14664 {
14665 rtx op2;
14666
14667 if (optimize_insn_for_size_p ())
14668 FAIL;
14669
14670 op2 = gen_reg_rtx (XFmode);
14671 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14672
14673 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14674 DONE;
14675 })
14676
14677 (define_expand "exp<mode>2"
14678 [(use (match_operand:MODEF 0 "register_operand"))
14679 (use (match_operand:MODEF 1 "general_operand"))]
14680 "TARGET_USE_FANCY_MATH_387
14681 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14682 || TARGET_MIX_SSE_I387)
14683 && flag_unsafe_math_optimizations"
14684 {
14685 rtx op0, op1;
14686
14687 if (optimize_insn_for_size_p ())
14688 FAIL;
14689
14690 op0 = gen_reg_rtx (XFmode);
14691 op1 = gen_reg_rtx (XFmode);
14692
14693 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14694 emit_insn (gen_expxf2 (op0, op1));
14695 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14696 DONE;
14697 })
14698
14699 (define_expand "exp10xf2"
14700 [(use (match_operand:XF 0 "register_operand"))
14701 (use (match_operand:XF 1 "register_operand"))]
14702 "TARGET_USE_FANCY_MATH_387
14703 && flag_unsafe_math_optimizations"
14704 {
14705 rtx op2;
14706
14707 if (optimize_insn_for_size_p ())
14708 FAIL;
14709
14710 op2 = gen_reg_rtx (XFmode);
14711 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14712
14713 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14714 DONE;
14715 })
14716
14717 (define_expand "exp10<mode>2"
14718 [(use (match_operand:MODEF 0 "register_operand"))
14719 (use (match_operand:MODEF 1 "general_operand"))]
14720 "TARGET_USE_FANCY_MATH_387
14721 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14722 || TARGET_MIX_SSE_I387)
14723 && flag_unsafe_math_optimizations"
14724 {
14725 rtx op0, op1;
14726
14727 if (optimize_insn_for_size_p ())
14728 FAIL;
14729
14730 op0 = gen_reg_rtx (XFmode);
14731 op1 = gen_reg_rtx (XFmode);
14732
14733 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14734 emit_insn (gen_exp10xf2 (op0, op1));
14735 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14736 DONE;
14737 })
14738
14739 (define_expand "exp2xf2"
14740 [(use (match_operand:XF 0 "register_operand"))
14741 (use (match_operand:XF 1 "register_operand"))]
14742 "TARGET_USE_FANCY_MATH_387
14743 && flag_unsafe_math_optimizations"
14744 {
14745 rtx op2;
14746
14747 if (optimize_insn_for_size_p ())
14748 FAIL;
14749
14750 op2 = gen_reg_rtx (XFmode);
14751 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14752
14753 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14754 DONE;
14755 })
14756
14757 (define_expand "exp2<mode>2"
14758 [(use (match_operand:MODEF 0 "register_operand"))
14759 (use (match_operand:MODEF 1 "general_operand"))]
14760 "TARGET_USE_FANCY_MATH_387
14761 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14762 || TARGET_MIX_SSE_I387)
14763 && flag_unsafe_math_optimizations"
14764 {
14765 rtx op0, op1;
14766
14767 if (optimize_insn_for_size_p ())
14768 FAIL;
14769
14770 op0 = gen_reg_rtx (XFmode);
14771 op1 = gen_reg_rtx (XFmode);
14772
14773 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14774 emit_insn (gen_exp2xf2 (op0, op1));
14775 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14776 DONE;
14777 })
14778
14779 (define_expand "expm1xf2"
14780 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14781 (match_dup 2)))
14782 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14783 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14784 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14785 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14786 (parallel [(set (match_dup 7)
14787 (unspec:XF [(match_dup 6) (match_dup 4)]
14788 UNSPEC_FSCALE_FRACT))
14789 (set (match_dup 8)
14790 (unspec:XF [(match_dup 6) (match_dup 4)]
14791 UNSPEC_FSCALE_EXP))])
14792 (parallel [(set (match_dup 10)
14793 (unspec:XF [(match_dup 9) (match_dup 8)]
14794 UNSPEC_FSCALE_FRACT))
14795 (set (match_dup 11)
14796 (unspec:XF [(match_dup 9) (match_dup 8)]
14797 UNSPEC_FSCALE_EXP))])
14798 (set (match_dup 12) (minus:XF (match_dup 10)
14799 (float_extend:XF (match_dup 13))))
14800 (set (match_operand:XF 0 "register_operand")
14801 (plus:XF (match_dup 12) (match_dup 7)))]
14802 "TARGET_USE_FANCY_MATH_387
14803 && flag_unsafe_math_optimizations"
14804 {
14805 int i;
14806
14807 if (optimize_insn_for_size_p ())
14808 FAIL;
14809
14810 for (i = 2; i < 13; i++)
14811 operands[i] = gen_reg_rtx (XFmode);
14812
14813 operands[13]
14814 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14815
14816 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14817 })
14818
14819 (define_expand "expm1<mode>2"
14820 [(use (match_operand:MODEF 0 "register_operand"))
14821 (use (match_operand:MODEF 1 "general_operand"))]
14822 "TARGET_USE_FANCY_MATH_387
14823 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14824 || TARGET_MIX_SSE_I387)
14825 && flag_unsafe_math_optimizations"
14826 {
14827 rtx op0, op1;
14828
14829 if (optimize_insn_for_size_p ())
14830 FAIL;
14831
14832 op0 = gen_reg_rtx (XFmode);
14833 op1 = gen_reg_rtx (XFmode);
14834
14835 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14836 emit_insn (gen_expm1xf2 (op0, op1));
14837 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14838 DONE;
14839 })
14840
14841 (define_expand "ldexpxf3"
14842 [(match_operand:XF 0 "register_operand")
14843 (match_operand:XF 1 "register_operand")
14844 (match_operand:SI 2 "register_operand")]
14845 "TARGET_USE_FANCY_MATH_387
14846 && flag_unsafe_math_optimizations"
14847 {
14848 rtx tmp1, tmp2;
14849 if (optimize_insn_for_size_p ())
14850 FAIL;
14851
14852 tmp1 = gen_reg_rtx (XFmode);
14853 tmp2 = gen_reg_rtx (XFmode);
14854
14855 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14856 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14857 operands[1], tmp1));
14858 DONE;
14859 })
14860
14861 (define_expand "ldexp<mode>3"
14862 [(use (match_operand:MODEF 0 "register_operand"))
14863 (use (match_operand:MODEF 1 "general_operand"))
14864 (use (match_operand:SI 2 "register_operand"))]
14865 "TARGET_USE_FANCY_MATH_387
14866 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14867 || TARGET_MIX_SSE_I387)
14868 && flag_unsafe_math_optimizations"
14869 {
14870 rtx op0, op1;
14871
14872 if (optimize_insn_for_size_p ())
14873 FAIL;
14874
14875 op0 = gen_reg_rtx (XFmode);
14876 op1 = gen_reg_rtx (XFmode);
14877
14878 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14879 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14880 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14881 DONE;
14882 })
14883
14884 (define_expand "scalbxf3"
14885 [(parallel [(set (match_operand:XF 0 " register_operand")
14886 (unspec:XF [(match_operand:XF 1 "register_operand")
14887 (match_operand:XF 2 "register_operand")]
14888 UNSPEC_FSCALE_FRACT))
14889 (set (match_dup 3)
14890 (unspec:XF [(match_dup 1) (match_dup 2)]
14891 UNSPEC_FSCALE_EXP))])]
14892 "TARGET_USE_FANCY_MATH_387
14893 && flag_unsafe_math_optimizations"
14894 {
14895 if (optimize_insn_for_size_p ())
14896 FAIL;
14897
14898 operands[3] = gen_reg_rtx (XFmode);
14899 })
14900
14901 (define_expand "scalb<mode>3"
14902 [(use (match_operand:MODEF 0 "register_operand"))
14903 (use (match_operand:MODEF 1 "general_operand"))
14904 (use (match_operand:MODEF 2 "general_operand"))]
14905 "TARGET_USE_FANCY_MATH_387
14906 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14907 || TARGET_MIX_SSE_I387)
14908 && flag_unsafe_math_optimizations"
14909 {
14910 rtx op0, op1, op2;
14911
14912 if (optimize_insn_for_size_p ())
14913 FAIL;
14914
14915 op0 = gen_reg_rtx (XFmode);
14916 op1 = gen_reg_rtx (XFmode);
14917 op2 = gen_reg_rtx (XFmode);
14918
14919 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14920 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14921 emit_insn (gen_scalbxf3 (op0, op1, op2));
14922 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14923 DONE;
14924 })
14925
14926 (define_expand "significandxf2"
14927 [(parallel [(set (match_operand:XF 0 "register_operand")
14928 (unspec:XF [(match_operand:XF 1 "register_operand")]
14929 UNSPEC_XTRACT_FRACT))
14930 (set (match_dup 2)
14931 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14932 "TARGET_USE_FANCY_MATH_387
14933 && flag_unsafe_math_optimizations"
14934 "operands[2] = gen_reg_rtx (XFmode);")
14935
14936 (define_expand "significand<mode>2"
14937 [(use (match_operand:MODEF 0 "register_operand"))
14938 (use (match_operand:MODEF 1 "register_operand"))]
14939 "TARGET_USE_FANCY_MATH_387
14940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14941 || TARGET_MIX_SSE_I387)
14942 && flag_unsafe_math_optimizations"
14943 {
14944 rtx op0 = gen_reg_rtx (XFmode);
14945 rtx op1 = gen_reg_rtx (XFmode);
14946
14947 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14948 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14949 DONE;
14950 })
14951 \f
14952
14953 (define_insn "sse4_1_round<mode>2"
14954 [(set (match_operand:MODEF 0 "register_operand" "=x")
14955 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14956 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14957 UNSPEC_ROUND))]
14958 "TARGET_ROUND"
14959 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14960 [(set_attr "type" "ssecvt")
14961 (set_attr "prefix_extra" "1")
14962 (set_attr "prefix" "maybe_vex")
14963 (set_attr "mode" "<MODE>")])
14964
14965 (define_insn "rintxf2"
14966 [(set (match_operand:XF 0 "register_operand" "=f")
14967 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14968 UNSPEC_FRNDINT))]
14969 "TARGET_USE_FANCY_MATH_387
14970 && flag_unsafe_math_optimizations"
14971 "frndint"
14972 [(set_attr "type" "fpspc")
14973 (set_attr "mode" "XF")])
14974
14975 (define_expand "rint<mode>2"
14976 [(use (match_operand:MODEF 0 "register_operand"))
14977 (use (match_operand:MODEF 1 "register_operand"))]
14978 "(TARGET_USE_FANCY_MATH_387
14979 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14980 || TARGET_MIX_SSE_I387)
14981 && flag_unsafe_math_optimizations)
14982 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14983 && !flag_trapping_math)"
14984 {
14985 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14986 && !flag_trapping_math)
14987 {
14988 if (TARGET_ROUND)
14989 emit_insn (gen_sse4_1_round<mode>2
14990 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14991 else if (optimize_insn_for_size_p ())
14992 FAIL;
14993 else
14994 ix86_expand_rint (operands[0], operands[1]);
14995 }
14996 else
14997 {
14998 rtx op0 = gen_reg_rtx (XFmode);
14999 rtx op1 = gen_reg_rtx (XFmode);
15000
15001 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15002 emit_insn (gen_rintxf2 (op0, op1));
15003
15004 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15005 }
15006 DONE;
15007 })
15008
15009 (define_expand "round<mode>2"
15010 [(match_operand:X87MODEF 0 "register_operand")
15011 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15012 "(TARGET_USE_FANCY_MATH_387
15013 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15014 || TARGET_MIX_SSE_I387)
15015 && flag_unsafe_math_optimizations)
15016 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15017 && !flag_trapping_math && !flag_rounding_math)"
15018 {
15019 if (optimize_insn_for_size_p ())
15020 FAIL;
15021
15022 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15023 && !flag_trapping_math && !flag_rounding_math)
15024 {
15025 if (TARGET_ROUND)
15026 {
15027 operands[1] = force_reg (<MODE>mode, operands[1]);
15028 ix86_expand_round_sse4 (operands[0], operands[1]);
15029 }
15030 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15031 ix86_expand_round (operands[0], operands[1]);
15032 else
15033 ix86_expand_rounddf_32 (operands[0], operands[1]);
15034 }
15035 else
15036 {
15037 operands[1] = force_reg (<MODE>mode, operands[1]);
15038 ix86_emit_i387_round (operands[0], operands[1]);
15039 }
15040 DONE;
15041 })
15042
15043 (define_insn_and_split "*fistdi2_1"
15044 [(set (match_operand:DI 0 "nonimmediate_operand")
15045 (unspec:DI [(match_operand:XF 1 "register_operand")]
15046 UNSPEC_FIST))]
15047 "TARGET_USE_FANCY_MATH_387
15048 && can_create_pseudo_p ()"
15049 "#"
15050 "&& 1"
15051 [(const_int 0)]
15052 {
15053 if (memory_operand (operands[0], VOIDmode))
15054 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15055 else
15056 {
15057 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15058 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15059 operands[2]));
15060 }
15061 DONE;
15062 }
15063 [(set_attr "type" "fpspc")
15064 (set_attr "mode" "DI")])
15065
15066 (define_insn "fistdi2"
15067 [(set (match_operand:DI 0 "memory_operand" "=m")
15068 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15069 UNSPEC_FIST))
15070 (clobber (match_scratch:XF 2 "=&1f"))]
15071 "TARGET_USE_FANCY_MATH_387"
15072 "* return output_fix_trunc (insn, operands, false);"
15073 [(set_attr "type" "fpspc")
15074 (set_attr "mode" "DI")])
15075
15076 (define_insn "fistdi2_with_temp"
15077 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15078 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15079 UNSPEC_FIST))
15080 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15081 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15082 "TARGET_USE_FANCY_MATH_387"
15083 "#"
15084 [(set_attr "type" "fpspc")
15085 (set_attr "mode" "DI")])
15086
15087 (define_split
15088 [(set (match_operand:DI 0 "register_operand")
15089 (unspec:DI [(match_operand:XF 1 "register_operand")]
15090 UNSPEC_FIST))
15091 (clobber (match_operand:DI 2 "memory_operand"))
15092 (clobber (match_scratch 3))]
15093 "reload_completed"
15094 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15095 (clobber (match_dup 3))])
15096 (set (match_dup 0) (match_dup 2))])
15097
15098 (define_split
15099 [(set (match_operand:DI 0 "memory_operand")
15100 (unspec:DI [(match_operand:XF 1 "register_operand")]
15101 UNSPEC_FIST))
15102 (clobber (match_operand:DI 2 "memory_operand"))
15103 (clobber (match_scratch 3))]
15104 "reload_completed"
15105 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15106 (clobber (match_dup 3))])])
15107
15108 (define_insn_and_split "*fist<mode>2_1"
15109 [(set (match_operand:SWI24 0 "register_operand")
15110 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15111 UNSPEC_FIST))]
15112 "TARGET_USE_FANCY_MATH_387
15113 && can_create_pseudo_p ()"
15114 "#"
15115 "&& 1"
15116 [(const_int 0)]
15117 {
15118 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15119 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15120 operands[2]));
15121 DONE;
15122 }
15123 [(set_attr "type" "fpspc")
15124 (set_attr "mode" "<MODE>")])
15125
15126 (define_insn "fist<mode>2"
15127 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15128 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15129 UNSPEC_FIST))]
15130 "TARGET_USE_FANCY_MATH_387"
15131 "* return output_fix_trunc (insn, operands, false);"
15132 [(set_attr "type" "fpspc")
15133 (set_attr "mode" "<MODE>")])
15134
15135 (define_insn "fist<mode>2_with_temp"
15136 [(set (match_operand:SWI24 0 "register_operand" "=r")
15137 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15138 UNSPEC_FIST))
15139 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15140 "TARGET_USE_FANCY_MATH_387"
15141 "#"
15142 [(set_attr "type" "fpspc")
15143 (set_attr "mode" "<MODE>")])
15144
15145 (define_split
15146 [(set (match_operand:SWI24 0 "register_operand")
15147 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15148 UNSPEC_FIST))
15149 (clobber (match_operand:SWI24 2 "memory_operand"))]
15150 "reload_completed"
15151 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15152 (set (match_dup 0) (match_dup 2))])
15153
15154 (define_split
15155 [(set (match_operand:SWI24 0 "memory_operand")
15156 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15157 UNSPEC_FIST))
15158 (clobber (match_operand:SWI24 2 "memory_operand"))]
15159 "reload_completed"
15160 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15161
15162 (define_expand "lrintxf<mode>2"
15163 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15164 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15165 UNSPEC_FIST))]
15166 "TARGET_USE_FANCY_MATH_387")
15167
15168 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15169 [(set (match_operand:SWI48 0 "nonimmediate_operand")
15170 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15171 UNSPEC_FIX_NOTRUNC))]
15172 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15173
15174 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15175 [(match_operand:SWI248x 0 "nonimmediate_operand")
15176 (match_operand:X87MODEF 1 "register_operand")]
15177 "(TARGET_USE_FANCY_MATH_387
15178 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15179 || TARGET_MIX_SSE_I387)
15180 && flag_unsafe_math_optimizations)
15181 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15182 && <SWI248x:MODE>mode != HImode
15183 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15184 && !flag_trapping_math && !flag_rounding_math)"
15185 {
15186 if (optimize_insn_for_size_p ())
15187 FAIL;
15188
15189 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15190 && <SWI248x:MODE>mode != HImode
15191 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15192 && !flag_trapping_math && !flag_rounding_math)
15193 ix86_expand_lround (operands[0], operands[1]);
15194 else
15195 ix86_emit_i387_round (operands[0], operands[1]);
15196 DONE;
15197 })
15198
15199 (define_int_iterator FRNDINT_ROUNDING
15200 [UNSPEC_FRNDINT_FLOOR
15201 UNSPEC_FRNDINT_CEIL
15202 UNSPEC_FRNDINT_TRUNC])
15203
15204 (define_int_iterator FIST_ROUNDING
15205 [UNSPEC_FIST_FLOOR
15206 UNSPEC_FIST_CEIL])
15207
15208 ;; Base name for define_insn
15209 (define_int_attr rounding_insn
15210 [(UNSPEC_FRNDINT_FLOOR "floor")
15211 (UNSPEC_FRNDINT_CEIL "ceil")
15212 (UNSPEC_FRNDINT_TRUNC "btrunc")
15213 (UNSPEC_FIST_FLOOR "floor")
15214 (UNSPEC_FIST_CEIL "ceil")])
15215
15216 (define_int_attr rounding
15217 [(UNSPEC_FRNDINT_FLOOR "floor")
15218 (UNSPEC_FRNDINT_CEIL "ceil")
15219 (UNSPEC_FRNDINT_TRUNC "trunc")
15220 (UNSPEC_FIST_FLOOR "floor")
15221 (UNSPEC_FIST_CEIL "ceil")])
15222
15223 (define_int_attr ROUNDING
15224 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15225 (UNSPEC_FRNDINT_CEIL "CEIL")
15226 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15227 (UNSPEC_FIST_FLOOR "FLOOR")
15228 (UNSPEC_FIST_CEIL "CEIL")])
15229
15230 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15231 (define_insn_and_split "frndintxf2_<rounding>"
15232 [(set (match_operand:XF 0 "register_operand")
15233 (unspec:XF [(match_operand:XF 1 "register_operand")]
15234 FRNDINT_ROUNDING))
15235 (clobber (reg:CC FLAGS_REG))]
15236 "TARGET_USE_FANCY_MATH_387
15237 && flag_unsafe_math_optimizations
15238 && can_create_pseudo_p ()"
15239 "#"
15240 "&& 1"
15241 [(const_int 0)]
15242 {
15243 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15244
15245 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15246 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15247
15248 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15249 operands[2], operands[3]));
15250 DONE;
15251 }
15252 [(set_attr "type" "frndint")
15253 (set_attr "i387_cw" "<rounding>")
15254 (set_attr "mode" "XF")])
15255
15256 (define_insn "frndintxf2_<rounding>_i387"
15257 [(set (match_operand:XF 0 "register_operand" "=f")
15258 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15259 FRNDINT_ROUNDING))
15260 (use (match_operand:HI 2 "memory_operand" "m"))
15261 (use (match_operand:HI 3 "memory_operand" "m"))]
15262 "TARGET_USE_FANCY_MATH_387
15263 && flag_unsafe_math_optimizations"
15264 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15265 [(set_attr "type" "frndint")
15266 (set_attr "i387_cw" "<rounding>")
15267 (set_attr "mode" "XF")])
15268
15269 (define_expand "<rounding_insn>xf2"
15270 [(parallel [(set (match_operand:XF 0 "register_operand")
15271 (unspec:XF [(match_operand:XF 1 "register_operand")]
15272 FRNDINT_ROUNDING))
15273 (clobber (reg:CC FLAGS_REG))])]
15274 "TARGET_USE_FANCY_MATH_387
15275 && flag_unsafe_math_optimizations
15276 && !optimize_insn_for_size_p ()")
15277
15278 (define_expand "<rounding_insn><mode>2"
15279 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15280 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15281 FRNDINT_ROUNDING))
15282 (clobber (reg:CC FLAGS_REG))])]
15283 "(TARGET_USE_FANCY_MATH_387
15284 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15285 || TARGET_MIX_SSE_I387)
15286 && flag_unsafe_math_optimizations)
15287 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15288 && !flag_trapping_math)"
15289 {
15290 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15291 && !flag_trapping_math)
15292 {
15293 if (TARGET_ROUND)
15294 emit_insn (gen_sse4_1_round<mode>2
15295 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15296 else if (optimize_insn_for_size_p ())
15297 FAIL;
15298 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15299 {
15300 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15301 ix86_expand_floorceil (operands[0], operands[1], true);
15302 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15303 ix86_expand_floorceil (operands[0], operands[1], false);
15304 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15305 ix86_expand_trunc (operands[0], operands[1]);
15306 else
15307 gcc_unreachable ();
15308 }
15309 else
15310 {
15311 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15312 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15313 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15314 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15315 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15316 ix86_expand_truncdf_32 (operands[0], operands[1]);
15317 else
15318 gcc_unreachable ();
15319 }
15320 }
15321 else
15322 {
15323 rtx op0, op1;
15324
15325 if (optimize_insn_for_size_p ())
15326 FAIL;
15327
15328 op0 = gen_reg_rtx (XFmode);
15329 op1 = gen_reg_rtx (XFmode);
15330 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15331 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15332
15333 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15334 }
15335 DONE;
15336 })
15337
15338 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15339 (define_insn_and_split "frndintxf2_mask_pm"
15340 [(set (match_operand:XF 0 "register_operand")
15341 (unspec:XF [(match_operand:XF 1 "register_operand")]
15342 UNSPEC_FRNDINT_MASK_PM))
15343 (clobber (reg:CC FLAGS_REG))]
15344 "TARGET_USE_FANCY_MATH_387
15345 && flag_unsafe_math_optimizations
15346 && can_create_pseudo_p ()"
15347 "#"
15348 "&& 1"
15349 [(const_int 0)]
15350 {
15351 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15352
15353 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15354 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15355
15356 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15357 operands[2], operands[3]));
15358 DONE;
15359 }
15360 [(set_attr "type" "frndint")
15361 (set_attr "i387_cw" "mask_pm")
15362 (set_attr "mode" "XF")])
15363
15364 (define_insn "frndintxf2_mask_pm_i387"
15365 [(set (match_operand:XF 0 "register_operand" "=f")
15366 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15367 UNSPEC_FRNDINT_MASK_PM))
15368 (use (match_operand:HI 2 "memory_operand" "m"))
15369 (use (match_operand:HI 3 "memory_operand" "m"))]
15370 "TARGET_USE_FANCY_MATH_387
15371 && flag_unsafe_math_optimizations"
15372 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15373 [(set_attr "type" "frndint")
15374 (set_attr "i387_cw" "mask_pm")
15375 (set_attr "mode" "XF")])
15376
15377 (define_expand "nearbyintxf2"
15378 [(parallel [(set (match_operand:XF 0 "register_operand")
15379 (unspec:XF [(match_operand:XF 1 "register_operand")]
15380 UNSPEC_FRNDINT_MASK_PM))
15381 (clobber (reg:CC FLAGS_REG))])]
15382 "TARGET_USE_FANCY_MATH_387
15383 && flag_unsafe_math_optimizations")
15384
15385 (define_expand "nearbyint<mode>2"
15386 [(use (match_operand:MODEF 0 "register_operand"))
15387 (use (match_operand:MODEF 1 "register_operand"))]
15388 "TARGET_USE_FANCY_MATH_387
15389 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15390 || TARGET_MIX_SSE_I387)
15391 && flag_unsafe_math_optimizations"
15392 {
15393 rtx op0 = gen_reg_rtx (XFmode);
15394 rtx op1 = gen_reg_rtx (XFmode);
15395
15396 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15397 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15398
15399 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15400 DONE;
15401 })
15402
15403 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15404 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15405 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15406 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15407 FIST_ROUNDING))
15408 (clobber (reg:CC FLAGS_REG))]
15409 "TARGET_USE_FANCY_MATH_387
15410 && flag_unsafe_math_optimizations
15411 && can_create_pseudo_p ()"
15412 "#"
15413 "&& 1"
15414 [(const_int 0)]
15415 {
15416 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15417
15418 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15419 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15420 if (memory_operand (operands[0], VOIDmode))
15421 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15422 operands[2], operands[3]));
15423 else
15424 {
15425 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15426 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15427 (operands[0], operands[1], operands[2],
15428 operands[3], operands[4]));
15429 }
15430 DONE;
15431 }
15432 [(set_attr "type" "fistp")
15433 (set_attr "i387_cw" "<rounding>")
15434 (set_attr "mode" "<MODE>")])
15435
15436 (define_insn "fistdi2_<rounding>"
15437 [(set (match_operand:DI 0 "memory_operand" "=m")
15438 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15439 FIST_ROUNDING))
15440 (use (match_operand:HI 2 "memory_operand" "m"))
15441 (use (match_operand:HI 3 "memory_operand" "m"))
15442 (clobber (match_scratch:XF 4 "=&1f"))]
15443 "TARGET_USE_FANCY_MATH_387
15444 && flag_unsafe_math_optimizations"
15445 "* return output_fix_trunc (insn, operands, false);"
15446 [(set_attr "type" "fistp")
15447 (set_attr "i387_cw" "<rounding>")
15448 (set_attr "mode" "DI")])
15449
15450 (define_insn "fistdi2_<rounding>_with_temp"
15451 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15452 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15453 FIST_ROUNDING))
15454 (use (match_operand:HI 2 "memory_operand" "m,m"))
15455 (use (match_operand:HI 3 "memory_operand" "m,m"))
15456 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15457 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15458 "TARGET_USE_FANCY_MATH_387
15459 && flag_unsafe_math_optimizations"
15460 "#"
15461 [(set_attr "type" "fistp")
15462 (set_attr "i387_cw" "<rounding>")
15463 (set_attr "mode" "DI")])
15464
15465 (define_split
15466 [(set (match_operand:DI 0 "register_operand")
15467 (unspec:DI [(match_operand:XF 1 "register_operand")]
15468 FIST_ROUNDING))
15469 (use (match_operand:HI 2 "memory_operand"))
15470 (use (match_operand:HI 3 "memory_operand"))
15471 (clobber (match_operand:DI 4 "memory_operand"))
15472 (clobber (match_scratch 5))]
15473 "reload_completed"
15474 [(parallel [(set (match_dup 4)
15475 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15476 (use (match_dup 2))
15477 (use (match_dup 3))
15478 (clobber (match_dup 5))])
15479 (set (match_dup 0) (match_dup 4))])
15480
15481 (define_split
15482 [(set (match_operand:DI 0 "memory_operand")
15483 (unspec:DI [(match_operand:XF 1 "register_operand")]
15484 FIST_ROUNDING))
15485 (use (match_operand:HI 2 "memory_operand"))
15486 (use (match_operand:HI 3 "memory_operand"))
15487 (clobber (match_operand:DI 4 "memory_operand"))
15488 (clobber (match_scratch 5))]
15489 "reload_completed"
15490 [(parallel [(set (match_dup 0)
15491 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15492 (use (match_dup 2))
15493 (use (match_dup 3))
15494 (clobber (match_dup 5))])])
15495
15496 (define_insn "fist<mode>2_<rounding>"
15497 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15498 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15499 FIST_ROUNDING))
15500 (use (match_operand:HI 2 "memory_operand" "m"))
15501 (use (match_operand:HI 3 "memory_operand" "m"))]
15502 "TARGET_USE_FANCY_MATH_387
15503 && flag_unsafe_math_optimizations"
15504 "* return output_fix_trunc (insn, operands, false);"
15505 [(set_attr "type" "fistp")
15506 (set_attr "i387_cw" "<rounding>")
15507 (set_attr "mode" "<MODE>")])
15508
15509 (define_insn "fist<mode>2_<rounding>_with_temp"
15510 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15511 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15512 FIST_ROUNDING))
15513 (use (match_operand:HI 2 "memory_operand" "m,m"))
15514 (use (match_operand:HI 3 "memory_operand" "m,m"))
15515 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15516 "TARGET_USE_FANCY_MATH_387
15517 && flag_unsafe_math_optimizations"
15518 "#"
15519 [(set_attr "type" "fistp")
15520 (set_attr "i387_cw" "<rounding>")
15521 (set_attr "mode" "<MODE>")])
15522
15523 (define_split
15524 [(set (match_operand:SWI24 0 "register_operand")
15525 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15526 FIST_ROUNDING))
15527 (use (match_operand:HI 2 "memory_operand"))
15528 (use (match_operand:HI 3 "memory_operand"))
15529 (clobber (match_operand:SWI24 4 "memory_operand"))]
15530 "reload_completed"
15531 [(parallel [(set (match_dup 4)
15532 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15533 (use (match_dup 2))
15534 (use (match_dup 3))])
15535 (set (match_dup 0) (match_dup 4))])
15536
15537 (define_split
15538 [(set (match_operand:SWI24 0 "memory_operand")
15539 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15540 FIST_ROUNDING))
15541 (use (match_operand:HI 2 "memory_operand"))
15542 (use (match_operand:HI 3 "memory_operand"))
15543 (clobber (match_operand:SWI24 4 "memory_operand"))]
15544 "reload_completed"
15545 [(parallel [(set (match_dup 0)
15546 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15547 (use (match_dup 2))
15548 (use (match_dup 3))])])
15549
15550 (define_expand "l<rounding_insn>xf<mode>2"
15551 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15552 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15553 FIST_ROUNDING))
15554 (clobber (reg:CC FLAGS_REG))])]
15555 "TARGET_USE_FANCY_MATH_387
15556 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15557 && flag_unsafe_math_optimizations")
15558
15559 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15560 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15561 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15562 FIST_ROUNDING))
15563 (clobber (reg:CC FLAGS_REG))])]
15564 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15565 && !flag_trapping_math"
15566 {
15567 if (TARGET_64BIT && optimize_insn_for_size_p ())
15568 FAIL;
15569
15570 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15571 ix86_expand_lfloorceil (operands[0], operands[1], true);
15572 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15573 ix86_expand_lfloorceil (operands[0], operands[1], false);
15574 else
15575 gcc_unreachable ();
15576
15577 DONE;
15578 })
15579
15580 (define_insn "fxam<mode>2_i387"
15581 [(set (match_operand:HI 0 "register_operand" "=a")
15582 (unspec:HI
15583 [(match_operand:X87MODEF 1 "register_operand" "f")]
15584 UNSPEC_FXAM))]
15585 "TARGET_USE_FANCY_MATH_387"
15586 "fxam\n\tfnstsw\t%0"
15587 [(set_attr "type" "multi")
15588 (set_attr "length" "4")
15589 (set_attr "unit" "i387")
15590 (set_attr "mode" "<MODE>")])
15591
15592 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15593 [(set (match_operand:HI 0 "register_operand")
15594 (unspec:HI
15595 [(match_operand:MODEF 1 "memory_operand")]
15596 UNSPEC_FXAM_MEM))]
15597 "TARGET_USE_FANCY_MATH_387
15598 && can_create_pseudo_p ()"
15599 "#"
15600 "&& 1"
15601 [(set (match_dup 2)(match_dup 1))
15602 (set (match_dup 0)
15603 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15604 {
15605 operands[2] = gen_reg_rtx (<MODE>mode);
15606
15607 MEM_VOLATILE_P (operands[1]) = 1;
15608 }
15609 [(set_attr "type" "multi")
15610 (set_attr "unit" "i387")
15611 (set_attr "mode" "<MODE>")])
15612
15613 (define_expand "isinfxf2"
15614 [(use (match_operand:SI 0 "register_operand"))
15615 (use (match_operand:XF 1 "register_operand"))]
15616 "TARGET_USE_FANCY_MATH_387
15617 && ix86_libc_has_function (function_c99_misc)"
15618 {
15619 rtx mask = GEN_INT (0x45);
15620 rtx val = GEN_INT (0x05);
15621
15622 rtx cond;
15623
15624 rtx scratch = gen_reg_rtx (HImode);
15625 rtx res = gen_reg_rtx (QImode);
15626
15627 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15628
15629 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15630 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15631 cond = gen_rtx_fmt_ee (EQ, QImode,
15632 gen_rtx_REG (CCmode, FLAGS_REG),
15633 const0_rtx);
15634 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15635 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15636 DONE;
15637 })
15638
15639 (define_expand "isinf<mode>2"
15640 [(use (match_operand:SI 0 "register_operand"))
15641 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15642 "TARGET_USE_FANCY_MATH_387
15643 && ix86_libc_has_function (function_c99_misc)
15644 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15645 {
15646 rtx mask = GEN_INT (0x45);
15647 rtx val = GEN_INT (0x05);
15648
15649 rtx cond;
15650
15651 rtx scratch = gen_reg_rtx (HImode);
15652 rtx res = gen_reg_rtx (QImode);
15653
15654 /* Remove excess precision by forcing value through memory. */
15655 if (memory_operand (operands[1], VOIDmode))
15656 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15657 else
15658 {
15659 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15660
15661 emit_move_insn (temp, operands[1]);
15662 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15663 }
15664
15665 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15666 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15667 cond = gen_rtx_fmt_ee (EQ, QImode,
15668 gen_rtx_REG (CCmode, FLAGS_REG),
15669 const0_rtx);
15670 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15671 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15672 DONE;
15673 })
15674
15675 (define_expand "signbitxf2"
15676 [(use (match_operand:SI 0 "register_operand"))
15677 (use (match_operand:XF 1 "register_operand"))]
15678 "TARGET_USE_FANCY_MATH_387"
15679 {
15680 rtx scratch = gen_reg_rtx (HImode);
15681
15682 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15683 emit_insn (gen_andsi3 (operands[0],
15684 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15685 DONE;
15686 })
15687
15688 (define_insn "movmsk_df"
15689 [(set (match_operand:SI 0 "register_operand" "=r")
15690 (unspec:SI
15691 [(match_operand:DF 1 "register_operand" "x")]
15692 UNSPEC_MOVMSK))]
15693 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15694 "%vmovmskpd\t{%1, %0|%0, %1}"
15695 [(set_attr "type" "ssemov")
15696 (set_attr "prefix" "maybe_vex")
15697 (set_attr "mode" "DF")])
15698
15699 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15700 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15701 (define_expand "signbitdf2"
15702 [(use (match_operand:SI 0 "register_operand"))
15703 (use (match_operand:DF 1 "register_operand"))]
15704 "TARGET_USE_FANCY_MATH_387
15705 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15706 {
15707 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15708 {
15709 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15710 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15711 }
15712 else
15713 {
15714 rtx scratch = gen_reg_rtx (HImode);
15715
15716 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15717 emit_insn (gen_andsi3 (operands[0],
15718 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15719 }
15720 DONE;
15721 })
15722
15723 (define_expand "signbitsf2"
15724 [(use (match_operand:SI 0 "register_operand"))
15725 (use (match_operand:SF 1 "register_operand"))]
15726 "TARGET_USE_FANCY_MATH_387
15727 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15728 {
15729 rtx scratch = gen_reg_rtx (HImode);
15730
15731 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15732 emit_insn (gen_andsi3 (operands[0],
15733 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15734 DONE;
15735 })
15736 \f
15737 ;; Block operation instructions
15738
15739 (define_insn "cld"
15740 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15741 ""
15742 "cld"
15743 [(set_attr "length" "1")
15744 (set_attr "length_immediate" "0")
15745 (set_attr "modrm" "0")])
15746
15747 (define_expand "movmem<mode>"
15748 [(use (match_operand:BLK 0 "memory_operand"))
15749 (use (match_operand:BLK 1 "memory_operand"))
15750 (use (match_operand:SWI48 2 "nonmemory_operand"))
15751 (use (match_operand:SWI48 3 "const_int_operand"))
15752 (use (match_operand:SI 4 "const_int_operand"))
15753 (use (match_operand:SI 5 "const_int_operand"))
15754 (use (match_operand:SI 6 ""))
15755 (use (match_operand:SI 7 ""))
15756 (use (match_operand:SI 8 ""))]
15757 ""
15758 {
15759 if (ix86_expand_set_or_movmem (operands[0], operands[1],
15760 operands[2], NULL, operands[3],
15761 operands[4], operands[5],
15762 operands[6], operands[7],
15763 operands[8], false))
15764 DONE;
15765 else
15766 FAIL;
15767 })
15768
15769 ;; Most CPUs don't like single string operations
15770 ;; Handle this case here to simplify previous expander.
15771
15772 (define_expand "strmov"
15773 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15774 (set (match_operand 1 "memory_operand") (match_dup 4))
15775 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15776 (clobber (reg:CC FLAGS_REG))])
15777 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15778 (clobber (reg:CC FLAGS_REG))])]
15779 ""
15780 {
15781 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15782
15783 /* If .md ever supports :P for Pmode, these can be directly
15784 in the pattern above. */
15785 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15786 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15787
15788 /* Can't use this if the user has appropriated esi or edi. */
15789 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15790 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15791 {
15792 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15793 operands[2], operands[3],
15794 operands[5], operands[6]));
15795 DONE;
15796 }
15797
15798 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15799 })
15800
15801 (define_expand "strmov_singleop"
15802 [(parallel [(set (match_operand 1 "memory_operand")
15803 (match_operand 3 "memory_operand"))
15804 (set (match_operand 0 "register_operand")
15805 (match_operand 4))
15806 (set (match_operand 2 "register_operand")
15807 (match_operand 5))])]
15808 ""
15809 "ix86_current_function_needs_cld = 1;")
15810
15811 (define_insn "*strmovdi_rex_1"
15812 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15813 (mem:DI (match_operand:P 3 "register_operand" "1")))
15814 (set (match_operand:P 0 "register_operand" "=D")
15815 (plus:P (match_dup 2)
15816 (const_int 8)))
15817 (set (match_operand:P 1 "register_operand" "=S")
15818 (plus:P (match_dup 3)
15819 (const_int 8)))]
15820 "TARGET_64BIT
15821 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15822 "%^movsq"
15823 [(set_attr "type" "str")
15824 (set_attr "memory" "both")
15825 (set_attr "mode" "DI")])
15826
15827 (define_insn "*strmovsi_1"
15828 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15829 (mem:SI (match_operand:P 3 "register_operand" "1")))
15830 (set (match_operand:P 0 "register_operand" "=D")
15831 (plus:P (match_dup 2)
15832 (const_int 4)))
15833 (set (match_operand:P 1 "register_operand" "=S")
15834 (plus:P (match_dup 3)
15835 (const_int 4)))]
15836 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15837 "%^movs{l|d}"
15838 [(set_attr "type" "str")
15839 (set_attr "memory" "both")
15840 (set_attr "mode" "SI")])
15841
15842 (define_insn "*strmovhi_1"
15843 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15844 (mem:HI (match_operand:P 3 "register_operand" "1")))
15845 (set (match_operand:P 0 "register_operand" "=D")
15846 (plus:P (match_dup 2)
15847 (const_int 2)))
15848 (set (match_operand:P 1 "register_operand" "=S")
15849 (plus:P (match_dup 3)
15850 (const_int 2)))]
15851 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15852 "%^movsw"
15853 [(set_attr "type" "str")
15854 (set_attr "memory" "both")
15855 (set_attr "mode" "HI")])
15856
15857 (define_insn "*strmovqi_1"
15858 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15859 (mem:QI (match_operand:P 3 "register_operand" "1")))
15860 (set (match_operand:P 0 "register_operand" "=D")
15861 (plus:P (match_dup 2)
15862 (const_int 1)))
15863 (set (match_operand:P 1 "register_operand" "=S")
15864 (plus:P (match_dup 3)
15865 (const_int 1)))]
15866 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15867 "%^movsb"
15868 [(set_attr "type" "str")
15869 (set_attr "memory" "both")
15870 (set (attr "prefix_rex")
15871 (if_then_else
15872 (match_test "<P:MODE>mode == DImode")
15873 (const_string "0")
15874 (const_string "*")))
15875 (set_attr "mode" "QI")])
15876
15877 (define_expand "rep_mov"
15878 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15879 (set (match_operand 0 "register_operand")
15880 (match_operand 5))
15881 (set (match_operand 2 "register_operand")
15882 (match_operand 6))
15883 (set (match_operand 1 "memory_operand")
15884 (match_operand 3 "memory_operand"))
15885 (use (match_dup 4))])]
15886 ""
15887 "ix86_current_function_needs_cld = 1;")
15888
15889 (define_insn "*rep_movdi_rex64"
15890 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15891 (set (match_operand:P 0 "register_operand" "=D")
15892 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15893 (const_int 3))
15894 (match_operand:P 3 "register_operand" "0")))
15895 (set (match_operand:P 1 "register_operand" "=S")
15896 (plus:P (ashift:P (match_dup 5) (const_int 3))
15897 (match_operand:P 4 "register_operand" "1")))
15898 (set (mem:BLK (match_dup 3))
15899 (mem:BLK (match_dup 4)))
15900 (use (match_dup 5))]
15901 "TARGET_64BIT
15902 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15903 "%^rep{%;} movsq"
15904 [(set_attr "type" "str")
15905 (set_attr "prefix_rep" "1")
15906 (set_attr "memory" "both")
15907 (set_attr "mode" "DI")])
15908
15909 (define_insn "*rep_movsi"
15910 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15911 (set (match_operand:P 0 "register_operand" "=D")
15912 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15913 (const_int 2))
15914 (match_operand:P 3 "register_operand" "0")))
15915 (set (match_operand:P 1 "register_operand" "=S")
15916 (plus:P (ashift:P (match_dup 5) (const_int 2))
15917 (match_operand:P 4 "register_operand" "1")))
15918 (set (mem:BLK (match_dup 3))
15919 (mem:BLK (match_dup 4)))
15920 (use (match_dup 5))]
15921 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15922 "%^rep{%;} movs{l|d}"
15923 [(set_attr "type" "str")
15924 (set_attr "prefix_rep" "1")
15925 (set_attr "memory" "both")
15926 (set_attr "mode" "SI")])
15927
15928 (define_insn "*rep_movqi"
15929 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15930 (set (match_operand:P 0 "register_operand" "=D")
15931 (plus:P (match_operand:P 3 "register_operand" "0")
15932 (match_operand:P 5 "register_operand" "2")))
15933 (set (match_operand:P 1 "register_operand" "=S")
15934 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15935 (set (mem:BLK (match_dup 3))
15936 (mem:BLK (match_dup 4)))
15937 (use (match_dup 5))]
15938 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15939 "%^rep{%;} movsb"
15940 [(set_attr "type" "str")
15941 (set_attr "prefix_rep" "1")
15942 (set_attr "memory" "both")
15943 (set_attr "mode" "QI")])
15944
15945 (define_expand "setmem<mode>"
15946 [(use (match_operand:BLK 0 "memory_operand"))
15947 (use (match_operand:SWI48 1 "nonmemory_operand"))
15948 (use (match_operand:QI 2 "nonmemory_operand"))
15949 (use (match_operand 3 "const_int_operand"))
15950 (use (match_operand:SI 4 "const_int_operand"))
15951 (use (match_operand:SI 5 "const_int_operand"))
15952 (use (match_operand:SI 6 ""))
15953 (use (match_operand:SI 7 ""))
15954 (use (match_operand:SI 8 ""))]
15955 ""
15956 {
15957 if (ix86_expand_set_or_movmem (operands[0], NULL,
15958 operands[1], operands[2],
15959 operands[3], operands[4],
15960 operands[5], operands[6],
15961 operands[7], operands[8], true))
15962 DONE;
15963 else
15964 FAIL;
15965 })
15966
15967 ;; Most CPUs don't like single string operations
15968 ;; Handle this case here to simplify previous expander.
15969
15970 (define_expand "strset"
15971 [(set (match_operand 1 "memory_operand")
15972 (match_operand 2 "register_operand"))
15973 (parallel [(set (match_operand 0 "register_operand")
15974 (match_dup 3))
15975 (clobber (reg:CC FLAGS_REG))])]
15976 ""
15977 {
15978 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15979 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15980
15981 /* If .md ever supports :P for Pmode, this can be directly
15982 in the pattern above. */
15983 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15984 GEN_INT (GET_MODE_SIZE (GET_MODE
15985 (operands[2]))));
15986 /* Can't use this if the user has appropriated eax or edi. */
15987 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15988 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15989 {
15990 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15991 operands[3]));
15992 DONE;
15993 }
15994 })
15995
15996 (define_expand "strset_singleop"
15997 [(parallel [(set (match_operand 1 "memory_operand")
15998 (match_operand 2 "register_operand"))
15999 (set (match_operand 0 "register_operand")
16000 (match_operand 3))
16001 (unspec [(const_int 0)] UNSPEC_STOS)])]
16002 ""
16003 "ix86_current_function_needs_cld = 1;")
16004
16005 (define_insn "*strsetdi_rex_1"
16006 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16007 (match_operand:DI 2 "register_operand" "a"))
16008 (set (match_operand:P 0 "register_operand" "=D")
16009 (plus:P (match_dup 1)
16010 (const_int 8)))
16011 (unspec [(const_int 0)] UNSPEC_STOS)]
16012 "TARGET_64BIT
16013 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16014 "%^stosq"
16015 [(set_attr "type" "str")
16016 (set_attr "memory" "store")
16017 (set_attr "mode" "DI")])
16018
16019 (define_insn "*strsetsi_1"
16020 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16021 (match_operand:SI 2 "register_operand" "a"))
16022 (set (match_operand:P 0 "register_operand" "=D")
16023 (plus:P (match_dup 1)
16024 (const_int 4)))
16025 (unspec [(const_int 0)] UNSPEC_STOS)]
16026 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16027 "%^stos{l|d}"
16028 [(set_attr "type" "str")
16029 (set_attr "memory" "store")
16030 (set_attr "mode" "SI")])
16031
16032 (define_insn "*strsethi_1"
16033 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16034 (match_operand:HI 2 "register_operand" "a"))
16035 (set (match_operand:P 0 "register_operand" "=D")
16036 (plus:P (match_dup 1)
16037 (const_int 2)))
16038 (unspec [(const_int 0)] UNSPEC_STOS)]
16039 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16040 "%^stosw"
16041 [(set_attr "type" "str")
16042 (set_attr "memory" "store")
16043 (set_attr "mode" "HI")])
16044
16045 (define_insn "*strsetqi_1"
16046 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16047 (match_operand:QI 2 "register_operand" "a"))
16048 (set (match_operand:P 0 "register_operand" "=D")
16049 (plus:P (match_dup 1)
16050 (const_int 1)))
16051 (unspec [(const_int 0)] UNSPEC_STOS)]
16052 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16053 "%^stosb"
16054 [(set_attr "type" "str")
16055 (set_attr "memory" "store")
16056 (set (attr "prefix_rex")
16057 (if_then_else
16058 (match_test "<P:MODE>mode == DImode")
16059 (const_string "0")
16060 (const_string "*")))
16061 (set_attr "mode" "QI")])
16062
16063 (define_expand "rep_stos"
16064 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16065 (set (match_operand 0 "register_operand")
16066 (match_operand 4))
16067 (set (match_operand 2 "memory_operand") (const_int 0))
16068 (use (match_operand 3 "register_operand"))
16069 (use (match_dup 1))])]
16070 ""
16071 "ix86_current_function_needs_cld = 1;")
16072
16073 (define_insn "*rep_stosdi_rex64"
16074 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16075 (set (match_operand:P 0 "register_operand" "=D")
16076 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16077 (const_int 3))
16078 (match_operand:P 3 "register_operand" "0")))
16079 (set (mem:BLK (match_dup 3))
16080 (const_int 0))
16081 (use (match_operand:DI 2 "register_operand" "a"))
16082 (use (match_dup 4))]
16083 "TARGET_64BIT
16084 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16085 "%^rep{%;} stosq"
16086 [(set_attr "type" "str")
16087 (set_attr "prefix_rep" "1")
16088 (set_attr "memory" "store")
16089 (set_attr "mode" "DI")])
16090
16091 (define_insn "*rep_stossi"
16092 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16093 (set (match_operand:P 0 "register_operand" "=D")
16094 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16095 (const_int 2))
16096 (match_operand:P 3 "register_operand" "0")))
16097 (set (mem:BLK (match_dup 3))
16098 (const_int 0))
16099 (use (match_operand:SI 2 "register_operand" "a"))
16100 (use (match_dup 4))]
16101 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16102 "%^rep{%;} stos{l|d}"
16103 [(set_attr "type" "str")
16104 (set_attr "prefix_rep" "1")
16105 (set_attr "memory" "store")
16106 (set_attr "mode" "SI")])
16107
16108 (define_insn "*rep_stosqi"
16109 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16110 (set (match_operand:P 0 "register_operand" "=D")
16111 (plus:P (match_operand:P 3 "register_operand" "0")
16112 (match_operand:P 4 "register_operand" "1")))
16113 (set (mem:BLK (match_dup 3))
16114 (const_int 0))
16115 (use (match_operand:QI 2 "register_operand" "a"))
16116 (use (match_dup 4))]
16117 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16118 "%^rep{%;} stosb"
16119 [(set_attr "type" "str")
16120 (set_attr "prefix_rep" "1")
16121 (set_attr "memory" "store")
16122 (set (attr "prefix_rex")
16123 (if_then_else
16124 (match_test "<P:MODE>mode == DImode")
16125 (const_string "0")
16126 (const_string "*")))
16127 (set_attr "mode" "QI")])
16128
16129 (define_expand "cmpstrnsi"
16130 [(set (match_operand:SI 0 "register_operand")
16131 (compare:SI (match_operand:BLK 1 "general_operand")
16132 (match_operand:BLK 2 "general_operand")))
16133 (use (match_operand 3 "general_operand"))
16134 (use (match_operand 4 "immediate_operand"))]
16135 ""
16136 {
16137 rtx addr1, addr2, out, outlow, count, countreg, align;
16138
16139 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16140 FAIL;
16141
16142 /* Can't use this if the user has appropriated ecx, esi or edi. */
16143 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16144 FAIL;
16145
16146 out = operands[0];
16147 if (!REG_P (out))
16148 out = gen_reg_rtx (SImode);
16149
16150 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16151 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16152 if (addr1 != XEXP (operands[1], 0))
16153 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16154 if (addr2 != XEXP (operands[2], 0))
16155 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16156
16157 count = operands[3];
16158 countreg = ix86_zero_extend_to_Pmode (count);
16159
16160 /* %%% Iff we are testing strict equality, we can use known alignment
16161 to good advantage. This may be possible with combine, particularly
16162 once cc0 is dead. */
16163 align = operands[4];
16164
16165 if (CONST_INT_P (count))
16166 {
16167 if (INTVAL (count) == 0)
16168 {
16169 emit_move_insn (operands[0], const0_rtx);
16170 DONE;
16171 }
16172 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16173 operands[1], operands[2]));
16174 }
16175 else
16176 {
16177 rtx (*gen_cmp) (rtx, rtx);
16178
16179 gen_cmp = (TARGET_64BIT
16180 ? gen_cmpdi_1 : gen_cmpsi_1);
16181
16182 emit_insn (gen_cmp (countreg, countreg));
16183 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16184 operands[1], operands[2]));
16185 }
16186
16187 outlow = gen_lowpart (QImode, out);
16188 emit_insn (gen_cmpintqi (outlow));
16189 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16190
16191 if (operands[0] != out)
16192 emit_move_insn (operands[0], out);
16193
16194 DONE;
16195 })
16196
16197 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16198
16199 (define_expand "cmpintqi"
16200 [(set (match_dup 1)
16201 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16202 (set (match_dup 2)
16203 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16204 (parallel [(set (match_operand:QI 0 "register_operand")
16205 (minus:QI (match_dup 1)
16206 (match_dup 2)))
16207 (clobber (reg:CC FLAGS_REG))])]
16208 ""
16209 {
16210 operands[1] = gen_reg_rtx (QImode);
16211 operands[2] = gen_reg_rtx (QImode);
16212 })
16213
16214 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16215 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16216
16217 (define_expand "cmpstrnqi_nz_1"
16218 [(parallel [(set (reg:CC FLAGS_REG)
16219 (compare:CC (match_operand 4 "memory_operand")
16220 (match_operand 5 "memory_operand")))
16221 (use (match_operand 2 "register_operand"))
16222 (use (match_operand:SI 3 "immediate_operand"))
16223 (clobber (match_operand 0 "register_operand"))
16224 (clobber (match_operand 1 "register_operand"))
16225 (clobber (match_dup 2))])]
16226 ""
16227 "ix86_current_function_needs_cld = 1;")
16228
16229 (define_insn "*cmpstrnqi_nz_1"
16230 [(set (reg:CC FLAGS_REG)
16231 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16232 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16233 (use (match_operand:P 6 "register_operand" "2"))
16234 (use (match_operand:SI 3 "immediate_operand" "i"))
16235 (clobber (match_operand:P 0 "register_operand" "=S"))
16236 (clobber (match_operand:P 1 "register_operand" "=D"))
16237 (clobber (match_operand:P 2 "register_operand" "=c"))]
16238 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16239 "%^repz{%;} cmpsb"
16240 [(set_attr "type" "str")
16241 (set_attr "mode" "QI")
16242 (set (attr "prefix_rex")
16243 (if_then_else
16244 (match_test "<P:MODE>mode == DImode")
16245 (const_string "0")
16246 (const_string "*")))
16247 (set_attr "prefix_rep" "1")])
16248
16249 ;; The same, but the count is not known to not be zero.
16250
16251 (define_expand "cmpstrnqi_1"
16252 [(parallel [(set (reg:CC FLAGS_REG)
16253 (if_then_else:CC (ne (match_operand 2 "register_operand")
16254 (const_int 0))
16255 (compare:CC (match_operand 4 "memory_operand")
16256 (match_operand 5 "memory_operand"))
16257 (const_int 0)))
16258 (use (match_operand:SI 3 "immediate_operand"))
16259 (use (reg:CC FLAGS_REG))
16260 (clobber (match_operand 0 "register_operand"))
16261 (clobber (match_operand 1 "register_operand"))
16262 (clobber (match_dup 2))])]
16263 ""
16264 "ix86_current_function_needs_cld = 1;")
16265
16266 (define_insn "*cmpstrnqi_1"
16267 [(set (reg:CC FLAGS_REG)
16268 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16269 (const_int 0))
16270 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16271 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16272 (const_int 0)))
16273 (use (match_operand:SI 3 "immediate_operand" "i"))
16274 (use (reg:CC FLAGS_REG))
16275 (clobber (match_operand:P 0 "register_operand" "=S"))
16276 (clobber (match_operand:P 1 "register_operand" "=D"))
16277 (clobber (match_operand:P 2 "register_operand" "=c"))]
16278 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16279 "%^repz{%;} cmpsb"
16280 [(set_attr "type" "str")
16281 (set_attr "mode" "QI")
16282 (set (attr "prefix_rex")
16283 (if_then_else
16284 (match_test "<P:MODE>mode == DImode")
16285 (const_string "0")
16286 (const_string "*")))
16287 (set_attr "prefix_rep" "1")])
16288
16289 (define_expand "strlen<mode>"
16290 [(set (match_operand:P 0 "register_operand")
16291 (unspec:P [(match_operand:BLK 1 "general_operand")
16292 (match_operand:QI 2 "immediate_operand")
16293 (match_operand 3 "immediate_operand")]
16294 UNSPEC_SCAS))]
16295 ""
16296 {
16297 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16298 DONE;
16299 else
16300 FAIL;
16301 })
16302
16303 (define_expand "strlenqi_1"
16304 [(parallel [(set (match_operand 0 "register_operand")
16305 (match_operand 2))
16306 (clobber (match_operand 1 "register_operand"))
16307 (clobber (reg:CC FLAGS_REG))])]
16308 ""
16309 "ix86_current_function_needs_cld = 1;")
16310
16311 (define_insn "*strlenqi_1"
16312 [(set (match_operand:P 0 "register_operand" "=&c")
16313 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16314 (match_operand:QI 2 "register_operand" "a")
16315 (match_operand:P 3 "immediate_operand" "i")
16316 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16317 (clobber (match_operand:P 1 "register_operand" "=D"))
16318 (clobber (reg:CC FLAGS_REG))]
16319 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16320 "%^repnz{%;} scasb"
16321 [(set_attr "type" "str")
16322 (set_attr "mode" "QI")
16323 (set (attr "prefix_rex")
16324 (if_then_else
16325 (match_test "<P:MODE>mode == DImode")
16326 (const_string "0")
16327 (const_string "*")))
16328 (set_attr "prefix_rep" "1")])
16329
16330 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16331 ;; handled in combine, but it is not currently up to the task.
16332 ;; When used for their truth value, the cmpstrn* expanders generate
16333 ;; code like this:
16334 ;;
16335 ;; repz cmpsb
16336 ;; seta %al
16337 ;; setb %dl
16338 ;; cmpb %al, %dl
16339 ;; jcc label
16340 ;;
16341 ;; The intermediate three instructions are unnecessary.
16342
16343 ;; This one handles cmpstrn*_nz_1...
16344 (define_peephole2
16345 [(parallel[
16346 (set (reg:CC FLAGS_REG)
16347 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16348 (mem:BLK (match_operand 5 "register_operand"))))
16349 (use (match_operand 6 "register_operand"))
16350 (use (match_operand:SI 3 "immediate_operand"))
16351 (clobber (match_operand 0 "register_operand"))
16352 (clobber (match_operand 1 "register_operand"))
16353 (clobber (match_operand 2 "register_operand"))])
16354 (set (match_operand:QI 7 "register_operand")
16355 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16356 (set (match_operand:QI 8 "register_operand")
16357 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16358 (set (reg FLAGS_REG)
16359 (compare (match_dup 7) (match_dup 8)))
16360 ]
16361 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16362 [(parallel[
16363 (set (reg:CC FLAGS_REG)
16364 (compare:CC (mem:BLK (match_dup 4))
16365 (mem:BLK (match_dup 5))))
16366 (use (match_dup 6))
16367 (use (match_dup 3))
16368 (clobber (match_dup 0))
16369 (clobber (match_dup 1))
16370 (clobber (match_dup 2))])])
16371
16372 ;; ...and this one handles cmpstrn*_1.
16373 (define_peephole2
16374 [(parallel[
16375 (set (reg:CC FLAGS_REG)
16376 (if_then_else:CC (ne (match_operand 6 "register_operand")
16377 (const_int 0))
16378 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16379 (mem:BLK (match_operand 5 "register_operand")))
16380 (const_int 0)))
16381 (use (match_operand:SI 3 "immediate_operand"))
16382 (use (reg:CC FLAGS_REG))
16383 (clobber (match_operand 0 "register_operand"))
16384 (clobber (match_operand 1 "register_operand"))
16385 (clobber (match_operand 2 "register_operand"))])
16386 (set (match_operand:QI 7 "register_operand")
16387 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16388 (set (match_operand:QI 8 "register_operand")
16389 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16390 (set (reg FLAGS_REG)
16391 (compare (match_dup 7) (match_dup 8)))
16392 ]
16393 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16394 [(parallel[
16395 (set (reg:CC FLAGS_REG)
16396 (if_then_else:CC (ne (match_dup 6)
16397 (const_int 0))
16398 (compare:CC (mem:BLK (match_dup 4))
16399 (mem:BLK (match_dup 5)))
16400 (const_int 0)))
16401 (use (match_dup 3))
16402 (use (reg:CC FLAGS_REG))
16403 (clobber (match_dup 0))
16404 (clobber (match_dup 1))
16405 (clobber (match_dup 2))])])
16406 \f
16407 ;; Conditional move instructions.
16408
16409 (define_expand "mov<mode>cc"
16410 [(set (match_operand:SWIM 0 "register_operand")
16411 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16412 (match_operand:SWIM 2 "<general_operand>")
16413 (match_operand:SWIM 3 "<general_operand>")))]
16414 ""
16415 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16416
16417 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16418 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16419 ;; So just document what we're doing explicitly.
16420
16421 (define_expand "x86_mov<mode>cc_0_m1"
16422 [(parallel
16423 [(set (match_operand:SWI48 0 "register_operand")
16424 (if_then_else:SWI48
16425 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16426 [(match_operand 1 "flags_reg_operand")
16427 (const_int 0)])
16428 (const_int -1)
16429 (const_int 0)))
16430 (clobber (reg:CC FLAGS_REG))])])
16431
16432 (define_insn "*x86_mov<mode>cc_0_m1"
16433 [(set (match_operand:SWI48 0 "register_operand" "=r")
16434 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16435 [(reg FLAGS_REG) (const_int 0)])
16436 (const_int -1)
16437 (const_int 0)))
16438 (clobber (reg:CC FLAGS_REG))]
16439 ""
16440 "sbb{<imodesuffix>}\t%0, %0"
16441 ; Since we don't have the proper number of operands for an alu insn,
16442 ; fill in all the blanks.
16443 [(set_attr "type" "alu")
16444 (set_attr "use_carry" "1")
16445 (set_attr "pent_pair" "pu")
16446 (set_attr "memory" "none")
16447 (set_attr "imm_disp" "false")
16448 (set_attr "mode" "<MODE>")
16449 (set_attr "length_immediate" "0")])
16450
16451 (define_insn "*x86_mov<mode>cc_0_m1_se"
16452 [(set (match_operand:SWI48 0 "register_operand" "=r")
16453 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16454 [(reg FLAGS_REG) (const_int 0)])
16455 (const_int 1)
16456 (const_int 0)))
16457 (clobber (reg:CC FLAGS_REG))]
16458 ""
16459 "sbb{<imodesuffix>}\t%0, %0"
16460 [(set_attr "type" "alu")
16461 (set_attr "use_carry" "1")
16462 (set_attr "pent_pair" "pu")
16463 (set_attr "memory" "none")
16464 (set_attr "imm_disp" "false")
16465 (set_attr "mode" "<MODE>")
16466 (set_attr "length_immediate" "0")])
16467
16468 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16469 [(set (match_operand:SWI48 0 "register_operand" "=r")
16470 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16471 [(reg FLAGS_REG) (const_int 0)])))
16472 (clobber (reg:CC FLAGS_REG))]
16473 ""
16474 "sbb{<imodesuffix>}\t%0, %0"
16475 [(set_attr "type" "alu")
16476 (set_attr "use_carry" "1")
16477 (set_attr "pent_pair" "pu")
16478 (set_attr "memory" "none")
16479 (set_attr "imm_disp" "false")
16480 (set_attr "mode" "<MODE>")
16481 (set_attr "length_immediate" "0")])
16482
16483 (define_insn "*mov<mode>cc_noc"
16484 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16485 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16486 [(reg FLAGS_REG) (const_int 0)])
16487 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16488 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16489 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16490 "@
16491 cmov%O2%C1\t{%2, %0|%0, %2}
16492 cmov%O2%c1\t{%3, %0|%0, %3}"
16493 [(set_attr "type" "icmov")
16494 (set_attr "mode" "<MODE>")])
16495
16496 ;; Don't do conditional moves with memory inputs. This splitter helps
16497 ;; register starved x86_32 by forcing inputs into registers before reload.
16498 (define_split
16499 [(set (match_operand:SWI248 0 "register_operand")
16500 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16501 [(reg FLAGS_REG) (const_int 0)])
16502 (match_operand:SWI248 2 "nonimmediate_operand")
16503 (match_operand:SWI248 3 "nonimmediate_operand")))]
16504 "!TARGET_64BIT && TARGET_CMOVE
16505 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16506 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16507 && can_create_pseudo_p ()
16508 && optimize_insn_for_speed_p ()"
16509 [(set (match_dup 0)
16510 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16511 {
16512 if (MEM_P (operands[2]))
16513 operands[2] = force_reg (<MODE>mode, operands[2]);
16514 if (MEM_P (operands[3]))
16515 operands[3] = force_reg (<MODE>mode, operands[3]);
16516 })
16517
16518 (define_insn "*movqicc_noc"
16519 [(set (match_operand:QI 0 "register_operand" "=r,r")
16520 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16521 [(reg FLAGS_REG) (const_int 0)])
16522 (match_operand:QI 2 "register_operand" "r,0")
16523 (match_operand:QI 3 "register_operand" "0,r")))]
16524 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16525 "#"
16526 [(set_attr "type" "icmov")
16527 (set_attr "mode" "QI")])
16528
16529 (define_split
16530 [(set (match_operand:SWI12 0 "register_operand")
16531 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16532 [(reg FLAGS_REG) (const_int 0)])
16533 (match_operand:SWI12 2 "register_operand")
16534 (match_operand:SWI12 3 "register_operand")))]
16535 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16536 && reload_completed"
16537 [(set (match_dup 0)
16538 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16539 {
16540 operands[0] = gen_lowpart (SImode, operands[0]);
16541 operands[2] = gen_lowpart (SImode, operands[2]);
16542 operands[3] = gen_lowpart (SImode, operands[3]);
16543 })
16544
16545 ;; Don't do conditional moves with memory inputs
16546 (define_peephole2
16547 [(match_scratch:SWI248 2 "r")
16548 (set (match_operand:SWI248 0 "register_operand")
16549 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16550 [(reg FLAGS_REG) (const_int 0)])
16551 (match_dup 0)
16552 (match_operand:SWI248 3 "memory_operand")))]
16553 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16554 && optimize_insn_for_speed_p ()"
16555 [(set (match_dup 2) (match_dup 3))
16556 (set (match_dup 0)
16557 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16558
16559 (define_peephole2
16560 [(match_scratch:SWI248 2 "r")
16561 (set (match_operand:SWI248 0 "register_operand")
16562 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16563 [(reg FLAGS_REG) (const_int 0)])
16564 (match_operand:SWI248 3 "memory_operand")
16565 (match_dup 0)))]
16566 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16567 && optimize_insn_for_speed_p ()"
16568 [(set (match_dup 2) (match_dup 3))
16569 (set (match_dup 0)
16570 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16571
16572 (define_expand "mov<mode>cc"
16573 [(set (match_operand:X87MODEF 0 "register_operand")
16574 (if_then_else:X87MODEF
16575 (match_operand 1 "comparison_operator")
16576 (match_operand:X87MODEF 2 "register_operand")
16577 (match_operand:X87MODEF 3 "register_operand")))]
16578 "(TARGET_80387 && TARGET_CMOVE)
16579 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16580 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16581
16582 (define_insn "*movxfcc_1"
16583 [(set (match_operand:XF 0 "register_operand" "=f,f")
16584 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16585 [(reg FLAGS_REG) (const_int 0)])
16586 (match_operand:XF 2 "register_operand" "f,0")
16587 (match_operand:XF 3 "register_operand" "0,f")))]
16588 "TARGET_80387 && TARGET_CMOVE"
16589 "@
16590 fcmov%F1\t{%2, %0|%0, %2}
16591 fcmov%f1\t{%3, %0|%0, %3}"
16592 [(set_attr "type" "fcmov")
16593 (set_attr "mode" "XF")])
16594
16595 (define_insn "*movdfcc_1"
16596 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16597 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16598 [(reg FLAGS_REG) (const_int 0)])
16599 (match_operand:DF 2 "nonimmediate_operand"
16600 "f ,0,rm,0 ,rm,0")
16601 (match_operand:DF 3 "nonimmediate_operand"
16602 "0 ,f,0 ,rm,0, rm")))]
16603 "TARGET_80387 && TARGET_CMOVE
16604 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16605 "@
16606 fcmov%F1\t{%2, %0|%0, %2}
16607 fcmov%f1\t{%3, %0|%0, %3}
16608 #
16609 #
16610 cmov%O2%C1\t{%2, %0|%0, %2}
16611 cmov%O2%c1\t{%3, %0|%0, %3}"
16612 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16613 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16614 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16615
16616 (define_split
16617 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16618 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16619 [(reg FLAGS_REG) (const_int 0)])
16620 (match_operand:DF 2 "nonimmediate_operand")
16621 (match_operand:DF 3 "nonimmediate_operand")))]
16622 "!TARGET_64BIT && reload_completed"
16623 [(set (match_dup 2)
16624 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16625 (set (match_dup 3)
16626 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16627 {
16628 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16629 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16630 })
16631
16632 (define_insn "*movsfcc_1_387"
16633 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16634 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16635 [(reg FLAGS_REG) (const_int 0)])
16636 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16637 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16638 "TARGET_80387 && TARGET_CMOVE
16639 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16640 "@
16641 fcmov%F1\t{%2, %0|%0, %2}
16642 fcmov%f1\t{%3, %0|%0, %3}
16643 cmov%O2%C1\t{%2, %0|%0, %2}
16644 cmov%O2%c1\t{%3, %0|%0, %3}"
16645 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16646 (set_attr "mode" "SF,SF,SI,SI")])
16647
16648 ;; Don't do conditional moves with memory inputs. This splitter helps
16649 ;; register starved x86_32 by forcing inputs into registers before reload.
16650 (define_split
16651 [(set (match_operand:MODEF 0 "register_operand")
16652 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16653 [(reg FLAGS_REG) (const_int 0)])
16654 (match_operand:MODEF 2 "nonimmediate_operand")
16655 (match_operand:MODEF 3 "nonimmediate_operand")))]
16656 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16657 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16658 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16659 && can_create_pseudo_p ()
16660 && optimize_insn_for_speed_p ()"
16661 [(set (match_dup 0)
16662 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16663 {
16664 if (MEM_P (operands[2]))
16665 operands[2] = force_reg (<MODE>mode, operands[2]);
16666 if (MEM_P (operands[3]))
16667 operands[3] = force_reg (<MODE>mode, operands[3]);
16668 })
16669
16670 ;; Don't do conditional moves with memory inputs
16671 (define_peephole2
16672 [(match_scratch:MODEF 2 "r")
16673 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16674 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16675 [(reg FLAGS_REG) (const_int 0)])
16676 (match_dup 0)
16677 (match_operand:MODEF 3 "memory_operand")))]
16678 "(<MODE>mode != DFmode || TARGET_64BIT)
16679 && TARGET_80387 && TARGET_CMOVE
16680 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16681 && optimize_insn_for_speed_p ()"
16682 [(set (match_dup 2) (match_dup 3))
16683 (set (match_dup 0)
16684 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16685
16686 (define_peephole2
16687 [(match_scratch:MODEF 2 "r")
16688 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16689 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16690 [(reg FLAGS_REG) (const_int 0)])
16691 (match_operand:MODEF 3 "memory_operand")
16692 (match_dup 0)))]
16693 "(<MODE>mode != DFmode || TARGET_64BIT)
16694 && TARGET_80387 && TARGET_CMOVE
16695 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16696 && optimize_insn_for_speed_p ()"
16697 [(set (match_dup 2) (match_dup 3))
16698 (set (match_dup 0)
16699 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16700
16701 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16702 ;; the scalar versions to have only XMM registers as operands.
16703
16704 ;; XOP conditional move
16705 (define_insn "*xop_pcmov_<mode>"
16706 [(set (match_operand:MODEF 0 "register_operand" "=x")
16707 (if_then_else:MODEF
16708 (match_operand:MODEF 1 "register_operand" "x")
16709 (match_operand:MODEF 2 "register_operand" "x")
16710 (match_operand:MODEF 3 "register_operand" "x")))]
16711 "TARGET_XOP"
16712 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16713 [(set_attr "type" "sse4arg")])
16714
16715 ;; These versions of the min/max patterns are intentionally ignorant of
16716 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16717 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16718 ;; are undefined in this condition, we're certain this is correct.
16719
16720 (define_insn "<code><mode>3"
16721 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16722 (smaxmin:MODEF
16723 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16724 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16725 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16726 "@
16727 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16728 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16729 [(set_attr "isa" "noavx,avx")
16730 (set_attr "prefix" "orig,vex")
16731 (set_attr "type" "sseadd")
16732 (set_attr "mode" "<MODE>")])
16733
16734 ;; These versions of the min/max patterns implement exactly the operations
16735 ;; min = (op1 < op2 ? op1 : op2)
16736 ;; max = (!(op1 < op2) ? op1 : op2)
16737 ;; Their operands are not commutative, and thus they may be used in the
16738 ;; presence of -0.0 and NaN.
16739
16740 (define_int_iterator IEEE_MAXMIN
16741 [UNSPEC_IEEE_MAX
16742 UNSPEC_IEEE_MIN])
16743
16744 (define_int_attr ieee_maxmin
16745 [(UNSPEC_IEEE_MAX "max")
16746 (UNSPEC_IEEE_MIN "min")])
16747
16748 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16749 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16750 (unspec:MODEF
16751 [(match_operand:MODEF 1 "register_operand" "0,x")
16752 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16753 IEEE_MAXMIN))]
16754 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16755 "@
16756 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16757 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16758 [(set_attr "isa" "noavx,avx")
16759 (set_attr "prefix" "orig,vex")
16760 (set_attr "type" "sseadd")
16761 (set_attr "mode" "<MODE>")])
16762
16763 ;; Make two stack loads independent:
16764 ;; fld aa fld aa
16765 ;; fld %st(0) -> fld bb
16766 ;; fmul bb fmul %st(1), %st
16767 ;;
16768 ;; Actually we only match the last two instructions for simplicity.
16769 (define_peephole2
16770 [(set (match_operand 0 "fp_register_operand")
16771 (match_operand 1 "fp_register_operand"))
16772 (set (match_dup 0)
16773 (match_operator 2 "binary_fp_operator"
16774 [(match_dup 0)
16775 (match_operand 3 "memory_operand")]))]
16776 "REGNO (operands[0]) != REGNO (operands[1])"
16777 [(set (match_dup 0) (match_dup 3))
16778 (set (match_dup 0) (match_dup 4))]
16779
16780 ;; The % modifier is not operational anymore in peephole2's, so we have to
16781 ;; swap the operands manually in the case of addition and multiplication.
16782 {
16783 rtx op0, op1;
16784
16785 if (COMMUTATIVE_ARITH_P (operands[2]))
16786 op0 = operands[0], op1 = operands[1];
16787 else
16788 op0 = operands[1], op1 = operands[0];
16789
16790 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16791 GET_MODE (operands[2]),
16792 op0, op1);
16793 })
16794
16795 ;; Conditional addition patterns
16796 (define_expand "add<mode>cc"
16797 [(match_operand:SWI 0 "register_operand")
16798 (match_operand 1 "ordered_comparison_operator")
16799 (match_operand:SWI 2 "register_operand")
16800 (match_operand:SWI 3 "const_int_operand")]
16801 ""
16802 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16803 \f
16804 ;; Misc patterns (?)
16805
16806 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16807 ;; Otherwise there will be nothing to keep
16808 ;;
16809 ;; [(set (reg ebp) (reg esp))]
16810 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16811 ;; (clobber (eflags)]
16812 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16813 ;;
16814 ;; in proper program order.
16815
16816 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16817 [(set (match_operand:P 0 "register_operand" "=r,r")
16818 (plus:P (match_operand:P 1 "register_operand" "0,r")
16819 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16820 (clobber (reg:CC FLAGS_REG))
16821 (clobber (mem:BLK (scratch)))]
16822 ""
16823 {
16824 switch (get_attr_type (insn))
16825 {
16826 case TYPE_IMOV:
16827 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16828
16829 case TYPE_ALU:
16830 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16831 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16832 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16833
16834 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16835
16836 default:
16837 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16838 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16839 }
16840 }
16841 [(set (attr "type")
16842 (cond [(and (eq_attr "alternative" "0")
16843 (not (match_test "TARGET_OPT_AGU")))
16844 (const_string "alu")
16845 (match_operand:<MODE> 2 "const0_operand")
16846 (const_string "imov")
16847 ]
16848 (const_string "lea")))
16849 (set (attr "length_immediate")
16850 (cond [(eq_attr "type" "imov")
16851 (const_string "0")
16852 (and (eq_attr "type" "alu")
16853 (match_operand 2 "const128_operand"))
16854 (const_string "1")
16855 ]
16856 (const_string "*")))
16857 (set_attr "mode" "<MODE>")])
16858
16859 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16860 [(set (match_operand:P 0 "register_operand" "=r")
16861 (minus:P (match_operand:P 1 "register_operand" "0")
16862 (match_operand:P 2 "register_operand" "r")))
16863 (clobber (reg:CC FLAGS_REG))
16864 (clobber (mem:BLK (scratch)))]
16865 ""
16866 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16867 [(set_attr "type" "alu")
16868 (set_attr "mode" "<MODE>")])
16869
16870 (define_insn "allocate_stack_worker_probe_<mode>"
16871 [(set (match_operand:P 0 "register_operand" "=a")
16872 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16873 UNSPECV_STACK_PROBE))
16874 (clobber (reg:CC FLAGS_REG))]
16875 "ix86_target_stack_probe ()"
16876 "call\t___chkstk_ms"
16877 [(set_attr "type" "multi")
16878 (set_attr "length" "5")])
16879
16880 (define_expand "allocate_stack"
16881 [(match_operand 0 "register_operand")
16882 (match_operand 1 "general_operand")]
16883 "ix86_target_stack_probe ()"
16884 {
16885 rtx x;
16886
16887 #ifndef CHECK_STACK_LIMIT
16888 #define CHECK_STACK_LIMIT 0
16889 #endif
16890
16891 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16892 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16893 x = operands[1];
16894 else
16895 {
16896 rtx (*insn) (rtx, rtx);
16897
16898 x = copy_to_mode_reg (Pmode, operands[1]);
16899
16900 insn = (TARGET_64BIT
16901 ? gen_allocate_stack_worker_probe_di
16902 : gen_allocate_stack_worker_probe_si);
16903
16904 emit_insn (insn (x, x));
16905 }
16906
16907 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16908 stack_pointer_rtx, 0, OPTAB_DIRECT);
16909
16910 if (x != stack_pointer_rtx)
16911 emit_move_insn (stack_pointer_rtx, x);
16912
16913 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16914 DONE;
16915 })
16916
16917 ;; Use IOR for stack probes, this is shorter.
16918 (define_expand "probe_stack"
16919 [(match_operand 0 "memory_operand")]
16920 ""
16921 {
16922 rtx (*gen_ior3) (rtx, rtx, rtx);
16923
16924 gen_ior3 = (GET_MODE (operands[0]) == DImode
16925 ? gen_iordi3 : gen_iorsi3);
16926
16927 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16928 DONE;
16929 })
16930
16931 (define_insn "adjust_stack_and_probe<mode>"
16932 [(set (match_operand:P 0 "register_operand" "=r")
16933 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16934 UNSPECV_PROBE_STACK_RANGE))
16935 (set (reg:P SP_REG)
16936 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16937 (clobber (reg:CC FLAGS_REG))
16938 (clobber (mem:BLK (scratch)))]
16939 ""
16940 "* return output_adjust_stack_and_probe (operands[0]);"
16941 [(set_attr "type" "multi")])
16942
16943 (define_insn "probe_stack_range<mode>"
16944 [(set (match_operand:P 0 "register_operand" "=r")
16945 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16946 (match_operand:P 2 "const_int_operand" "n")]
16947 UNSPECV_PROBE_STACK_RANGE))
16948 (clobber (reg:CC FLAGS_REG))]
16949 ""
16950 "* return output_probe_stack_range (operands[0], operands[2]);"
16951 [(set_attr "type" "multi")])
16952
16953 (define_expand "builtin_setjmp_receiver"
16954 [(label_ref (match_operand 0))]
16955 "!TARGET_64BIT && flag_pic"
16956 {
16957 #if TARGET_MACHO
16958 if (TARGET_MACHO)
16959 {
16960 rtx xops[3];
16961 rtx_code_label *label_rtx = gen_label_rtx ();
16962 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16963 xops[0] = xops[1] = pic_offset_table_rtx;
16964 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16965 ix86_expand_binary_operator (MINUS, SImode, xops);
16966 }
16967 else
16968 #endif
16969 emit_insn (gen_set_got (pic_offset_table_rtx));
16970 DONE;
16971 })
16972
16973 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16974 ;; Do not split instructions with mask registers.
16975 (define_split
16976 [(set (match_operand 0 "general_reg_operand")
16977 (match_operator 3 "promotable_binary_operator"
16978 [(match_operand 1 "general_reg_operand")
16979 (match_operand 2 "aligned_operand")]))
16980 (clobber (reg:CC FLAGS_REG))]
16981 "! TARGET_PARTIAL_REG_STALL && reload_completed
16982 && ((GET_MODE (operands[0]) == HImode
16983 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16984 /* ??? next two lines just !satisfies_constraint_K (...) */
16985 || !CONST_INT_P (operands[2])
16986 || satisfies_constraint_K (operands[2])))
16987 || (GET_MODE (operands[0]) == QImode
16988 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16989 [(parallel [(set (match_dup 0)
16990 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16991 (clobber (reg:CC FLAGS_REG))])]
16992 {
16993 operands[0] = gen_lowpart (SImode, operands[0]);
16994 operands[1] = gen_lowpart (SImode, operands[1]);
16995 if (GET_CODE (operands[3]) != ASHIFT)
16996 operands[2] = gen_lowpart (SImode, operands[2]);
16997 PUT_MODE (operands[3], SImode);
16998 })
16999
17000 ; Promote the QImode tests, as i386 has encoding of the AND
17001 ; instruction with 32-bit sign-extended immediate and thus the
17002 ; instruction size is unchanged, except in the %eax case for
17003 ; which it is increased by one byte, hence the ! optimize_size.
17004 (define_split
17005 [(set (match_operand 0 "flags_reg_operand")
17006 (match_operator 2 "compare_operator"
17007 [(and (match_operand 3 "aligned_operand")
17008 (match_operand 4 "const_int_operand"))
17009 (const_int 0)]))
17010 (set (match_operand 1 "register_operand")
17011 (and (match_dup 3) (match_dup 4)))]
17012 "! TARGET_PARTIAL_REG_STALL && reload_completed
17013 && optimize_insn_for_speed_p ()
17014 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17015 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17016 /* Ensure that the operand will remain sign-extended immediate. */
17017 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17018 [(parallel [(set (match_dup 0)
17019 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17020 (const_int 0)]))
17021 (set (match_dup 1)
17022 (and:SI (match_dup 3) (match_dup 4)))])]
17023 {
17024 operands[4]
17025 = gen_int_mode (INTVAL (operands[4])
17026 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17027 operands[1] = gen_lowpart (SImode, operands[1]);
17028 operands[3] = gen_lowpart (SImode, operands[3]);
17029 })
17030
17031 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17032 ; the TEST instruction with 32-bit sign-extended immediate and thus
17033 ; the instruction size would at least double, which is not what we
17034 ; want even with ! optimize_size.
17035 (define_split
17036 [(set (match_operand 0 "flags_reg_operand")
17037 (match_operator 1 "compare_operator"
17038 [(and (match_operand:HI 2 "aligned_operand")
17039 (match_operand:HI 3 "const_int_operand"))
17040 (const_int 0)]))]
17041 "! TARGET_PARTIAL_REG_STALL && reload_completed
17042 && ! TARGET_FAST_PREFIX
17043 && optimize_insn_for_speed_p ()
17044 /* Ensure that the operand will remain sign-extended immediate. */
17045 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17046 [(set (match_dup 0)
17047 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17048 (const_int 0)]))]
17049 {
17050 operands[3]
17051 = gen_int_mode (INTVAL (operands[3])
17052 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17053 operands[2] = gen_lowpart (SImode, operands[2]);
17054 })
17055
17056 (define_split
17057 [(set (match_operand 0 "register_operand")
17058 (neg (match_operand 1 "register_operand")))
17059 (clobber (reg:CC FLAGS_REG))]
17060 "! TARGET_PARTIAL_REG_STALL && reload_completed
17061 && (GET_MODE (operands[0]) == HImode
17062 || (GET_MODE (operands[0]) == QImode
17063 && (TARGET_PROMOTE_QImode
17064 || optimize_insn_for_size_p ())))"
17065 [(parallel [(set (match_dup 0)
17066 (neg:SI (match_dup 1)))
17067 (clobber (reg:CC FLAGS_REG))])]
17068 {
17069 operands[0] = gen_lowpart (SImode, operands[0]);
17070 operands[1] = gen_lowpart (SImode, operands[1]);
17071 })
17072
17073 ;; Do not split instructions with mask regs.
17074 (define_split
17075 [(set (match_operand 0 "general_reg_operand")
17076 (not (match_operand 1 "general_reg_operand")))]
17077 "! TARGET_PARTIAL_REG_STALL && reload_completed
17078 && (GET_MODE (operands[0]) == HImode
17079 || (GET_MODE (operands[0]) == QImode
17080 && (TARGET_PROMOTE_QImode
17081 || optimize_insn_for_size_p ())))"
17082 [(set (match_dup 0)
17083 (not:SI (match_dup 1)))]
17084 {
17085 operands[0] = gen_lowpart (SImode, operands[0]);
17086 operands[1] = gen_lowpart (SImode, operands[1]);
17087 })
17088 \f
17089 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17090 ;; transform a complex memory operation into two memory to register operations.
17091
17092 ;; Don't push memory operands
17093 (define_peephole2
17094 [(set (match_operand:SWI 0 "push_operand")
17095 (match_operand:SWI 1 "memory_operand"))
17096 (match_scratch:SWI 2 "<r>")]
17097 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17098 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17099 [(set (match_dup 2) (match_dup 1))
17100 (set (match_dup 0) (match_dup 2))])
17101
17102 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17103 ;; SImode pushes.
17104 (define_peephole2
17105 [(set (match_operand:SF 0 "push_operand")
17106 (match_operand:SF 1 "memory_operand"))
17107 (match_scratch:SF 2 "r")]
17108 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17109 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17110 [(set (match_dup 2) (match_dup 1))
17111 (set (match_dup 0) (match_dup 2))])
17112
17113 ;; Don't move an immediate directly to memory when the instruction
17114 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17115 (define_peephole2
17116 [(match_scratch:SWI124 1 "<r>")
17117 (set (match_operand:SWI124 0 "memory_operand")
17118 (const_int 0))]
17119 "optimize_insn_for_speed_p ()
17120 && ((<MODE>mode == HImode
17121 && TARGET_LCP_STALL)
17122 || (!TARGET_USE_MOV0
17123 && TARGET_SPLIT_LONG_MOVES
17124 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17125 && peep2_regno_dead_p (0, FLAGS_REG)"
17126 [(parallel [(set (match_dup 2) (const_int 0))
17127 (clobber (reg:CC FLAGS_REG))])
17128 (set (match_dup 0) (match_dup 1))]
17129 "operands[2] = gen_lowpart (SImode, operands[1]);")
17130
17131 (define_peephole2
17132 [(match_scratch:SWI124 2 "<r>")
17133 (set (match_operand:SWI124 0 "memory_operand")
17134 (match_operand:SWI124 1 "immediate_operand"))]
17135 "optimize_insn_for_speed_p ()
17136 && ((<MODE>mode == HImode
17137 && TARGET_LCP_STALL)
17138 || (TARGET_SPLIT_LONG_MOVES
17139 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17140 [(set (match_dup 2) (match_dup 1))
17141 (set (match_dup 0) (match_dup 2))])
17142
17143 ;; Don't compare memory with zero, load and use a test instead.
17144 (define_peephole2
17145 [(set (match_operand 0 "flags_reg_operand")
17146 (match_operator 1 "compare_operator"
17147 [(match_operand:SI 2 "memory_operand")
17148 (const_int 0)]))
17149 (match_scratch:SI 3 "r")]
17150 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17151 [(set (match_dup 3) (match_dup 2))
17152 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17153
17154 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17155 ;; Don't split NOTs with a displacement operand, because resulting XOR
17156 ;; will not be pairable anyway.
17157 ;;
17158 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17159 ;; represented using a modRM byte. The XOR replacement is long decoded,
17160 ;; so this split helps here as well.
17161 ;;
17162 ;; Note: Can't do this as a regular split because we can't get proper
17163 ;; lifetime information then.
17164
17165 (define_peephole2
17166 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17167 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17168 "optimize_insn_for_speed_p ()
17169 && ((TARGET_NOT_UNPAIRABLE
17170 && (!MEM_P (operands[0])
17171 || !memory_displacement_operand (operands[0], <MODE>mode)))
17172 || (TARGET_NOT_VECTORMODE
17173 && long_memory_operand (operands[0], <MODE>mode)))
17174 && peep2_regno_dead_p (0, FLAGS_REG)"
17175 [(parallel [(set (match_dup 0)
17176 (xor:SWI124 (match_dup 1) (const_int -1)))
17177 (clobber (reg:CC FLAGS_REG))])])
17178
17179 ;; Non pairable "test imm, reg" instructions can be translated to
17180 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17181 ;; byte opcode instead of two, have a short form for byte operands),
17182 ;; so do it for other CPUs as well. Given that the value was dead,
17183 ;; this should not create any new dependencies. Pass on the sub-word
17184 ;; versions if we're concerned about partial register stalls.
17185
17186 (define_peephole2
17187 [(set (match_operand 0 "flags_reg_operand")
17188 (match_operator 1 "compare_operator"
17189 [(and:SI (match_operand:SI 2 "register_operand")
17190 (match_operand:SI 3 "immediate_operand"))
17191 (const_int 0)]))]
17192 "ix86_match_ccmode (insn, CCNOmode)
17193 && (true_regnum (operands[2]) != AX_REG
17194 || satisfies_constraint_K (operands[3]))
17195 && peep2_reg_dead_p (1, operands[2])"
17196 [(parallel
17197 [(set (match_dup 0)
17198 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17199 (const_int 0)]))
17200 (set (match_dup 2)
17201 (and:SI (match_dup 2) (match_dup 3)))])])
17202
17203 ;; We don't need to handle HImode case, because it will be promoted to SImode
17204 ;; on ! TARGET_PARTIAL_REG_STALL
17205
17206 (define_peephole2
17207 [(set (match_operand 0 "flags_reg_operand")
17208 (match_operator 1 "compare_operator"
17209 [(and:QI (match_operand:QI 2 "register_operand")
17210 (match_operand:QI 3 "immediate_operand"))
17211 (const_int 0)]))]
17212 "! TARGET_PARTIAL_REG_STALL
17213 && ix86_match_ccmode (insn, CCNOmode)
17214 && true_regnum (operands[2]) != AX_REG
17215 && peep2_reg_dead_p (1, operands[2])"
17216 [(parallel
17217 [(set (match_dup 0)
17218 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17219 (const_int 0)]))
17220 (set (match_dup 2)
17221 (and:QI (match_dup 2) (match_dup 3)))])])
17222
17223 (define_peephole2
17224 [(set (match_operand 0 "flags_reg_operand")
17225 (match_operator 1 "compare_operator"
17226 [(and:SI
17227 (zero_extract:SI
17228 (match_operand 2 "ext_register_operand")
17229 (const_int 8)
17230 (const_int 8))
17231 (match_operand 3 "const_int_operand"))
17232 (const_int 0)]))]
17233 "! TARGET_PARTIAL_REG_STALL
17234 && ix86_match_ccmode (insn, CCNOmode)
17235 && true_regnum (operands[2]) != AX_REG
17236 && peep2_reg_dead_p (1, operands[2])"
17237 [(parallel [(set (match_dup 0)
17238 (match_op_dup 1
17239 [(and:SI
17240 (zero_extract:SI
17241 (match_dup 2)
17242 (const_int 8)
17243 (const_int 8))
17244 (match_dup 3))
17245 (const_int 0)]))
17246 (set (zero_extract:SI (match_dup 2)
17247 (const_int 8)
17248 (const_int 8))
17249 (and:SI
17250 (zero_extract:SI
17251 (match_dup 2)
17252 (const_int 8)
17253 (const_int 8))
17254 (match_dup 3)))])])
17255
17256 ;; Don't do logical operations with memory inputs.
17257 (define_peephole2
17258 [(match_scratch:SI 2 "r")
17259 (parallel [(set (match_operand:SI 0 "register_operand")
17260 (match_operator:SI 3 "arith_or_logical_operator"
17261 [(match_dup 0)
17262 (match_operand:SI 1 "memory_operand")]))
17263 (clobber (reg:CC FLAGS_REG))])]
17264 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17265 [(set (match_dup 2) (match_dup 1))
17266 (parallel [(set (match_dup 0)
17267 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17268 (clobber (reg:CC FLAGS_REG))])])
17269
17270 (define_peephole2
17271 [(match_scratch:SI 2 "r")
17272 (parallel [(set (match_operand:SI 0 "register_operand")
17273 (match_operator:SI 3 "arith_or_logical_operator"
17274 [(match_operand:SI 1 "memory_operand")
17275 (match_dup 0)]))
17276 (clobber (reg:CC FLAGS_REG))])]
17277 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17278 [(set (match_dup 2) (match_dup 1))
17279 (parallel [(set (match_dup 0)
17280 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17281 (clobber (reg:CC FLAGS_REG))])])
17282
17283 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17284 ;; refers to the destination of the load!
17285
17286 (define_peephole2
17287 [(set (match_operand:SI 0 "register_operand")
17288 (match_operand:SI 1 "register_operand"))
17289 (parallel [(set (match_dup 0)
17290 (match_operator:SI 3 "commutative_operator"
17291 [(match_dup 0)
17292 (match_operand:SI 2 "memory_operand")]))
17293 (clobber (reg:CC FLAGS_REG))])]
17294 "REGNO (operands[0]) != REGNO (operands[1])
17295 && GENERAL_REGNO_P (REGNO (operands[0]))
17296 && GENERAL_REGNO_P (REGNO (operands[1]))"
17297 [(set (match_dup 0) (match_dup 4))
17298 (parallel [(set (match_dup 0)
17299 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17300 (clobber (reg:CC FLAGS_REG))])]
17301 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17302
17303 (define_peephole2
17304 [(set (match_operand 0 "register_operand")
17305 (match_operand 1 "register_operand"))
17306 (set (match_dup 0)
17307 (match_operator 3 "commutative_operator"
17308 [(match_dup 0)
17309 (match_operand 2 "memory_operand")]))]
17310 "REGNO (operands[0]) != REGNO (operands[1])
17311 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17312 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17313 [(set (match_dup 0) (match_dup 2))
17314 (set (match_dup 0)
17315 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17316
17317 ; Don't do logical operations with memory outputs
17318 ;
17319 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17320 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17321 ; the same decoder scheduling characteristics as the original.
17322
17323 (define_peephole2
17324 [(match_scratch:SI 2 "r")
17325 (parallel [(set (match_operand:SI 0 "memory_operand")
17326 (match_operator:SI 3 "arith_or_logical_operator"
17327 [(match_dup 0)
17328 (match_operand:SI 1 "nonmemory_operand")]))
17329 (clobber (reg:CC FLAGS_REG))])]
17330 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17331 /* Do not split stack checking probes. */
17332 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17333 [(set (match_dup 2) (match_dup 0))
17334 (parallel [(set (match_dup 2)
17335 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17336 (clobber (reg:CC FLAGS_REG))])
17337 (set (match_dup 0) (match_dup 2))])
17338
17339 (define_peephole2
17340 [(match_scratch:SI 2 "r")
17341 (parallel [(set (match_operand:SI 0 "memory_operand")
17342 (match_operator:SI 3 "arith_or_logical_operator"
17343 [(match_operand:SI 1 "nonmemory_operand")
17344 (match_dup 0)]))
17345 (clobber (reg:CC FLAGS_REG))])]
17346 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17347 /* Do not split stack checking probes. */
17348 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17349 [(set (match_dup 2) (match_dup 0))
17350 (parallel [(set (match_dup 2)
17351 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17352 (clobber (reg:CC FLAGS_REG))])
17353 (set (match_dup 0) (match_dup 2))])
17354
17355 ;; Attempt to use arith or logical operations with memory outputs with
17356 ;; setting of flags.
17357 (define_peephole2
17358 [(set (match_operand:SWI 0 "register_operand")
17359 (match_operand:SWI 1 "memory_operand"))
17360 (parallel [(set (match_dup 0)
17361 (match_operator:SWI 3 "plusminuslogic_operator"
17362 [(match_dup 0)
17363 (match_operand:SWI 2 "<nonmemory_operand>")]))
17364 (clobber (reg:CC FLAGS_REG))])
17365 (set (match_dup 1) (match_dup 0))
17366 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17367 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17368 && peep2_reg_dead_p (4, operands[0])
17369 && !reg_overlap_mentioned_p (operands[0], operands[1])
17370 && !reg_overlap_mentioned_p (operands[0], operands[2])
17371 && (<MODE>mode != QImode
17372 || immediate_operand (operands[2], QImode)
17373 || q_regs_operand (operands[2], QImode))
17374 && ix86_match_ccmode (peep2_next_insn (3),
17375 (GET_CODE (operands[3]) == PLUS
17376 || GET_CODE (operands[3]) == MINUS)
17377 ? CCGOCmode : CCNOmode)"
17378 [(parallel [(set (match_dup 4) (match_dup 5))
17379 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17380 (match_dup 2)]))])]
17381 {
17382 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17383 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17384 copy_rtx (operands[1]),
17385 copy_rtx (operands[2]));
17386 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17387 operands[5], const0_rtx);
17388 })
17389
17390 (define_peephole2
17391 [(parallel [(set (match_operand:SWI 0 "register_operand")
17392 (match_operator:SWI 2 "plusminuslogic_operator"
17393 [(match_dup 0)
17394 (match_operand:SWI 1 "memory_operand")]))
17395 (clobber (reg:CC FLAGS_REG))])
17396 (set (match_dup 1) (match_dup 0))
17397 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17398 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17399 && GET_CODE (operands[2]) != MINUS
17400 && peep2_reg_dead_p (3, operands[0])
17401 && !reg_overlap_mentioned_p (operands[0], operands[1])
17402 && ix86_match_ccmode (peep2_next_insn (2),
17403 GET_CODE (operands[2]) == PLUS
17404 ? CCGOCmode : CCNOmode)"
17405 [(parallel [(set (match_dup 3) (match_dup 4))
17406 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17407 (match_dup 0)]))])]
17408 {
17409 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17410 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17411 copy_rtx (operands[1]),
17412 copy_rtx (operands[0]));
17413 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17414 operands[4], const0_rtx);
17415 })
17416
17417 (define_peephole2
17418 [(set (match_operand:SWI12 0 "register_operand")
17419 (match_operand:SWI12 1 "memory_operand"))
17420 (parallel [(set (match_operand:SI 4 "register_operand")
17421 (match_operator:SI 3 "plusminuslogic_operator"
17422 [(match_dup 4)
17423 (match_operand:SI 2 "nonmemory_operand")]))
17424 (clobber (reg:CC FLAGS_REG))])
17425 (set (match_dup 1) (match_dup 0))
17426 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17427 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17428 && REG_P (operands[0]) && REG_P (operands[4])
17429 && REGNO (operands[0]) == REGNO (operands[4])
17430 && peep2_reg_dead_p (4, operands[0])
17431 && (<MODE>mode != QImode
17432 || immediate_operand (operands[2], SImode)
17433 || q_regs_operand (operands[2], SImode))
17434 && !reg_overlap_mentioned_p (operands[0], operands[1])
17435 && !reg_overlap_mentioned_p (operands[0], operands[2])
17436 && ix86_match_ccmode (peep2_next_insn (3),
17437 (GET_CODE (operands[3]) == PLUS
17438 || GET_CODE (operands[3]) == MINUS)
17439 ? CCGOCmode : CCNOmode)"
17440 [(parallel [(set (match_dup 4) (match_dup 5))
17441 (set (match_dup 1) (match_dup 6))])]
17442 {
17443 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17444 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17445 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17446 copy_rtx (operands[1]), operands[2]);
17447 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17448 operands[5], const0_rtx);
17449 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17450 copy_rtx (operands[1]),
17451 copy_rtx (operands[2]));
17452 })
17453
17454 ;; Attempt to always use XOR for zeroing registers.
17455 (define_peephole2
17456 [(set (match_operand 0 "register_operand")
17457 (match_operand 1 "const0_operand"))]
17458 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17459 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17460 && GENERAL_REG_P (operands[0])
17461 && peep2_regno_dead_p (0, FLAGS_REG)"
17462 [(parallel [(set (match_dup 0) (const_int 0))
17463 (clobber (reg:CC FLAGS_REG))])]
17464 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17465
17466 (define_peephole2
17467 [(set (strict_low_part (match_operand 0 "register_operand"))
17468 (const_int 0))]
17469 "(GET_MODE (operands[0]) == QImode
17470 || GET_MODE (operands[0]) == HImode)
17471 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17472 && peep2_regno_dead_p (0, FLAGS_REG)"
17473 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17474 (clobber (reg:CC FLAGS_REG))])])
17475
17476 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17477 (define_peephole2
17478 [(set (match_operand:SWI248 0 "register_operand")
17479 (const_int -1))]
17480 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17481 && peep2_regno_dead_p (0, FLAGS_REG)"
17482 [(parallel [(set (match_dup 0) (const_int -1))
17483 (clobber (reg:CC FLAGS_REG))])]
17484 {
17485 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17486 operands[0] = gen_lowpart (SImode, operands[0]);
17487 })
17488
17489 ;; Attempt to convert simple lea to add/shift.
17490 ;; These can be created by move expanders.
17491 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17492 ;; relevant lea instructions were already split.
17493
17494 (define_peephole2
17495 [(set (match_operand:SWI48 0 "register_operand")
17496 (plus:SWI48 (match_dup 0)
17497 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17498 "!TARGET_OPT_AGU
17499 && peep2_regno_dead_p (0, FLAGS_REG)"
17500 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17501 (clobber (reg:CC FLAGS_REG))])])
17502
17503 (define_peephole2
17504 [(set (match_operand:SWI48 0 "register_operand")
17505 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17506 (match_dup 0)))]
17507 "!TARGET_OPT_AGU
17508 && peep2_regno_dead_p (0, FLAGS_REG)"
17509 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17510 (clobber (reg:CC FLAGS_REG))])])
17511
17512 (define_peephole2
17513 [(set (match_operand:DI 0 "register_operand")
17514 (zero_extend:DI
17515 (plus:SI (match_operand:SI 1 "register_operand")
17516 (match_operand:SI 2 "nonmemory_operand"))))]
17517 "TARGET_64BIT && !TARGET_OPT_AGU
17518 && REGNO (operands[0]) == REGNO (operands[1])
17519 && peep2_regno_dead_p (0, FLAGS_REG)"
17520 [(parallel [(set (match_dup 0)
17521 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17522 (clobber (reg:CC FLAGS_REG))])])
17523
17524 (define_peephole2
17525 [(set (match_operand:DI 0 "register_operand")
17526 (zero_extend:DI
17527 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17528 (match_operand:SI 2 "register_operand"))))]
17529 "TARGET_64BIT && !TARGET_OPT_AGU
17530 && REGNO (operands[0]) == REGNO (operands[2])
17531 && peep2_regno_dead_p (0, FLAGS_REG)"
17532 [(parallel [(set (match_dup 0)
17533 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17534 (clobber (reg:CC FLAGS_REG))])])
17535
17536 (define_peephole2
17537 [(set (match_operand:SWI48 0 "register_operand")
17538 (mult:SWI48 (match_dup 0)
17539 (match_operand:SWI48 1 "const_int_operand")))]
17540 "exact_log2 (INTVAL (operands[1])) >= 0
17541 && peep2_regno_dead_p (0, FLAGS_REG)"
17542 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17543 (clobber (reg:CC FLAGS_REG))])]
17544 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17545
17546 (define_peephole2
17547 [(set (match_operand:DI 0 "register_operand")
17548 (zero_extend:DI
17549 (mult:SI (match_operand:SI 1 "register_operand")
17550 (match_operand:SI 2 "const_int_operand"))))]
17551 "TARGET_64BIT
17552 && exact_log2 (INTVAL (operands[2])) >= 0
17553 && REGNO (operands[0]) == REGNO (operands[1])
17554 && peep2_regno_dead_p (0, FLAGS_REG)"
17555 [(parallel [(set (match_dup 0)
17556 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17557 (clobber (reg:CC FLAGS_REG))])]
17558 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17559
17560 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17561 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17562 ;; On many CPUs it is also faster, since special hardware to avoid esp
17563 ;; dependencies is present.
17564
17565 ;; While some of these conversions may be done using splitters, we use
17566 ;; peepholes in order to allow combine_stack_adjustments pass to see
17567 ;; nonobfuscated RTL.
17568
17569 ;; Convert prologue esp subtractions to push.
17570 ;; We need register to push. In order to keep verify_flow_info happy we have
17571 ;; two choices
17572 ;; - use scratch and clobber it in order to avoid dependencies
17573 ;; - use already live register
17574 ;; We can't use the second way right now, since there is no reliable way how to
17575 ;; verify that given register is live. First choice will also most likely in
17576 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17577 ;; call clobbered registers are dead. We may want to use base pointer as an
17578 ;; alternative when no register is available later.
17579
17580 (define_peephole2
17581 [(match_scratch:W 1 "r")
17582 (parallel [(set (reg:P SP_REG)
17583 (plus:P (reg:P SP_REG)
17584 (match_operand:P 0 "const_int_operand")))
17585 (clobber (reg:CC FLAGS_REG))
17586 (clobber (mem:BLK (scratch)))])]
17587 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17588 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17589 [(clobber (match_dup 1))
17590 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17591 (clobber (mem:BLK (scratch)))])])
17592
17593 (define_peephole2
17594 [(match_scratch:W 1 "r")
17595 (parallel [(set (reg:P SP_REG)
17596 (plus:P (reg:P SP_REG)
17597 (match_operand:P 0 "const_int_operand")))
17598 (clobber (reg:CC FLAGS_REG))
17599 (clobber (mem:BLK (scratch)))])]
17600 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17601 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17602 [(clobber (match_dup 1))
17603 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17604 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17605 (clobber (mem:BLK (scratch)))])])
17606
17607 ;; Convert esp subtractions to push.
17608 (define_peephole2
17609 [(match_scratch:W 1 "r")
17610 (parallel [(set (reg:P SP_REG)
17611 (plus:P (reg:P SP_REG)
17612 (match_operand:P 0 "const_int_operand")))
17613 (clobber (reg:CC FLAGS_REG))])]
17614 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17615 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17616 [(clobber (match_dup 1))
17617 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17618
17619 (define_peephole2
17620 [(match_scratch:W 1 "r")
17621 (parallel [(set (reg:P SP_REG)
17622 (plus:P (reg:P SP_REG)
17623 (match_operand:P 0 "const_int_operand")))
17624 (clobber (reg:CC FLAGS_REG))])]
17625 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17626 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17627 [(clobber (match_dup 1))
17628 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17629 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17630
17631 ;; Convert epilogue deallocator to pop.
17632 (define_peephole2
17633 [(match_scratch:W 1 "r")
17634 (parallel [(set (reg:P SP_REG)
17635 (plus:P (reg:P SP_REG)
17636 (match_operand:P 0 "const_int_operand")))
17637 (clobber (reg:CC FLAGS_REG))
17638 (clobber (mem:BLK (scratch)))])]
17639 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17640 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17641 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17642 (clobber (mem:BLK (scratch)))])])
17643
17644 ;; Two pops case is tricky, since pop causes dependency
17645 ;; on destination register. We use two registers if available.
17646 (define_peephole2
17647 [(match_scratch:W 1 "r")
17648 (match_scratch:W 2 "r")
17649 (parallel [(set (reg:P SP_REG)
17650 (plus:P (reg:P SP_REG)
17651 (match_operand:P 0 "const_int_operand")))
17652 (clobber (reg:CC FLAGS_REG))
17653 (clobber (mem:BLK (scratch)))])]
17654 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17655 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17656 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17657 (clobber (mem:BLK (scratch)))])
17658 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17659
17660 (define_peephole2
17661 [(match_scratch:W 1 "r")
17662 (parallel [(set (reg:P SP_REG)
17663 (plus:P (reg:P SP_REG)
17664 (match_operand:P 0 "const_int_operand")))
17665 (clobber (reg:CC FLAGS_REG))
17666 (clobber (mem:BLK (scratch)))])]
17667 "optimize_insn_for_size_p ()
17668 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17669 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17670 (clobber (mem:BLK (scratch)))])
17671 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17672
17673 ;; Convert esp additions to pop.
17674 (define_peephole2
17675 [(match_scratch:W 1 "r")
17676 (parallel [(set (reg:P SP_REG)
17677 (plus:P (reg:P SP_REG)
17678 (match_operand:P 0 "const_int_operand")))
17679 (clobber (reg:CC FLAGS_REG))])]
17680 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17681 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17682
17683 ;; Two pops case is tricky, since pop causes dependency
17684 ;; on destination register. We use two registers if available.
17685 (define_peephole2
17686 [(match_scratch:W 1 "r")
17687 (match_scratch:W 2 "r")
17688 (parallel [(set (reg:P SP_REG)
17689 (plus:P (reg:P SP_REG)
17690 (match_operand:P 0 "const_int_operand")))
17691 (clobber (reg:CC FLAGS_REG))])]
17692 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17693 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17694 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17695
17696 (define_peephole2
17697 [(match_scratch:W 1 "r")
17698 (parallel [(set (reg:P SP_REG)
17699 (plus:P (reg:P SP_REG)
17700 (match_operand:P 0 "const_int_operand")))
17701 (clobber (reg:CC FLAGS_REG))])]
17702 "optimize_insn_for_size_p ()
17703 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17704 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17705 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17706 \f
17707 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17708 ;; required and register dies. Similarly for 128 to -128.
17709 (define_peephole2
17710 [(set (match_operand 0 "flags_reg_operand")
17711 (match_operator 1 "compare_operator"
17712 [(match_operand 2 "register_operand")
17713 (match_operand 3 "const_int_operand")]))]
17714 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17715 && incdec_operand (operands[3], GET_MODE (operands[3])))
17716 || (!TARGET_FUSE_CMP_AND_BRANCH
17717 && INTVAL (operands[3]) == 128))
17718 && ix86_match_ccmode (insn, CCGCmode)
17719 && peep2_reg_dead_p (1, operands[2])"
17720 [(parallel [(set (match_dup 0)
17721 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17722 (clobber (match_dup 2))])])
17723 \f
17724 ;; Convert imul by three, five and nine into lea
17725 (define_peephole2
17726 [(parallel
17727 [(set (match_operand:SWI48 0 "register_operand")
17728 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17729 (match_operand:SWI48 2 "const359_operand")))
17730 (clobber (reg:CC FLAGS_REG))])]
17731 "!TARGET_PARTIAL_REG_STALL
17732 || <MODE>mode == SImode
17733 || optimize_function_for_size_p (cfun)"
17734 [(set (match_dup 0)
17735 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17736 (match_dup 1)))]
17737 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17738
17739 (define_peephole2
17740 [(parallel
17741 [(set (match_operand:SWI48 0 "register_operand")
17742 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17743 (match_operand:SWI48 2 "const359_operand")))
17744 (clobber (reg:CC FLAGS_REG))])]
17745 "optimize_insn_for_speed_p ()
17746 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17747 [(set (match_dup 0) (match_dup 1))
17748 (set (match_dup 0)
17749 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17750 (match_dup 0)))]
17751 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17752
17753 ;; imul $32bit_imm, mem, reg is vector decoded, while
17754 ;; imul $32bit_imm, reg, reg is direct decoded.
17755 (define_peephole2
17756 [(match_scratch:SWI48 3 "r")
17757 (parallel [(set (match_operand:SWI48 0 "register_operand")
17758 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17759 (match_operand:SWI48 2 "immediate_operand")))
17760 (clobber (reg:CC FLAGS_REG))])]
17761 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17762 && !satisfies_constraint_K (operands[2])"
17763 [(set (match_dup 3) (match_dup 1))
17764 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17765 (clobber (reg:CC FLAGS_REG))])])
17766
17767 (define_peephole2
17768 [(match_scratch:SI 3 "r")
17769 (parallel [(set (match_operand:DI 0 "register_operand")
17770 (zero_extend:DI
17771 (mult:SI (match_operand:SI 1 "memory_operand")
17772 (match_operand:SI 2 "immediate_operand"))))
17773 (clobber (reg:CC FLAGS_REG))])]
17774 "TARGET_64BIT
17775 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17776 && !satisfies_constraint_K (operands[2])"
17777 [(set (match_dup 3) (match_dup 1))
17778 (parallel [(set (match_dup 0)
17779 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17780 (clobber (reg:CC FLAGS_REG))])])
17781
17782 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17783 ;; Convert it into imul reg, reg
17784 ;; It would be better to force assembler to encode instruction using long
17785 ;; immediate, but there is apparently no way to do so.
17786 (define_peephole2
17787 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17788 (mult:SWI248
17789 (match_operand:SWI248 1 "nonimmediate_operand")
17790 (match_operand:SWI248 2 "const_int_operand")))
17791 (clobber (reg:CC FLAGS_REG))])
17792 (match_scratch:SWI248 3 "r")]
17793 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17794 && satisfies_constraint_K (operands[2])"
17795 [(set (match_dup 3) (match_dup 2))
17796 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17797 (clobber (reg:CC FLAGS_REG))])]
17798 {
17799 if (!rtx_equal_p (operands[0], operands[1]))
17800 emit_move_insn (operands[0], operands[1]);
17801 })
17802
17803 ;; After splitting up read-modify operations, array accesses with memory
17804 ;; operands might end up in form:
17805 ;; sall $2, %eax
17806 ;; movl 4(%esp), %edx
17807 ;; addl %edx, %eax
17808 ;; instead of pre-splitting:
17809 ;; sall $2, %eax
17810 ;; addl 4(%esp), %eax
17811 ;; Turn it into:
17812 ;; movl 4(%esp), %edx
17813 ;; leal (%edx,%eax,4), %eax
17814
17815 (define_peephole2
17816 [(match_scratch:W 5 "r")
17817 (parallel [(set (match_operand 0 "register_operand")
17818 (ashift (match_operand 1 "register_operand")
17819 (match_operand 2 "const_int_operand")))
17820 (clobber (reg:CC FLAGS_REG))])
17821 (parallel [(set (match_operand 3 "register_operand")
17822 (plus (match_dup 0)
17823 (match_operand 4 "x86_64_general_operand")))
17824 (clobber (reg:CC FLAGS_REG))])]
17825 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17826 /* Validate MODE for lea. */
17827 && ((!TARGET_PARTIAL_REG_STALL
17828 && (GET_MODE (operands[0]) == QImode
17829 || GET_MODE (operands[0]) == HImode))
17830 || GET_MODE (operands[0]) == SImode
17831 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17832 && (rtx_equal_p (operands[0], operands[3])
17833 || peep2_reg_dead_p (2, operands[0]))
17834 /* We reorder load and the shift. */
17835 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17836 [(set (match_dup 5) (match_dup 4))
17837 (set (match_dup 0) (match_dup 1))]
17838 {
17839 machine_mode op1mode = GET_MODE (operands[1]);
17840 machine_mode mode = op1mode == DImode ? DImode : SImode;
17841 int scale = 1 << INTVAL (operands[2]);
17842 rtx index = gen_lowpart (word_mode, operands[1]);
17843 rtx base = gen_lowpart (word_mode, operands[5]);
17844 rtx dest = gen_lowpart (mode, operands[3]);
17845
17846 operands[1] = gen_rtx_PLUS (word_mode, base,
17847 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17848 operands[5] = base;
17849 if (mode != word_mode)
17850 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17851 if (op1mode != word_mode)
17852 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17853 operands[0] = dest;
17854 })
17855 \f
17856 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17857 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17858 ;; caught for use by garbage collectors and the like. Using an insn that
17859 ;; maps to SIGILL makes it more likely the program will rightfully die.
17860 ;; Keeping with tradition, "6" is in honor of #UD.
17861 (define_insn "trap"
17862 [(trap_if (const_int 1) (const_int 6))]
17863 ""
17864 {
17865 #ifdef HAVE_AS_IX86_UD2
17866 return "ud2";
17867 #else
17868 return ASM_SHORT "0x0b0f";
17869 #endif
17870 }
17871 [(set_attr "length" "2")])
17872
17873 (define_expand "prefetch"
17874 [(prefetch (match_operand 0 "address_operand")
17875 (match_operand:SI 1 "const_int_operand")
17876 (match_operand:SI 2 "const_int_operand"))]
17877 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17878 {
17879 bool write = INTVAL (operands[1]) != 0;
17880 int locality = INTVAL (operands[2]);
17881
17882 gcc_assert (IN_RANGE (locality, 0, 3));
17883
17884 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17885 supported by SSE counterpart or the SSE prefetch is not available
17886 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17887 of locality. */
17888 if (TARGET_PREFETCHWT1 && write && locality <= 2)
17889 operands[2] = const2_rtx;
17890 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17891 operands[2] = GEN_INT (3);
17892 else
17893 operands[1] = const0_rtx;
17894 })
17895
17896 (define_insn "*prefetch_sse"
17897 [(prefetch (match_operand 0 "address_operand" "p")
17898 (const_int 0)
17899 (match_operand:SI 1 "const_int_operand"))]
17900 "TARGET_PREFETCH_SSE"
17901 {
17902 static const char * const patterns[4] = {
17903 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17904 };
17905
17906 int locality = INTVAL (operands[1]);
17907 gcc_assert (IN_RANGE (locality, 0, 3));
17908
17909 return patterns[locality];
17910 }
17911 [(set_attr "type" "sse")
17912 (set_attr "atom_sse_attr" "prefetch")
17913 (set (attr "length_address")
17914 (symbol_ref "memory_address_length (operands[0], false)"))
17915 (set_attr "memory" "none")])
17916
17917 (define_insn "*prefetch_3dnow"
17918 [(prefetch (match_operand 0 "address_operand" "p")
17919 (match_operand:SI 1 "const_int_operand" "n")
17920 (const_int 3))]
17921 "TARGET_PRFCHW"
17922 {
17923 if (INTVAL (operands[1]) == 0)
17924 return "prefetch\t%a0";
17925 else
17926 return "prefetchw\t%a0";
17927 }
17928 [(set_attr "type" "mmx")
17929 (set (attr "length_address")
17930 (symbol_ref "memory_address_length (operands[0], false)"))
17931 (set_attr "memory" "none")])
17932
17933 (define_insn "*prefetch_prefetchwt1_<mode>"
17934 [(prefetch (match_operand:P 0 "address_operand" "p")
17935 (const_int 1)
17936 (const_int 2))]
17937 "TARGET_PREFETCHWT1"
17938 "prefetchwt1\t%a0";
17939 [(set_attr "type" "sse")
17940 (set (attr "length_address")
17941 (symbol_ref "memory_address_length (operands[0], false)"))
17942 (set_attr "memory" "none")])
17943
17944 (define_expand "stack_protect_set"
17945 [(match_operand 0 "memory_operand")
17946 (match_operand 1 "memory_operand")]
17947 "TARGET_SSP_TLS_GUARD"
17948 {
17949 rtx (*insn)(rtx, rtx);
17950
17951 #ifdef TARGET_THREAD_SSP_OFFSET
17952 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17953 insn = (TARGET_LP64
17954 ? gen_stack_tls_protect_set_di
17955 : gen_stack_tls_protect_set_si);
17956 #else
17957 insn = (TARGET_LP64
17958 ? gen_stack_protect_set_di
17959 : gen_stack_protect_set_si);
17960 #endif
17961
17962 emit_insn (insn (operands[0], operands[1]));
17963 DONE;
17964 })
17965
17966 (define_insn "stack_protect_set_<mode>"
17967 [(set (match_operand:PTR 0 "memory_operand" "=m")
17968 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17969 UNSPEC_SP_SET))
17970 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17971 (clobber (reg:CC FLAGS_REG))]
17972 "TARGET_SSP_TLS_GUARD"
17973 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17974 [(set_attr "type" "multi")])
17975
17976 (define_insn "stack_tls_protect_set_<mode>"
17977 [(set (match_operand:PTR 0 "memory_operand" "=m")
17978 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17979 UNSPEC_SP_TLS_SET))
17980 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17981 (clobber (reg:CC FLAGS_REG))]
17982 ""
17983 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17984 [(set_attr "type" "multi")])
17985
17986 (define_expand "stack_protect_test"
17987 [(match_operand 0 "memory_operand")
17988 (match_operand 1 "memory_operand")
17989 (match_operand 2)]
17990 "TARGET_SSP_TLS_GUARD"
17991 {
17992 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17993
17994 rtx (*insn)(rtx, rtx, rtx);
17995
17996 #ifdef TARGET_THREAD_SSP_OFFSET
17997 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17998 insn = (TARGET_LP64
17999 ? gen_stack_tls_protect_test_di
18000 : gen_stack_tls_protect_test_si);
18001 #else
18002 insn = (TARGET_LP64
18003 ? gen_stack_protect_test_di
18004 : gen_stack_protect_test_si);
18005 #endif
18006
18007 emit_insn (insn (flags, operands[0], operands[1]));
18008
18009 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18010 flags, const0_rtx, operands[2]));
18011 DONE;
18012 })
18013
18014 (define_insn "stack_protect_test_<mode>"
18015 [(set (match_operand:CCZ 0 "flags_reg_operand")
18016 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18017 (match_operand:PTR 2 "memory_operand" "m")]
18018 UNSPEC_SP_TEST))
18019 (clobber (match_scratch:PTR 3 "=&r"))]
18020 "TARGET_SSP_TLS_GUARD"
18021 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18022 [(set_attr "type" "multi")])
18023
18024 (define_insn "stack_tls_protect_test_<mode>"
18025 [(set (match_operand:CCZ 0 "flags_reg_operand")
18026 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18027 (match_operand:PTR 2 "const_int_operand" "i")]
18028 UNSPEC_SP_TLS_TEST))
18029 (clobber (match_scratch:PTR 3 "=r"))]
18030 ""
18031 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18032 [(set_attr "type" "multi")])
18033
18034 (define_insn "sse4_2_crc32<mode>"
18035 [(set (match_operand:SI 0 "register_operand" "=r")
18036 (unspec:SI
18037 [(match_operand:SI 1 "register_operand" "0")
18038 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18039 UNSPEC_CRC32))]
18040 "TARGET_SSE4_2 || TARGET_CRC32"
18041 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18042 [(set_attr "type" "sselog1")
18043 (set_attr "prefix_rep" "1")
18044 (set_attr "prefix_extra" "1")
18045 (set (attr "prefix_data16")
18046 (if_then_else (match_operand:HI 2)
18047 (const_string "1")
18048 (const_string "*")))
18049 (set (attr "prefix_rex")
18050 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18051 (const_string "1")
18052 (const_string "*")))
18053 (set_attr "mode" "SI")])
18054
18055 (define_insn "sse4_2_crc32di"
18056 [(set (match_operand:DI 0 "register_operand" "=r")
18057 (unspec:DI
18058 [(match_operand:DI 1 "register_operand" "0")
18059 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18060 UNSPEC_CRC32))]
18061 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18062 "crc32{q}\t{%2, %0|%0, %2}"
18063 [(set_attr "type" "sselog1")
18064 (set_attr "prefix_rep" "1")
18065 (set_attr "prefix_extra" "1")
18066 (set_attr "mode" "DI")])
18067
18068 (define_insn "rdpmc"
18069 [(set (match_operand:DI 0 "register_operand" "=A")
18070 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18071 UNSPECV_RDPMC))]
18072 "!TARGET_64BIT"
18073 "rdpmc"
18074 [(set_attr "type" "other")
18075 (set_attr "length" "2")])
18076
18077 (define_insn "rdpmc_rex64"
18078 [(set (match_operand:DI 0 "register_operand" "=a")
18079 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18080 UNSPECV_RDPMC))
18081 (set (match_operand:DI 1 "register_operand" "=d")
18082 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18083 "TARGET_64BIT"
18084 "rdpmc"
18085 [(set_attr "type" "other")
18086 (set_attr "length" "2")])
18087
18088 (define_insn "rdtsc"
18089 [(set (match_operand:DI 0 "register_operand" "=A")
18090 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18091 "!TARGET_64BIT"
18092 "rdtsc"
18093 [(set_attr "type" "other")
18094 (set_attr "length" "2")])
18095
18096 (define_insn "rdtsc_rex64"
18097 [(set (match_operand:DI 0 "register_operand" "=a")
18098 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18099 (set (match_operand:DI 1 "register_operand" "=d")
18100 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18101 "TARGET_64BIT"
18102 "rdtsc"
18103 [(set_attr "type" "other")
18104 (set_attr "length" "2")])
18105
18106 (define_insn "rdtscp"
18107 [(set (match_operand:DI 0 "register_operand" "=A")
18108 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18109 (set (match_operand:SI 1 "register_operand" "=c")
18110 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18111 "!TARGET_64BIT"
18112 "rdtscp"
18113 [(set_attr "type" "other")
18114 (set_attr "length" "3")])
18115
18116 (define_insn "rdtscp_rex64"
18117 [(set (match_operand:DI 0 "register_operand" "=a")
18118 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18119 (set (match_operand:DI 1 "register_operand" "=d")
18120 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18121 (set (match_operand:SI 2 "register_operand" "=c")
18122 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18123 "TARGET_64BIT"
18124 "rdtscp"
18125 [(set_attr "type" "other")
18126 (set_attr "length" "3")])
18127
18128 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18129 ;;
18130 ;; FXSR, XSAVE and XSAVEOPT instructions
18131 ;;
18132 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18133
18134 (define_insn "fxsave"
18135 [(set (match_operand:BLK 0 "memory_operand" "=m")
18136 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18137 "TARGET_FXSR"
18138 "fxsave\t%0"
18139 [(set_attr "type" "other")
18140 (set_attr "memory" "store")
18141 (set (attr "length")
18142 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18143
18144 (define_insn "fxsave64"
18145 [(set (match_operand:BLK 0 "memory_operand" "=m")
18146 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18147 "TARGET_64BIT && TARGET_FXSR"
18148 "fxsave64\t%0"
18149 [(set_attr "type" "other")
18150 (set_attr "memory" "store")
18151 (set (attr "length")
18152 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18153
18154 (define_insn "fxrstor"
18155 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18156 UNSPECV_FXRSTOR)]
18157 "TARGET_FXSR"
18158 "fxrstor\t%0"
18159 [(set_attr "type" "other")
18160 (set_attr "memory" "load")
18161 (set (attr "length")
18162 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18163
18164 (define_insn "fxrstor64"
18165 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18166 UNSPECV_FXRSTOR64)]
18167 "TARGET_64BIT && TARGET_FXSR"
18168 "fxrstor64\t%0"
18169 [(set_attr "type" "other")
18170 (set_attr "memory" "load")
18171 (set (attr "length")
18172 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18173
18174 (define_int_iterator ANY_XSAVE
18175 [UNSPECV_XSAVE
18176 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18177 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18178 (UNSPECV_XSAVES "TARGET_XSAVES")])
18179
18180 (define_int_iterator ANY_XSAVE64
18181 [UNSPECV_XSAVE64
18182 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18183 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18184 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18185
18186 (define_int_attr xsave
18187 [(UNSPECV_XSAVE "xsave")
18188 (UNSPECV_XSAVE64 "xsave64")
18189 (UNSPECV_XSAVEOPT "xsaveopt")
18190 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18191 (UNSPECV_XSAVEC "xsavec")
18192 (UNSPECV_XSAVEC64 "xsavec64")
18193 (UNSPECV_XSAVES "xsaves")
18194 (UNSPECV_XSAVES64 "xsaves64")])
18195
18196 (define_int_iterator ANY_XRSTOR
18197 [UNSPECV_XRSTOR
18198 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18199
18200 (define_int_iterator ANY_XRSTOR64
18201 [UNSPECV_XRSTOR64
18202 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18203
18204 (define_int_attr xrstor
18205 [(UNSPECV_XRSTOR "xrstor")
18206 (UNSPECV_XRSTOR64 "xrstor")
18207 (UNSPECV_XRSTORS "xrstors")
18208 (UNSPECV_XRSTORS64 "xrstors")])
18209
18210 (define_insn "<xsave>"
18211 [(set (match_operand:BLK 0 "memory_operand" "=m")
18212 (unspec_volatile:BLK
18213 [(match_operand:DI 1 "register_operand" "A")]
18214 ANY_XSAVE))]
18215 "!TARGET_64BIT && TARGET_XSAVE"
18216 "<xsave>\t%0"
18217 [(set_attr "type" "other")
18218 (set_attr "memory" "store")
18219 (set (attr "length")
18220 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18221
18222 (define_insn "<xsave>_rex64"
18223 [(set (match_operand:BLK 0 "memory_operand" "=m")
18224 (unspec_volatile:BLK
18225 [(match_operand:SI 1 "register_operand" "a")
18226 (match_operand:SI 2 "register_operand" "d")]
18227 ANY_XSAVE))]
18228 "TARGET_64BIT && TARGET_XSAVE"
18229 "<xsave>\t%0"
18230 [(set_attr "type" "other")
18231 (set_attr "memory" "store")
18232 (set (attr "length")
18233 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18234
18235 (define_insn "<xsave>"
18236 [(set (match_operand:BLK 0 "memory_operand" "=m")
18237 (unspec_volatile:BLK
18238 [(match_operand:SI 1 "register_operand" "a")
18239 (match_operand:SI 2 "register_operand" "d")]
18240 ANY_XSAVE64))]
18241 "TARGET_64BIT && TARGET_XSAVE"
18242 "<xsave>\t%0"
18243 [(set_attr "type" "other")
18244 (set_attr "memory" "store")
18245 (set (attr "length")
18246 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18247
18248 (define_insn "<xrstor>"
18249 [(unspec_volatile:BLK
18250 [(match_operand:BLK 0 "memory_operand" "m")
18251 (match_operand:DI 1 "register_operand" "A")]
18252 ANY_XRSTOR)]
18253 "!TARGET_64BIT && TARGET_XSAVE"
18254 "<xrstor>\t%0"
18255 [(set_attr "type" "other")
18256 (set_attr "memory" "load")
18257 (set (attr "length")
18258 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18259
18260 (define_insn "<xrstor>_rex64"
18261 [(unspec_volatile:BLK
18262 [(match_operand:BLK 0 "memory_operand" "m")
18263 (match_operand:SI 1 "register_operand" "a")
18264 (match_operand:SI 2 "register_operand" "d")]
18265 ANY_XRSTOR)]
18266 "TARGET_64BIT && TARGET_XSAVE"
18267 "<xrstor>\t%0"
18268 [(set_attr "type" "other")
18269 (set_attr "memory" "load")
18270 (set (attr "length")
18271 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18272
18273 (define_insn "<xrstor>64"
18274 [(unspec_volatile:BLK
18275 [(match_operand:BLK 0 "memory_operand" "m")
18276 (match_operand:SI 1 "register_operand" "a")
18277 (match_operand:SI 2 "register_operand" "d")]
18278 ANY_XRSTOR64)]
18279 "TARGET_64BIT && TARGET_XSAVE"
18280 "<xrstor>64\t%0"
18281 [(set_attr "type" "other")
18282 (set_attr "memory" "load")
18283 (set (attr "length")
18284 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18285
18286 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18287 ;;
18288 ;; Floating-point instructions for atomic compound assignments
18289 ;;
18290 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18291
18292 ; Clobber all floating-point registers on environment save and restore
18293 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18294 (define_insn "fnstenv"
18295 [(set (match_operand:BLK 0 "memory_operand" "=m")
18296 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18297 (clobber (reg:HI FPCR_REG))
18298 (clobber (reg:XF ST0_REG))
18299 (clobber (reg:XF ST1_REG))
18300 (clobber (reg:XF ST2_REG))
18301 (clobber (reg:XF ST3_REG))
18302 (clobber (reg:XF ST4_REG))
18303 (clobber (reg:XF ST5_REG))
18304 (clobber (reg:XF ST6_REG))
18305 (clobber (reg:XF ST7_REG))]
18306 "TARGET_80387"
18307 "fnstenv\t%0"
18308 [(set_attr "type" "other")
18309 (set_attr "memory" "store")
18310 (set (attr "length")
18311 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18312
18313 (define_insn "fldenv"
18314 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18315 UNSPECV_FLDENV)
18316 (clobber (reg:CCFP FPSR_REG))
18317 (clobber (reg:HI FPCR_REG))
18318 (clobber (reg:XF ST0_REG))
18319 (clobber (reg:XF ST1_REG))
18320 (clobber (reg:XF ST2_REG))
18321 (clobber (reg:XF ST3_REG))
18322 (clobber (reg:XF ST4_REG))
18323 (clobber (reg:XF ST5_REG))
18324 (clobber (reg:XF ST6_REG))
18325 (clobber (reg:XF ST7_REG))]
18326 "TARGET_80387"
18327 "fldenv\t%0"
18328 [(set_attr "type" "other")
18329 (set_attr "memory" "load")
18330 (set (attr "length")
18331 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18332
18333 (define_insn "fnstsw"
18334 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18335 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18336 "TARGET_80387"
18337 "fnstsw\t%0"
18338 [(set_attr "type" "other,other")
18339 (set_attr "memory" "none,store")
18340 (set (attr "length")
18341 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18342
18343 (define_insn "fnclex"
18344 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18345 "TARGET_80387"
18346 "fnclex"
18347 [(set_attr "type" "other")
18348 (set_attr "memory" "none")
18349 (set_attr "length" "2")])
18350
18351 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18352 ;;
18353 ;; LWP instructions
18354 ;;
18355 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18356
18357 (define_expand "lwp_llwpcb"
18358 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18359 UNSPECV_LLWP_INTRINSIC)]
18360 "TARGET_LWP")
18361
18362 (define_insn "*lwp_llwpcb<mode>1"
18363 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18364 UNSPECV_LLWP_INTRINSIC)]
18365 "TARGET_LWP"
18366 "llwpcb\t%0"
18367 [(set_attr "type" "lwp")
18368 (set_attr "mode" "<MODE>")
18369 (set_attr "length" "5")])
18370
18371 (define_expand "lwp_slwpcb"
18372 [(set (match_operand 0 "register_operand" "=r")
18373 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18374 "TARGET_LWP"
18375 {
18376 rtx (*insn)(rtx);
18377
18378 insn = (Pmode == DImode
18379 ? gen_lwp_slwpcbdi
18380 : gen_lwp_slwpcbsi);
18381
18382 emit_insn (insn (operands[0]));
18383 DONE;
18384 })
18385
18386 (define_insn "lwp_slwpcb<mode>"
18387 [(set (match_operand:P 0 "register_operand" "=r")
18388 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18389 "TARGET_LWP"
18390 "slwpcb\t%0"
18391 [(set_attr "type" "lwp")
18392 (set_attr "mode" "<MODE>")
18393 (set_attr "length" "5")])
18394
18395 (define_expand "lwp_lwpval<mode>3"
18396 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18397 (match_operand:SI 2 "nonimmediate_operand" "rm")
18398 (match_operand:SI 3 "const_int_operand" "i")]
18399 UNSPECV_LWPVAL_INTRINSIC)]
18400 "TARGET_LWP"
18401 ;; Avoid unused variable warning.
18402 "(void) operands[0];")
18403
18404 (define_insn "*lwp_lwpval<mode>3_1"
18405 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18406 (match_operand:SI 1 "nonimmediate_operand" "rm")
18407 (match_operand:SI 2 "const_int_operand" "i")]
18408 UNSPECV_LWPVAL_INTRINSIC)]
18409 "TARGET_LWP"
18410 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18411 [(set_attr "type" "lwp")
18412 (set_attr "mode" "<MODE>")
18413 (set (attr "length")
18414 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18415
18416 (define_expand "lwp_lwpins<mode>3"
18417 [(set (reg:CCC FLAGS_REG)
18418 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18419 (match_operand:SI 2 "nonimmediate_operand" "rm")
18420 (match_operand:SI 3 "const_int_operand" "i")]
18421 UNSPECV_LWPINS_INTRINSIC))
18422 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18423 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18424 "TARGET_LWP")
18425
18426 (define_insn "*lwp_lwpins<mode>3_1"
18427 [(set (reg:CCC FLAGS_REG)
18428 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18429 (match_operand:SI 1 "nonimmediate_operand" "rm")
18430 (match_operand:SI 2 "const_int_operand" "i")]
18431 UNSPECV_LWPINS_INTRINSIC))]
18432 "TARGET_LWP"
18433 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18434 [(set_attr "type" "lwp")
18435 (set_attr "mode" "<MODE>")
18436 (set (attr "length")
18437 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18438
18439 (define_int_iterator RDFSGSBASE
18440 [UNSPECV_RDFSBASE
18441 UNSPECV_RDGSBASE])
18442
18443 (define_int_iterator WRFSGSBASE
18444 [UNSPECV_WRFSBASE
18445 UNSPECV_WRGSBASE])
18446
18447 (define_int_attr fsgs
18448 [(UNSPECV_RDFSBASE "fs")
18449 (UNSPECV_RDGSBASE "gs")
18450 (UNSPECV_WRFSBASE "fs")
18451 (UNSPECV_WRGSBASE "gs")])
18452
18453 (define_insn "rd<fsgs>base<mode>"
18454 [(set (match_operand:SWI48 0 "register_operand" "=r")
18455 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18456 "TARGET_64BIT && TARGET_FSGSBASE"
18457 "rd<fsgs>base\t%0"
18458 [(set_attr "type" "other")
18459 (set_attr "prefix_extra" "2")])
18460
18461 (define_insn "wr<fsgs>base<mode>"
18462 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18463 WRFSGSBASE)]
18464 "TARGET_64BIT && TARGET_FSGSBASE"
18465 "wr<fsgs>base\t%0"
18466 [(set_attr "type" "other")
18467 (set_attr "prefix_extra" "2")])
18468
18469 (define_insn "rdrand<mode>_1"
18470 [(set (match_operand:SWI248 0 "register_operand" "=r")
18471 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18472 (set (reg:CCC FLAGS_REG)
18473 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18474 "TARGET_RDRND"
18475 "rdrand\t%0"
18476 [(set_attr "type" "other")
18477 (set_attr "prefix_extra" "1")])
18478
18479 (define_insn "rdseed<mode>_1"
18480 [(set (match_operand:SWI248 0 "register_operand" "=r")
18481 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18482 (set (reg:CCC FLAGS_REG)
18483 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18484 "TARGET_RDSEED"
18485 "rdseed\t%0"
18486 [(set_attr "type" "other")
18487 (set_attr "prefix_extra" "1")])
18488
18489 (define_expand "pause"
18490 [(set (match_dup 0)
18491 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18492 ""
18493 {
18494 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18495 MEM_VOLATILE_P (operands[0]) = 1;
18496 })
18497
18498 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18499 ;; They have the same encoding.
18500 (define_insn "*pause"
18501 [(set (match_operand:BLK 0)
18502 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18503 ""
18504 "rep%; nop"
18505 [(set_attr "length" "2")
18506 (set_attr "memory" "unknown")])
18507
18508 (define_expand "xbegin"
18509 [(set (match_operand:SI 0 "register_operand")
18510 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18511 "TARGET_RTM"
18512 {
18513 rtx_code_label *label = gen_label_rtx ();
18514
18515 /* xbegin is emitted as jump_insn, so reload won't be able
18516 to reload its operand. Force the value into AX hard register. */
18517 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18518 emit_move_insn (ax_reg, constm1_rtx);
18519
18520 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18521
18522 emit_label (label);
18523 LABEL_NUSES (label) = 1;
18524
18525 emit_move_insn (operands[0], ax_reg);
18526
18527 DONE;
18528 })
18529
18530 (define_insn "xbegin_1"
18531 [(set (pc)
18532 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18533 (const_int 0))
18534 (label_ref (match_operand 1))
18535 (pc)))
18536 (set (match_operand:SI 0 "register_operand" "+a")
18537 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18538 "TARGET_RTM"
18539 "xbegin\t%l1"
18540 [(set_attr "type" "other")
18541 (set_attr "length" "6")])
18542
18543 (define_insn "xend"
18544 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18545 "TARGET_RTM"
18546 "xend"
18547 [(set_attr "type" "other")
18548 (set_attr "length" "3")])
18549
18550 (define_insn "xabort"
18551 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18552 UNSPECV_XABORT)]
18553 "TARGET_RTM"
18554 "xabort\t%0"
18555 [(set_attr "type" "other")
18556 (set_attr "length" "3")])
18557
18558 (define_expand "xtest"
18559 [(set (match_operand:QI 0 "register_operand")
18560 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18561 "TARGET_RTM"
18562 {
18563 emit_insn (gen_xtest_1 ());
18564
18565 ix86_expand_setcc (operands[0], NE,
18566 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18567 DONE;
18568 })
18569
18570 (define_insn "xtest_1"
18571 [(set (reg:CCZ FLAGS_REG)
18572 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18573 "TARGET_RTM"
18574 "xtest"
18575 [(set_attr "type" "other")
18576 (set_attr "length" "3")])
18577
18578 (define_insn "clflushopt"
18579 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18580 UNSPECV_CLFLUSHOPT)]
18581 "TARGET_CLFLUSHOPT"
18582 "clflushopt\t%a0"
18583 [(set_attr "type" "sse")
18584 (set_attr "atom_sse_attr" "fence")
18585 (set_attr "memory" "unknown")])
18586
18587 ;; MPX instructions
18588
18589 (define_expand "<mode>_mk"
18590 [(set (match_operand:BND 0 "register_operand")
18591 (unspec:BND
18592 [(mem:<bnd_ptr>
18593 (match_par_dup 3
18594 [(match_operand:<bnd_ptr> 1 "register_operand")
18595 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18596 UNSPEC_BNDMK))]
18597 "TARGET_MPX"
18598 {
18599 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18600 operands[2]),
18601 UNSPEC_BNDMK_ADDR);
18602 })
18603
18604 (define_insn "*<mode>_mk"
18605 [(set (match_operand:BND 0 "register_operand" "=w")
18606 (unspec:BND
18607 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18608 [(unspec:<bnd_ptr>
18609 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18610 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18611 UNSPEC_BNDMK_ADDR)])]
18612 UNSPEC_BNDMK))]
18613 "TARGET_MPX"
18614 "bndmk\t{%3, %0|%0, %3}"
18615 [(set_attr "type" "mpxmk")])
18616
18617 (define_expand "mov<mode>"
18618 [(set (match_operand:BND 0 "general_operand")
18619 (match_operand:BND 1 "general_operand"))]
18620 "TARGET_MPX"
18621 {
18622 ix86_expand_move (<MODE>mode, operands);DONE;
18623 })
18624
18625 (define_insn "*mov<mode>_internal_mpx"
18626 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18627 (match_operand:BND 1 "general_operand" "wm,w"))]
18628 "TARGET_MPX"
18629 "bndmov\t{%1, %0|%0, %1}"
18630 [(set_attr "type" "mpxmov")])
18631
18632 (define_expand "<mode>_<bndcheck>"
18633 [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18634 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18635 (set (match_dup 2)
18636 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18637 "TARGET_MPX"
18638 {
18639 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18640 MEM_VOLATILE_P (operands[2]) = 1;
18641 })
18642
18643 (define_insn "*<mode>_<bndcheck>"
18644 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18645 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18646 (set (match_operand:BLK 2 "bnd_mem_operator")
18647 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18648 "TARGET_MPX"
18649 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18650 [(set_attr "type" "mpxchk")])
18651
18652 (define_expand "<mode>_ldx"
18653 [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18654 (unspec:BND
18655 [(mem:<bnd_ptr>
18656 (match_par_dup 3
18657 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18658 (match_operand:<bnd_ptr> 2 "register_operand")]))]
18659 UNSPEC_BNDLDX))
18660 (use (mem:BLK (match_dup 1)))])]
18661 "TARGET_MPX"
18662 {
18663 /* Avoid registers which connot be used as index. */
18664 if (!index_register_operand (operands[2], Pmode))
18665 {
18666 rtx temp = gen_reg_rtx (Pmode);
18667 emit_move_insn (temp, operands[2]);
18668 operands[2] = temp;
18669 }
18670
18671 /* If it was a register originally then it may have
18672 mode other than Pmode. We need to extend in such
18673 case because bndldx may work only with Pmode regs. */
18674 if (GET_MODE (operands[2]) != Pmode)
18675 operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18676
18677 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18678 operands[2]),
18679 UNSPEC_BNDLDX_ADDR);
18680 })
18681
18682 (define_insn "*<mode>_ldx"
18683 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
18684 (unspec:BND
18685 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18686 [(unspec:<bnd_ptr>
18687 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18688 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18689 UNSPEC_BNDLDX_ADDR)])]
18690 UNSPEC_BNDLDX))
18691 (use (mem:BLK (match_dup 1)))])]
18692 "TARGET_MPX"
18693 "bndldx\t{%3, %0|%0, %3}"
18694 [(set_attr "type" "mpxld")])
18695
18696 (define_expand "<mode>_stx"
18697 [(parallel [(unspec [(mem:<bnd_ptr>
18698 (match_par_dup 3
18699 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18700 (match_operand:<bnd_ptr> 1 "register_operand")]))
18701 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18702 (set (match_dup 4)
18703 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18704 "TARGET_MPX"
18705 {
18706 /* Avoid registers which connot be used as index. */
18707 if (!index_register_operand (operands[1], Pmode))
18708 {
18709 rtx temp = gen_reg_rtx (Pmode);
18710 emit_move_insn (temp, operands[1]);
18711 operands[1] = temp;
18712 }
18713
18714 /* If it was a register originally then it may have
18715 mode other than Pmode. We need to extend in such
18716 case because bndstx may work only with Pmode regs. */
18717 if (GET_MODE (operands[1]) != Pmode)
18718 operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
18719
18720 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18721 operands[1]),
18722 UNSPEC_BNDLDX_ADDR);
18723 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18724 MEM_VOLATILE_P (operands[4]) = 1;
18725 })
18726
18727 (define_insn "*<mode>_stx"
18728 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18729 [(unspec:<bnd_ptr>
18730 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18731 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18732 UNSPEC_BNDLDX_ADDR)])
18733 (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
18734 (set (match_operand:BLK 4 "bnd_mem_operator")
18735 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18736 "TARGET_MPX"
18737 "bndstx\t{%2, %3|%3, %2}"
18738 [(set_attr "type" "mpxst")])
18739
18740 (define_insn "move_size_reloc_<mode>"
18741 [(set (match_operand:SWI48 0 "register_operand" "=r")
18742 (unspec:SWI48
18743 [(match_operand:SWI48 1 "symbol_operand")]
18744 UNSPEC_SIZEOF))]
18745 "TARGET_MPX"
18746 {
18747 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
18748 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
18749 else
18750 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
18751 }
18752 [(set_attr "type" "imov")
18753 (set_attr "mode" "<MODE>")])
18754
18755 (include "mmx.md")
18756 (include "sse.md")
18757 (include "sync.md")