49a56863617a6bfe6c5a9096d5140a4feb37bf8e
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;; otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; K -- print HLE lock prefix
62 ;; Y -- print condition for XOP pcom* instruction.
63 ;; + -- print a branch hint as 'cs' or 'ds' prefix
64 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
65 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
66 ;; @ -- print a segment register of thread base pointer load
67 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
68
69 (define_c_enum "unspec" [
70 ;; Relocation specifiers
71 UNSPEC_GOT
72 UNSPEC_GOTOFF
73 UNSPEC_GOTPCREL
74 UNSPEC_GOTTPOFF
75 UNSPEC_TPOFF
76 UNSPEC_NTPOFF
77 UNSPEC_DTPOFF
78 UNSPEC_GOTNTPOFF
79 UNSPEC_INDNTPOFF
80 UNSPEC_PLTOFF
81 UNSPEC_MACHOPIC_OFFSET
82 UNSPEC_PCREL
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_MS_TO_SYSV_CALL
112 UNSPEC_CALL_NEEDS_VZEROUPPER
113 UNSPEC_PAUSE
114 UNSPEC_LEA_ADDR
115 UNSPEC_XBEGIN_ABORT
116
117 ;; For SSE/MMX support:
118 UNSPEC_FIX_NOTRUNC
119 UNSPEC_MASKMOV
120 UNSPEC_MOVMSK
121 UNSPEC_RCP
122 UNSPEC_RSQRT
123 UNSPEC_PSADBW
124
125 ;; Generic math support
126 UNSPEC_COPYSIGN
127 UNSPEC_IEEE_MIN ; not commutative
128 UNSPEC_IEEE_MAX ; not commutative
129
130 ;; x87 Floating point
131 UNSPEC_SIN
132 UNSPEC_COS
133 UNSPEC_FPATAN
134 UNSPEC_FYL2X
135 UNSPEC_FYL2XP1
136 UNSPEC_FRNDINT
137 UNSPEC_FIST
138 UNSPEC_F2XM1
139 UNSPEC_TAN
140 UNSPEC_FXAM
141
142 ;; x87 Rounding
143 UNSPEC_FRNDINT_FLOOR
144 UNSPEC_FRNDINT_CEIL
145 UNSPEC_FRNDINT_TRUNC
146 UNSPEC_FRNDINT_MASK_PM
147 UNSPEC_FIST_FLOOR
148 UNSPEC_FIST_CEIL
149
150 ;; x87 Double output FP
151 UNSPEC_SINCOS_COS
152 UNSPEC_SINCOS_SIN
153 UNSPEC_XTRACT_FRACT
154 UNSPEC_XTRACT_EXP
155 UNSPEC_FSCALE_FRACT
156 UNSPEC_FSCALE_EXP
157 UNSPEC_FPREM_F
158 UNSPEC_FPREM_U
159 UNSPEC_FPREM1_F
160 UNSPEC_FPREM1_U
161
162 UNSPEC_C2_FLAG
163 UNSPEC_FXAM_MEM
164
165 ;; SSP patterns
166 UNSPEC_SP_SET
167 UNSPEC_SP_TEST
168 UNSPEC_SP_TLS_SET
169 UNSPEC_SP_TLS_TEST
170
171 ;; For ROUND support
172 UNSPEC_ROUND
173
174 ;; For CRC32 support
175 UNSPEC_CRC32
176
177 ;; For BMI support
178 UNSPEC_BEXTR
179
180 ;; For BMI2 support
181 UNSPEC_PDEP
182 UNSPEC_PEXT
183 ])
184
185 (define_c_enum "unspecv" [
186 UNSPECV_BLOCKAGE
187 UNSPECV_STACK_PROBE
188 UNSPECV_PROBE_STACK_RANGE
189 UNSPECV_ALIGN
190 UNSPECV_PROLOGUE_USE
191 UNSPECV_SPLIT_STACK_RETURN
192 UNSPECV_CLD
193 UNSPECV_NOPS
194 UNSPECV_RDTSC
195 UNSPECV_RDTSCP
196 UNSPECV_RDPMC
197 UNSPECV_LLWP_INTRINSIC
198 UNSPECV_SLWP_INTRINSIC
199 UNSPECV_LWPVAL_INTRINSIC
200 UNSPECV_LWPINS_INTRINSIC
201 UNSPECV_RDFSBASE
202 UNSPECV_RDGSBASE
203 UNSPECV_WRFSBASE
204 UNSPECV_WRGSBASE
205
206 ;; For RDRAND support
207 UNSPECV_RDRAND
208
209 ;; For RTM support
210 UNSPECV_XBEGIN
211 UNSPECV_XEND
212 UNSPECV_XABORT
213 UNSPECV_XTEST
214 ])
215
216 ;; Constants to represent rounding modes in the ROUND instruction
217 (define_constants
218 [(ROUND_FLOOR 0x1)
219 (ROUND_CEIL 0x2)
220 (ROUND_TRUNC 0x3)
221 (ROUND_MXCSR 0x4)
222 (ROUND_NO_EXC 0x8)
223 ])
224
225 ;; Constants to represent pcomtrue/pcomfalse variants
226 (define_constants
227 [(PCOM_FALSE 0)
228 (PCOM_TRUE 1)
229 (COM_FALSE_S 2)
230 (COM_FALSE_P 3)
231 (COM_TRUE_S 4)
232 (COM_TRUE_P 5)
233 ])
234
235 ;; Constants used in the XOP pperm instruction
236 (define_constants
237 [(PPERM_SRC 0x00) /* copy source */
238 (PPERM_INVERT 0x20) /* invert source */
239 (PPERM_REVERSE 0x40) /* bit reverse source */
240 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
241 (PPERM_ZERO 0x80) /* all 0's */
242 (PPERM_ONES 0xa0) /* all 1's */
243 (PPERM_SIGN 0xc0) /* propagate sign bit */
244 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
245 (PPERM_SRC1 0x00) /* use first source byte */
246 (PPERM_SRC2 0x10) /* use second source byte */
247 ])
248
249 ;; Registers by name.
250 (define_constants
251 [(AX_REG 0)
252 (DX_REG 1)
253 (CX_REG 2)
254 (BX_REG 3)
255 (SI_REG 4)
256 (DI_REG 5)
257 (BP_REG 6)
258 (SP_REG 7)
259 (ST0_REG 8)
260 (ST1_REG 9)
261 (ST2_REG 10)
262 (ST3_REG 11)
263 (ST4_REG 12)
264 (ST5_REG 13)
265 (ST6_REG 14)
266 (ST7_REG 15)
267 (FLAGS_REG 17)
268 (FPSR_REG 18)
269 (FPCR_REG 19)
270 (XMM0_REG 21)
271 (XMM1_REG 22)
272 (XMM2_REG 23)
273 (XMM3_REG 24)
274 (XMM4_REG 25)
275 (XMM5_REG 26)
276 (XMM6_REG 27)
277 (XMM7_REG 28)
278 (MM0_REG 29)
279 (MM1_REG 30)
280 (MM2_REG 31)
281 (MM3_REG 32)
282 (MM4_REG 33)
283 (MM5_REG 34)
284 (MM6_REG 35)
285 (MM7_REG 36)
286 (R8_REG 37)
287 (R9_REG 38)
288 (R10_REG 39)
289 (R11_REG 40)
290 (R12_REG 41)
291 (R13_REG 42)
292 (XMM8_REG 45)
293 (XMM9_REG 46)
294 (XMM10_REG 47)
295 (XMM11_REG 48)
296 (XMM12_REG 49)
297 (XMM13_REG 50)
298 (XMM14_REG 51)
299 (XMM15_REG 52)
300 ])
301
302 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
303 ;; from i386.c.
304
305 ;; In C guard expressions, put expressions which may be compile-time
306 ;; constants first. This allows for better optimization. For
307 ;; example, write "TARGET_64BIT && reload_completed", not
308 ;; "reload_completed && TARGET_64BIT".
309
310 \f
311 ;; Processor type.
312 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
313 atom,generic64,amdfam10,bdver1,bdver2,btver1"
314 (const (symbol_ref "ix86_schedule")))
315
316 ;; A basic instruction type. Refinements due to arguments to be
317 ;; provided in other attributes.
318 (define_attr "type"
319 "other,multi,
320 alu,alu1,negnot,imov,imovx,lea,
321 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
322 icmp,test,ibr,setcc,icmov,
323 push,pop,call,callv,leave,
324 str,bitmanip,
325 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
326 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
327 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
328 ssemuladd,sse4arg,lwp,
329 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
330 (const_string "other"))
331
332 ;; Main data type used by the insn
333 (define_attr "mode"
334 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
335 (const_string "unknown"))
336
337 ;; The CPU unit operations uses.
338 (define_attr "unit" "integer,i387,sse,mmx,unknown"
339 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
340 (const_string "i387")
341 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
342 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
343 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
344 (const_string "sse")
345 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
346 (const_string "mmx")
347 (eq_attr "type" "other")
348 (const_string "unknown")]
349 (const_string "integer")))
350
351 ;; The (bounding maximum) length of an instruction immediate.
352 (define_attr "length_immediate" ""
353 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
354 bitmanip,imulx")
355 (const_int 0)
356 (eq_attr "unit" "i387,sse,mmx")
357 (const_int 0)
358 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
359 rotate,rotatex,rotate1,imul,icmp,push,pop")
360 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
361 (eq_attr "type" "imov,test")
362 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
363 (eq_attr "type" "call")
364 (if_then_else (match_operand 0 "constant_call_address_operand")
365 (const_int 4)
366 (const_int 0))
367 (eq_attr "type" "callv")
368 (if_then_else (match_operand 1 "constant_call_address_operand")
369 (const_int 4)
370 (const_int 0))
371 ;; We don't know the size before shorten_branches. Expect
372 ;; the instruction to fit for better scheduling.
373 (eq_attr "type" "ibr")
374 (const_int 1)
375 ]
376 (symbol_ref "/* Update immediate_length and other attributes! */
377 gcc_unreachable (),1")))
378
379 ;; The (bounding maximum) length of an instruction address.
380 (define_attr "length_address" ""
381 (cond [(eq_attr "type" "str,other,multi,fxch")
382 (const_int 0)
383 (and (eq_attr "type" "call")
384 (match_operand 0 "constant_call_address_operand"))
385 (const_int 0)
386 (and (eq_attr "type" "callv")
387 (match_operand 1 "constant_call_address_operand"))
388 (const_int 0)
389 ]
390 (symbol_ref "ix86_attr_length_address_default (insn)")))
391
392 ;; Set when length prefix is used.
393 (define_attr "prefix_data16" ""
394 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
395 (const_int 0)
396 (eq_attr "mode" "HI")
397 (const_int 1)
398 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
399 (const_int 1)
400 ]
401 (const_int 0)))
402
403 ;; Set when string REP prefix is used.
404 (define_attr "prefix_rep" ""
405 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
406 (const_int 0)
407 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
408 (const_int 1)
409 ]
410 (const_int 0)))
411
412 ;; Set when 0f opcode prefix is used.
413 (define_attr "prefix_0f" ""
414 (if_then_else
415 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
416 (eq_attr "unit" "sse,mmx"))
417 (const_int 1)
418 (const_int 0)))
419
420 ;; Set when REX opcode prefix is used.
421 (define_attr "prefix_rex" ""
422 (cond [(not (match_test "TARGET_64BIT"))
423 (const_int 0)
424 (and (eq_attr "mode" "DI")
425 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
426 (eq_attr "unit" "!mmx")))
427 (const_int 1)
428 (and (eq_attr "mode" "QI")
429 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
430 (const_int 1)
431 (match_test "x86_extended_reg_mentioned_p (insn)")
432 (const_int 1)
433 (and (eq_attr "type" "imovx")
434 (match_operand:QI 1 "ext_QIreg_operand"))
435 (const_int 1)
436 ]
437 (const_int 0)))
438
439 ;; There are also additional prefixes in 3DNOW, SSSE3.
440 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
441 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
442 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
443 (define_attr "prefix_extra" ""
444 (cond [(eq_attr "type" "ssemuladd,sse4arg")
445 (const_int 2)
446 (eq_attr "type" "sseiadd1,ssecvt1")
447 (const_int 1)
448 ]
449 (const_int 0)))
450
451 ;; Prefix used: original, VEX or maybe VEX.
452 (define_attr "prefix" "orig,vex,maybe_vex"
453 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
454 (const_string "vex")
455 (const_string "orig")))
456
457 ;; VEX W bit is used.
458 (define_attr "prefix_vex_w" "" (const_int 0))
459
460 ;; The length of VEX prefix
461 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
462 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
463 ;; still prefix_0f 1, with prefix_extra 1.
464 (define_attr "length_vex" ""
465 (if_then_else (and (eq_attr "prefix_0f" "1")
466 (eq_attr "prefix_extra" "0"))
467 (if_then_else (eq_attr "prefix_vex_w" "1")
468 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
469 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
470 (if_then_else (eq_attr "prefix_vex_w" "1")
471 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
472 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
473
474 ;; Set when modrm byte is used.
475 (define_attr "modrm" ""
476 (cond [(eq_attr "type" "str,leave")
477 (const_int 0)
478 (eq_attr "unit" "i387")
479 (const_int 0)
480 (and (eq_attr "type" "incdec")
481 (and (not (match_test "TARGET_64BIT"))
482 (ior (match_operand:SI 1 "register_operand")
483 (match_operand:HI 1 "register_operand"))))
484 (const_int 0)
485 (and (eq_attr "type" "push")
486 (not (match_operand 1 "memory_operand")))
487 (const_int 0)
488 (and (eq_attr "type" "pop")
489 (not (match_operand 0 "memory_operand")))
490 (const_int 0)
491 (and (eq_attr "type" "imov")
492 (and (not (eq_attr "mode" "DI"))
493 (ior (and (match_operand 0 "register_operand")
494 (match_operand 1 "immediate_operand"))
495 (ior (and (match_operand 0 "ax_reg_operand")
496 (match_operand 1 "memory_displacement_only_operand"))
497 (and (match_operand 0 "memory_displacement_only_operand")
498 (match_operand 1 "ax_reg_operand"))))))
499 (const_int 0)
500 (and (eq_attr "type" "call")
501 (match_operand 0 "constant_call_address_operand"))
502 (const_int 0)
503 (and (eq_attr "type" "callv")
504 (match_operand 1 "constant_call_address_operand"))
505 (const_int 0)
506 (and (eq_attr "type" "alu,alu1,icmp,test")
507 (match_operand 0 "ax_reg_operand"))
508 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
509 ]
510 (const_int 1)))
511
512 ;; The (bounding maximum) length of an instruction in bytes.
513 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
514 ;; Later we may want to split them and compute proper length as for
515 ;; other insns.
516 (define_attr "length" ""
517 (cond [(eq_attr "type" "other,multi,fistp,frndint")
518 (const_int 16)
519 (eq_attr "type" "fcmp")
520 (const_int 4)
521 (eq_attr "unit" "i387")
522 (plus (const_int 2)
523 (plus (attr "prefix_data16")
524 (attr "length_address")))
525 (ior (eq_attr "prefix" "vex")
526 (and (eq_attr "prefix" "maybe_vex")
527 (match_test "TARGET_AVX")))
528 (plus (attr "length_vex")
529 (plus (attr "length_immediate")
530 (plus (attr "modrm")
531 (attr "length_address"))))]
532 (plus (plus (attr "modrm")
533 (plus (attr "prefix_0f")
534 (plus (attr "prefix_rex")
535 (plus (attr "prefix_extra")
536 (const_int 1)))))
537 (plus (attr "prefix_rep")
538 (plus (attr "prefix_data16")
539 (plus (attr "length_immediate")
540 (attr "length_address")))))))
541
542 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
543 ;; `store' if there is a simple memory reference therein, or `unknown'
544 ;; if the instruction is complex.
545
546 (define_attr "memory" "none,load,store,both,unknown"
547 (cond [(eq_attr "type" "other,multi,str,lwp")
548 (const_string "unknown")
549 (eq_attr "type" "lea,fcmov,fpspc")
550 (const_string "none")
551 (eq_attr "type" "fistp,leave")
552 (const_string "both")
553 (eq_attr "type" "frndint")
554 (const_string "load")
555 (eq_attr "type" "push")
556 (if_then_else (match_operand 1 "memory_operand")
557 (const_string "both")
558 (const_string "store"))
559 (eq_attr "type" "pop")
560 (if_then_else (match_operand 0 "memory_operand")
561 (const_string "both")
562 (const_string "load"))
563 (eq_attr "type" "setcc")
564 (if_then_else (match_operand 0 "memory_operand")
565 (const_string "store")
566 (const_string "none"))
567 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
568 (if_then_else (ior (match_operand 0 "memory_operand")
569 (match_operand 1 "memory_operand"))
570 (const_string "load")
571 (const_string "none"))
572 (eq_attr "type" "ibr")
573 (if_then_else (match_operand 0 "memory_operand")
574 (const_string "load")
575 (const_string "none"))
576 (eq_attr "type" "call")
577 (if_then_else (match_operand 0 "constant_call_address_operand")
578 (const_string "none")
579 (const_string "load"))
580 (eq_attr "type" "callv")
581 (if_then_else (match_operand 1 "constant_call_address_operand")
582 (const_string "none")
583 (const_string "load"))
584 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
585 (match_operand 1 "memory_operand"))
586 (const_string "both")
587 (and (match_operand 0 "memory_operand")
588 (match_operand 1 "memory_operand"))
589 (const_string "both")
590 (match_operand 0 "memory_operand")
591 (const_string "store")
592 (match_operand 1 "memory_operand")
593 (const_string "load")
594 (and (eq_attr "type"
595 "!alu1,negnot,ishift1,
596 imov,imovx,icmp,test,bitmanip,
597 fmov,fcmp,fsgn,
598 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
599 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
600 (match_operand 2 "memory_operand"))
601 (const_string "load")
602 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
603 (match_operand 3 "memory_operand"))
604 (const_string "load")
605 ]
606 (const_string "none")))
607
608 ;; Indicates if an instruction has both an immediate and a displacement.
609
610 (define_attr "imm_disp" "false,true,unknown"
611 (cond [(eq_attr "type" "other,multi")
612 (const_string "unknown")
613 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
614 (and (match_operand 0 "memory_displacement_operand")
615 (match_operand 1 "immediate_operand")))
616 (const_string "true")
617 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
618 (and (match_operand 0 "memory_displacement_operand")
619 (match_operand 2 "immediate_operand")))
620 (const_string "true")
621 ]
622 (const_string "false")))
623
624 ;; Indicates if an FP operation has an integer source.
625
626 (define_attr "fp_int_src" "false,true"
627 (const_string "false"))
628
629 ;; Defines rounding mode of an FP operation.
630
631 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
632 (const_string "any"))
633
634 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
635 (define_attr "use_carry" "0,1" (const_string "0"))
636
637 ;; Define attribute to indicate unaligned ssemov insns
638 (define_attr "movu" "0,1" (const_string "0"))
639
640 ;; Used to control the "enabled" attribute on a per-instruction basis.
641 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,avx2,noavx2,bmi2"
642 (const_string "base"))
643
644 (define_attr "enabled" ""
645 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
646 (eq_attr "isa" "sse2_noavx")
647 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
648 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
649 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
650 (eq_attr "isa" "sse4_noavx")
651 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
652 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
653 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
654 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
655 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
656 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
657 ]
658 (const_int 1)))
659
660 ;; Describe a user's asm statement.
661 (define_asm_attributes
662 [(set_attr "length" "128")
663 (set_attr "type" "multi")])
664
665 (define_code_iterator plusminus [plus minus])
666
667 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
668
669 ;; Base name for define_insn
670 (define_code_attr plusminus_insn
671 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
672 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
673
674 ;; Base name for insn mnemonic.
675 (define_code_attr plusminus_mnemonic
676 [(plus "add") (ss_plus "adds") (us_plus "addus")
677 (minus "sub") (ss_minus "subs") (us_minus "subus")])
678 (define_code_attr plusminus_carry_mnemonic
679 [(plus "adc") (minus "sbb")])
680
681 ;; Mark commutative operators as such in constraints.
682 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
683 (minus "") (ss_minus "") (us_minus "")])
684
685 ;; Mapping of max and min
686 (define_code_iterator maxmin [smax smin umax umin])
687
688 ;; Mapping of signed max and min
689 (define_code_iterator smaxmin [smax smin])
690
691 ;; Mapping of unsigned max and min
692 (define_code_iterator umaxmin [umax umin])
693
694 ;; Base name for integer and FP insn mnemonic
695 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
696 (umax "maxu") (umin "minu")])
697 (define_code_attr maxmin_float [(smax "max") (smin "min")])
698
699 ;; Mapping of logic operators
700 (define_code_iterator any_logic [and ior xor])
701 (define_code_iterator any_or [ior xor])
702
703 ;; Base name for insn mnemonic.
704 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
705
706 ;; Mapping of logic-shift operators
707 (define_code_iterator any_lshift [ashift lshiftrt])
708
709 ;; Mapping of shift-right operators
710 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
711
712 ;; Mapping of all shift operators
713 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
714
715 ;; Base name for define_insn
716 (define_code_attr shift_insn
717 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
718
719 ;; Base name for insn mnemonic.
720 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
721 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
722
723 ;; Mapping of rotate operators
724 (define_code_iterator any_rotate [rotate rotatert])
725
726 ;; Base name for define_insn
727 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
728
729 ;; Base name for insn mnemonic.
730 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
731
732 ;; Mapping of abs neg operators
733 (define_code_iterator absneg [abs neg])
734
735 ;; Base name for x87 insn mnemonic.
736 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
737
738 ;; Used in signed and unsigned widening multiplications.
739 (define_code_iterator any_extend [sign_extend zero_extend])
740
741 ;; Prefix for insn menmonic.
742 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
743
744 ;; Prefix for define_insn
745 (define_code_attr u [(sign_extend "") (zero_extend "u")])
746 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
747 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
748
749 ;; All integer modes.
750 (define_mode_iterator SWI1248x [QI HI SI DI])
751
752 ;; All integer modes without QImode.
753 (define_mode_iterator SWI248x [HI SI DI])
754
755 ;; All integer modes without QImode and HImode.
756 (define_mode_iterator SWI48x [SI DI])
757
758 ;; All integer modes without SImode and DImode.
759 (define_mode_iterator SWI12 [QI HI])
760
761 ;; All integer modes without DImode.
762 (define_mode_iterator SWI124 [QI HI SI])
763
764 ;; All integer modes without QImode and DImode.
765 (define_mode_iterator SWI24 [HI SI])
766
767 ;; Single word integer modes.
768 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
769
770 ;; Single word integer modes without QImode.
771 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
772
773 ;; Single word integer modes without QImode and HImode.
774 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
775
776 ;; All math-dependant single and double word integer modes.
777 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
778 (HI "TARGET_HIMODE_MATH")
779 SI DI (TI "TARGET_64BIT")])
780
781 ;; Math-dependant single word integer modes.
782 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
783 (HI "TARGET_HIMODE_MATH")
784 SI (DI "TARGET_64BIT")])
785
786 ;; Math-dependant integer modes without DImode.
787 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
788 (HI "TARGET_HIMODE_MATH")
789 SI])
790
791 ;; Math-dependant single word integer modes without QImode.
792 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
793 SI (DI "TARGET_64BIT")])
794
795 ;; Double word integer modes.
796 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
797 (TI "TARGET_64BIT")])
798
799 ;; Double word integer modes as mode attribute.
800 (define_mode_attr DWI [(SI "DI") (DI "TI")])
801 (define_mode_attr dwi [(SI "di") (DI "ti")])
802
803 ;; Half mode for double word integer modes.
804 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
805 (DI "TARGET_64BIT")])
806
807 ;; Instruction suffix for integer modes.
808 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
809
810 ;; Pointer size prefix for integer modes (Intel asm dialect)
811 (define_mode_attr iptrsize [(QI "BYTE")
812 (HI "WORD")
813 (SI "DWORD")
814 (DI "QWORD")])
815
816 ;; Register class for integer modes.
817 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
818
819 ;; Immediate operand constraint for integer modes.
820 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
821
822 ;; General operand constraint for word modes.
823 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
824
825 ;; Immediate operand constraint for double integer modes.
826 (define_mode_attr di [(SI "nF") (DI "e")])
827
828 ;; Immediate operand constraint for shifts.
829 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
830
831 ;; General operand predicate for integer modes.
832 (define_mode_attr general_operand
833 [(QI "general_operand")
834 (HI "general_operand")
835 (SI "x86_64_general_operand")
836 (DI "x86_64_general_operand")
837 (TI "x86_64_general_operand")])
838
839 ;; General sign/zero extend operand predicate for integer modes.
840 (define_mode_attr general_szext_operand
841 [(QI "general_operand")
842 (HI "general_operand")
843 (SI "x86_64_szext_general_operand")
844 (DI "x86_64_szext_general_operand")])
845
846 ;; Immediate operand predicate for integer modes.
847 (define_mode_attr immediate_operand
848 [(QI "immediate_operand")
849 (HI "immediate_operand")
850 (SI "x86_64_immediate_operand")
851 (DI "x86_64_immediate_operand")])
852
853 ;; Nonmemory operand predicate for integer modes.
854 (define_mode_attr nonmemory_operand
855 [(QI "nonmemory_operand")
856 (HI "nonmemory_operand")
857 (SI "x86_64_nonmemory_operand")
858 (DI "x86_64_nonmemory_operand")])
859
860 ;; Operand predicate for shifts.
861 (define_mode_attr shift_operand
862 [(QI "nonimmediate_operand")
863 (HI "nonimmediate_operand")
864 (SI "nonimmediate_operand")
865 (DI "shiftdi_operand")
866 (TI "register_operand")])
867
868 ;; Operand predicate for shift argument.
869 (define_mode_attr shift_immediate_operand
870 [(QI "const_1_to_31_operand")
871 (HI "const_1_to_31_operand")
872 (SI "const_1_to_31_operand")
873 (DI "const_1_to_63_operand")])
874
875 ;; Input operand predicate for arithmetic left shifts.
876 (define_mode_attr ashl_input_operand
877 [(QI "nonimmediate_operand")
878 (HI "nonimmediate_operand")
879 (SI "nonimmediate_operand")
880 (DI "ashldi_input_operand")
881 (TI "reg_or_pm1_operand")])
882
883 ;; SSE and x87 SFmode and DFmode floating point modes
884 (define_mode_iterator MODEF [SF DF])
885
886 ;; All x87 floating point modes
887 (define_mode_iterator X87MODEF [SF DF XF])
888
889 ;; SSE instruction suffix for various modes
890 (define_mode_attr ssemodesuffix
891 [(SF "ss") (DF "sd")
892 (V8SF "ps") (V4DF "pd")
893 (V4SF "ps") (V2DF "pd")
894 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
895 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
896
897 ;; SSE vector suffix for floating point modes
898 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
899
900 ;; SSE vector mode corresponding to a scalar mode
901 (define_mode_attr ssevecmode
902 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
903
904 ;; Instruction suffix for REX 64bit operators.
905 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
906
907 ;; This mode iterator allows :P to be used for patterns that operate on
908 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
909 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
910
911 ;; This mode iterator allows :W to be used for patterns that operate on
912 ;; word_mode sized quantities.
913 (define_mode_iterator W
914 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
915
916 ;; This mode iterator allows :PTR to be used for patterns that operate on
917 ;; ptr_mode sized quantities.
918 (define_mode_iterator PTR
919 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
920 \f
921 ;; Scheduling descriptions
922
923 (include "pentium.md")
924 (include "ppro.md")
925 (include "k6.md")
926 (include "athlon.md")
927 (include "bdver1.md")
928 (include "geode.md")
929 (include "atom.md")
930 (include "core2.md")
931
932 \f
933 ;; Operand and operator predicates and constraints
934
935 (include "predicates.md")
936 (include "constraints.md")
937
938 \f
939 ;; Compare and branch/compare and store instructions.
940
941 (define_expand "cbranch<mode>4"
942 [(set (reg:CC FLAGS_REG)
943 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
944 (match_operand:SDWIM 2 "<general_operand>")))
945 (set (pc) (if_then_else
946 (match_operator 0 "ordered_comparison_operator"
947 [(reg:CC FLAGS_REG) (const_int 0)])
948 (label_ref (match_operand 3))
949 (pc)))]
950 ""
951 {
952 if (MEM_P (operands[1]) && MEM_P (operands[2]))
953 operands[1] = force_reg (<MODE>mode, operands[1]);
954 ix86_expand_branch (GET_CODE (operands[0]),
955 operands[1], operands[2], operands[3]);
956 DONE;
957 })
958
959 (define_expand "cstore<mode>4"
960 [(set (reg:CC FLAGS_REG)
961 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
962 (match_operand:SWIM 3 "<general_operand>")))
963 (set (match_operand:QI 0 "register_operand")
964 (match_operator 1 "ordered_comparison_operator"
965 [(reg:CC FLAGS_REG) (const_int 0)]))]
966 ""
967 {
968 if (MEM_P (operands[2]) && MEM_P (operands[3]))
969 operands[2] = force_reg (<MODE>mode, operands[2]);
970 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
971 operands[2], operands[3]);
972 DONE;
973 })
974
975 (define_expand "cmp<mode>_1"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
978 (match_operand:SWI48 1 "<general_operand>")))])
979
980 (define_insn "*cmp<mode>_ccno_1"
981 [(set (reg FLAGS_REG)
982 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
983 (match_operand:SWI 1 "const0_operand")))]
984 "ix86_match_ccmode (insn, CCNOmode)"
985 "@
986 test{<imodesuffix>}\t%0, %0
987 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
988 [(set_attr "type" "test,icmp")
989 (set_attr "length_immediate" "0,1")
990 (set_attr "mode" "<MODE>")])
991
992 (define_insn "*cmp<mode>_1"
993 [(set (reg FLAGS_REG)
994 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
995 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
996 "ix86_match_ccmode (insn, CCmode)"
997 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
998 [(set_attr "type" "icmp")
999 (set_attr "mode" "<MODE>")])
1000
1001 (define_insn "*cmp<mode>_minus_1"
1002 [(set (reg FLAGS_REG)
1003 (compare
1004 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1005 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1006 (const_int 0)))]
1007 "ix86_match_ccmode (insn, CCGOCmode)"
1008 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1009 [(set_attr "type" "icmp")
1010 (set_attr "mode" "<MODE>")])
1011
1012 (define_insn "*cmpqi_ext_1"
1013 [(set (reg FLAGS_REG)
1014 (compare
1015 (match_operand:QI 0 "general_operand" "Qm")
1016 (subreg:QI
1017 (zero_extract:SI
1018 (match_operand 1 "ext_register_operand" "Q")
1019 (const_int 8)
1020 (const_int 8)) 0)))]
1021 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1022 "cmp{b}\t{%h1, %0|%0, %h1}"
1023 [(set_attr "type" "icmp")
1024 (set_attr "mode" "QI")])
1025
1026 (define_insn "*cmpqi_ext_1_rex64"
1027 [(set (reg FLAGS_REG)
1028 (compare
1029 (match_operand:QI 0 "register_operand" "Q")
1030 (subreg:QI
1031 (zero_extract:SI
1032 (match_operand 1 "ext_register_operand" "Q")
1033 (const_int 8)
1034 (const_int 8)) 0)))]
1035 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1036 "cmp{b}\t{%h1, %0|%0, %h1}"
1037 [(set_attr "type" "icmp")
1038 (set_attr "mode" "QI")])
1039
1040 (define_insn "*cmpqi_ext_2"
1041 [(set (reg FLAGS_REG)
1042 (compare
1043 (subreg:QI
1044 (zero_extract:SI
1045 (match_operand 0 "ext_register_operand" "Q")
1046 (const_int 8)
1047 (const_int 8)) 0)
1048 (match_operand:QI 1 "const0_operand")))]
1049 "ix86_match_ccmode (insn, CCNOmode)"
1050 "test{b}\t%h0, %h0"
1051 [(set_attr "type" "test")
1052 (set_attr "length_immediate" "0")
1053 (set_attr "mode" "QI")])
1054
1055 (define_expand "cmpqi_ext_3"
1056 [(set (reg:CC FLAGS_REG)
1057 (compare:CC
1058 (subreg:QI
1059 (zero_extract:SI
1060 (match_operand 0 "ext_register_operand")
1061 (const_int 8)
1062 (const_int 8)) 0)
1063 (match_operand:QI 1 "immediate_operand")))])
1064
1065 (define_insn "*cmpqi_ext_3_insn"
1066 [(set (reg FLAGS_REG)
1067 (compare
1068 (subreg:QI
1069 (zero_extract:SI
1070 (match_operand 0 "ext_register_operand" "Q")
1071 (const_int 8)
1072 (const_int 8)) 0)
1073 (match_operand:QI 1 "general_operand" "Qmn")))]
1074 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1075 "cmp{b}\t{%1, %h0|%h0, %1}"
1076 [(set_attr "type" "icmp")
1077 (set_attr "modrm" "1")
1078 (set_attr "mode" "QI")])
1079
1080 (define_insn "*cmpqi_ext_3_insn_rex64"
1081 [(set (reg FLAGS_REG)
1082 (compare
1083 (subreg:QI
1084 (zero_extract:SI
1085 (match_operand 0 "ext_register_operand" "Q")
1086 (const_int 8)
1087 (const_int 8)) 0)
1088 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1089 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1090 "cmp{b}\t{%1, %h0|%h0, %1}"
1091 [(set_attr "type" "icmp")
1092 (set_attr "modrm" "1")
1093 (set_attr "mode" "QI")])
1094
1095 (define_insn "*cmpqi_ext_4"
1096 [(set (reg FLAGS_REG)
1097 (compare
1098 (subreg:QI
1099 (zero_extract:SI
1100 (match_operand 0 "ext_register_operand" "Q")
1101 (const_int 8)
1102 (const_int 8)) 0)
1103 (subreg:QI
1104 (zero_extract:SI
1105 (match_operand 1 "ext_register_operand" "Q")
1106 (const_int 8)
1107 (const_int 8)) 0)))]
1108 "ix86_match_ccmode (insn, CCmode)"
1109 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1110 [(set_attr "type" "icmp")
1111 (set_attr "mode" "QI")])
1112
1113 ;; These implement float point compares.
1114 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1115 ;; which would allow mix and match FP modes on the compares. Which is what
1116 ;; the old patterns did, but with many more of them.
1117
1118 (define_expand "cbranchxf4"
1119 [(set (reg:CC FLAGS_REG)
1120 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1121 (match_operand:XF 2 "nonmemory_operand")))
1122 (set (pc) (if_then_else
1123 (match_operator 0 "ix86_fp_comparison_operator"
1124 [(reg:CC FLAGS_REG)
1125 (const_int 0)])
1126 (label_ref (match_operand 3))
1127 (pc)))]
1128 "TARGET_80387"
1129 {
1130 ix86_expand_branch (GET_CODE (operands[0]),
1131 operands[1], operands[2], operands[3]);
1132 DONE;
1133 })
1134
1135 (define_expand "cstorexf4"
1136 [(set (reg:CC FLAGS_REG)
1137 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1138 (match_operand:XF 3 "nonmemory_operand")))
1139 (set (match_operand:QI 0 "register_operand")
1140 (match_operator 1 "ix86_fp_comparison_operator"
1141 [(reg:CC FLAGS_REG)
1142 (const_int 0)]))]
1143 "TARGET_80387"
1144 {
1145 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1146 operands[2], operands[3]);
1147 DONE;
1148 })
1149
1150 (define_expand "cbranch<mode>4"
1151 [(set (reg:CC FLAGS_REG)
1152 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1153 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1154 (set (pc) (if_then_else
1155 (match_operator 0 "ix86_fp_comparison_operator"
1156 [(reg:CC FLAGS_REG)
1157 (const_int 0)])
1158 (label_ref (match_operand 3))
1159 (pc)))]
1160 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1161 {
1162 ix86_expand_branch (GET_CODE (operands[0]),
1163 operands[1], operands[2], operands[3]);
1164 DONE;
1165 })
1166
1167 (define_expand "cstore<mode>4"
1168 [(set (reg:CC FLAGS_REG)
1169 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1170 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1171 (set (match_operand:QI 0 "register_operand")
1172 (match_operator 1 "ix86_fp_comparison_operator"
1173 [(reg:CC FLAGS_REG)
1174 (const_int 0)]))]
1175 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1176 {
1177 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1178 operands[2], operands[3]);
1179 DONE;
1180 })
1181
1182 (define_expand "cbranchcc4"
1183 [(set (pc) (if_then_else
1184 (match_operator 0 "comparison_operator"
1185 [(match_operand 1 "flags_reg_operand")
1186 (match_operand 2 "const0_operand")])
1187 (label_ref (match_operand 3))
1188 (pc)))]
1189 ""
1190 {
1191 ix86_expand_branch (GET_CODE (operands[0]),
1192 operands[1], operands[2], operands[3]);
1193 DONE;
1194 })
1195
1196 (define_expand "cstorecc4"
1197 [(set (match_operand:QI 0 "register_operand")
1198 (match_operator 1 "comparison_operator"
1199 [(match_operand 2 "flags_reg_operand")
1200 (match_operand 3 "const0_operand")]))]
1201 ""
1202 {
1203 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1204 operands[2], operands[3]);
1205 DONE;
1206 })
1207
1208
1209 ;; FP compares, step 1:
1210 ;; Set the FP condition codes.
1211 ;;
1212 ;; CCFPmode compare with exceptions
1213 ;; CCFPUmode compare with no exceptions
1214
1215 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1216 ;; used to manage the reg stack popping would not be preserved.
1217
1218 (define_insn "*cmpfp_0"
1219 [(set (match_operand:HI 0 "register_operand" "=a")
1220 (unspec:HI
1221 [(compare:CCFP
1222 (match_operand 1 "register_operand" "f")
1223 (match_operand 2 "const0_operand"))]
1224 UNSPEC_FNSTSW))]
1225 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1226 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1227 "* return output_fp_compare (insn, operands, false, false);"
1228 [(set_attr "type" "multi")
1229 (set_attr "unit" "i387")
1230 (set (attr "mode")
1231 (cond [(match_operand:SF 1)
1232 (const_string "SF")
1233 (match_operand:DF 1)
1234 (const_string "DF")
1235 ]
1236 (const_string "XF")))])
1237
1238 (define_insn_and_split "*cmpfp_0_cc"
1239 [(set (reg:CCFP FLAGS_REG)
1240 (compare:CCFP
1241 (match_operand 1 "register_operand" "f")
1242 (match_operand 2 "const0_operand")))
1243 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1244 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1245 && TARGET_SAHF && !TARGET_CMOVE
1246 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1247 "#"
1248 "&& reload_completed"
1249 [(set (match_dup 0)
1250 (unspec:HI
1251 [(compare:CCFP (match_dup 1)(match_dup 2))]
1252 UNSPEC_FNSTSW))
1253 (set (reg:CC FLAGS_REG)
1254 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1255 ""
1256 [(set_attr "type" "multi")
1257 (set_attr "unit" "i387")
1258 (set (attr "mode")
1259 (cond [(match_operand:SF 1)
1260 (const_string "SF")
1261 (match_operand:DF 1)
1262 (const_string "DF")
1263 ]
1264 (const_string "XF")))])
1265
1266 (define_insn "*cmpfp_xf"
1267 [(set (match_operand:HI 0 "register_operand" "=a")
1268 (unspec:HI
1269 [(compare:CCFP
1270 (match_operand:XF 1 "register_operand" "f")
1271 (match_operand:XF 2 "register_operand" "f"))]
1272 UNSPEC_FNSTSW))]
1273 "TARGET_80387"
1274 "* return output_fp_compare (insn, operands, false, false);"
1275 [(set_attr "type" "multi")
1276 (set_attr "unit" "i387")
1277 (set_attr "mode" "XF")])
1278
1279 (define_insn_and_split "*cmpfp_xf_cc"
1280 [(set (reg:CCFP FLAGS_REG)
1281 (compare:CCFP
1282 (match_operand:XF 1 "register_operand" "f")
1283 (match_operand:XF 2 "register_operand" "f")))
1284 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1285 "TARGET_80387
1286 && TARGET_SAHF && !TARGET_CMOVE"
1287 "#"
1288 "&& reload_completed"
1289 [(set (match_dup 0)
1290 (unspec:HI
1291 [(compare:CCFP (match_dup 1)(match_dup 2))]
1292 UNSPEC_FNSTSW))
1293 (set (reg:CC FLAGS_REG)
1294 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1295 ""
1296 [(set_attr "type" "multi")
1297 (set_attr "unit" "i387")
1298 (set_attr "mode" "XF")])
1299
1300 (define_insn "*cmpfp_<mode>"
1301 [(set (match_operand:HI 0 "register_operand" "=a")
1302 (unspec:HI
1303 [(compare:CCFP
1304 (match_operand:MODEF 1 "register_operand" "f")
1305 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1306 UNSPEC_FNSTSW))]
1307 "TARGET_80387"
1308 "* return output_fp_compare (insn, operands, false, false);"
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "<MODE>")])
1312
1313 (define_insn_and_split "*cmpfp_<mode>_cc"
1314 [(set (reg:CCFP FLAGS_REG)
1315 (compare:CCFP
1316 (match_operand:MODEF 1 "register_operand" "f")
1317 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1318 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1319 "TARGET_80387
1320 && TARGET_SAHF && !TARGET_CMOVE"
1321 "#"
1322 "&& reload_completed"
1323 [(set (match_dup 0)
1324 (unspec:HI
1325 [(compare:CCFP (match_dup 1)(match_dup 2))]
1326 UNSPEC_FNSTSW))
1327 (set (reg:CC FLAGS_REG)
1328 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1329 ""
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1332 (set_attr "mode" "<MODE>")])
1333
1334 (define_insn "*cmpfp_u"
1335 [(set (match_operand:HI 0 "register_operand" "=a")
1336 (unspec:HI
1337 [(compare:CCFPU
1338 (match_operand 1 "register_operand" "f")
1339 (match_operand 2 "register_operand" "f"))]
1340 UNSPEC_FNSTSW))]
1341 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1342 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1343 "* return output_fp_compare (insn, operands, false, true);"
1344 [(set_attr "type" "multi")
1345 (set_attr "unit" "i387")
1346 (set (attr "mode")
1347 (cond [(match_operand:SF 1)
1348 (const_string "SF")
1349 (match_operand:DF 1)
1350 (const_string "DF")
1351 ]
1352 (const_string "XF")))])
1353
1354 (define_insn_and_split "*cmpfp_u_cc"
1355 [(set (reg:CCFPU FLAGS_REG)
1356 (compare:CCFPU
1357 (match_operand 1 "register_operand" "f")
1358 (match_operand 2 "register_operand" "f")))
1359 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1360 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1361 && TARGET_SAHF && !TARGET_CMOVE
1362 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1363 "#"
1364 "&& reload_completed"
1365 [(set (match_dup 0)
1366 (unspec:HI
1367 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1368 UNSPEC_FNSTSW))
1369 (set (reg:CC FLAGS_REG)
1370 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1371 ""
1372 [(set_attr "type" "multi")
1373 (set_attr "unit" "i387")
1374 (set (attr "mode")
1375 (cond [(match_operand:SF 1)
1376 (const_string "SF")
1377 (match_operand:DF 1)
1378 (const_string "DF")
1379 ]
1380 (const_string "XF")))])
1381
1382 (define_insn "*cmpfp_<mode>"
1383 [(set (match_operand:HI 0 "register_operand" "=a")
1384 (unspec:HI
1385 [(compare:CCFP
1386 (match_operand 1 "register_operand" "f")
1387 (match_operator 3 "float_operator"
1388 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1389 UNSPEC_FNSTSW))]
1390 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1391 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1392 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1393 "* return output_fp_compare (insn, operands, false, false);"
1394 [(set_attr "type" "multi")
1395 (set_attr "unit" "i387")
1396 (set_attr "fp_int_src" "true")
1397 (set_attr "mode" "<MODE>")])
1398
1399 (define_insn_and_split "*cmpfp_<mode>_cc"
1400 [(set (reg:CCFP FLAGS_REG)
1401 (compare:CCFP
1402 (match_operand 1 "register_operand" "f")
1403 (match_operator 3 "float_operator"
1404 [(match_operand:SWI24 2 "memory_operand" "m")])))
1405 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1406 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1407 && TARGET_SAHF && !TARGET_CMOVE
1408 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1409 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1410 "#"
1411 "&& reload_completed"
1412 [(set (match_dup 0)
1413 (unspec:HI
1414 [(compare:CCFP
1415 (match_dup 1)
1416 (match_op_dup 3 [(match_dup 2)]))]
1417 UNSPEC_FNSTSW))
1418 (set (reg:CC FLAGS_REG)
1419 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1420 ""
1421 [(set_attr "type" "multi")
1422 (set_attr "unit" "i387")
1423 (set_attr "fp_int_src" "true")
1424 (set_attr "mode" "<MODE>")])
1425
1426 ;; FP compares, step 2
1427 ;; Move the fpsw to ax.
1428
1429 (define_insn "x86_fnstsw_1"
1430 [(set (match_operand:HI 0 "register_operand" "=a")
1431 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1432 "TARGET_80387"
1433 "fnstsw\t%0"
1434 [(set (attr "length")
1435 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1436 (set_attr "mode" "SI")
1437 (set_attr "unit" "i387")])
1438
1439 ;; FP compares, step 3
1440 ;; Get ax into flags, general case.
1441
1442 (define_insn "x86_sahf_1"
1443 [(set (reg:CC FLAGS_REG)
1444 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1445 UNSPEC_SAHF))]
1446 "TARGET_SAHF"
1447 {
1448 #ifndef HAVE_AS_IX86_SAHF
1449 if (TARGET_64BIT)
1450 return ASM_BYTE "0x9e";
1451 else
1452 #endif
1453 return "sahf";
1454 }
1455 [(set_attr "length" "1")
1456 (set_attr "athlon_decode" "vector")
1457 (set_attr "amdfam10_decode" "direct")
1458 (set_attr "bdver1_decode" "direct")
1459 (set_attr "mode" "SI")])
1460
1461 ;; Pentium Pro can do steps 1 through 3 in one go.
1462 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1463 ;; (these i387 instructions set flags directly)
1464 (define_insn "*cmpfp_i_mixed"
1465 [(set (reg:CCFP FLAGS_REG)
1466 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1467 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1468 "TARGET_MIX_SSE_I387
1469 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1470 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1471 "* return output_fp_compare (insn, operands, true, false);"
1472 [(set_attr "type" "fcmp,ssecomi")
1473 (set_attr "prefix" "orig,maybe_vex")
1474 (set (attr "mode")
1475 (if_then_else (match_operand:SF 1)
1476 (const_string "SF")
1477 (const_string "DF")))
1478 (set (attr "prefix_rep")
1479 (if_then_else (eq_attr "type" "ssecomi")
1480 (const_string "0")
1481 (const_string "*")))
1482 (set (attr "prefix_data16")
1483 (cond [(eq_attr "type" "fcmp")
1484 (const_string "*")
1485 (eq_attr "mode" "DF")
1486 (const_string "1")
1487 ]
1488 (const_string "0")))
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "direct")
1491 (set_attr "bdver1_decode" "double")])
1492
1493 (define_insn "*cmpfp_i_sse"
1494 [(set (reg:CCFP FLAGS_REG)
1495 (compare:CCFP (match_operand 0 "register_operand" "x")
1496 (match_operand 1 "nonimmediate_operand" "xm")))]
1497 "TARGET_SSE_MATH
1498 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1499 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1500 "* return output_fp_compare (insn, operands, true, false);"
1501 [(set_attr "type" "ssecomi")
1502 (set_attr "prefix" "maybe_vex")
1503 (set (attr "mode")
1504 (if_then_else (match_operand:SF 1)
1505 (const_string "SF")
1506 (const_string "DF")))
1507 (set_attr "prefix_rep" "0")
1508 (set (attr "prefix_data16")
1509 (if_then_else (eq_attr "mode" "DF")
1510 (const_string "1")
1511 (const_string "0")))
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")
1514 (set_attr "bdver1_decode" "double")])
1515
1516 (define_insn "*cmpfp_i_i387"
1517 [(set (reg:CCFP FLAGS_REG)
1518 (compare:CCFP (match_operand 0 "register_operand" "f")
1519 (match_operand 1 "register_operand" "f")))]
1520 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1521 && TARGET_CMOVE
1522 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1523 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1524 "* return output_fp_compare (insn, operands, true, false);"
1525 [(set_attr "type" "fcmp")
1526 (set (attr "mode")
1527 (cond [(match_operand:SF 1)
1528 (const_string "SF")
1529 (match_operand:DF 1)
1530 (const_string "DF")
1531 ]
1532 (const_string "XF")))
1533 (set_attr "athlon_decode" "vector")
1534 (set_attr "amdfam10_decode" "direct")
1535 (set_attr "bdver1_decode" "double")])
1536
1537 (define_insn "*cmpfp_iu_mixed"
1538 [(set (reg:CCFPU FLAGS_REG)
1539 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1540 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1541 "TARGET_MIX_SSE_I387
1542 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1543 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1544 "* return output_fp_compare (insn, operands, true, true);"
1545 [(set_attr "type" "fcmp,ssecomi")
1546 (set_attr "prefix" "orig,maybe_vex")
1547 (set (attr "mode")
1548 (if_then_else (match_operand:SF 1)
1549 (const_string "SF")
1550 (const_string "DF")))
1551 (set (attr "prefix_rep")
1552 (if_then_else (eq_attr "type" "ssecomi")
1553 (const_string "0")
1554 (const_string "*")))
1555 (set (attr "prefix_data16")
1556 (cond [(eq_attr "type" "fcmp")
1557 (const_string "*")
1558 (eq_attr "mode" "DF")
1559 (const_string "1")
1560 ]
1561 (const_string "0")))
1562 (set_attr "athlon_decode" "vector")
1563 (set_attr "amdfam10_decode" "direct")
1564 (set_attr "bdver1_decode" "double")])
1565
1566 (define_insn "*cmpfp_iu_sse"
1567 [(set (reg:CCFPU FLAGS_REG)
1568 (compare:CCFPU (match_operand 0 "register_operand" "x")
1569 (match_operand 1 "nonimmediate_operand" "xm")))]
1570 "TARGET_SSE_MATH
1571 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1572 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1573 "* return output_fp_compare (insn, operands, true, true);"
1574 [(set_attr "type" "ssecomi")
1575 (set_attr "prefix" "maybe_vex")
1576 (set (attr "mode")
1577 (if_then_else (match_operand:SF 1)
1578 (const_string "SF")
1579 (const_string "DF")))
1580 (set_attr "prefix_rep" "0")
1581 (set (attr "prefix_data16")
1582 (if_then_else (eq_attr "mode" "DF")
1583 (const_string "1")
1584 (const_string "0")))
1585 (set_attr "athlon_decode" "vector")
1586 (set_attr "amdfam10_decode" "direct")
1587 (set_attr "bdver1_decode" "double")])
1588
1589 (define_insn "*cmpfp_iu_387"
1590 [(set (reg:CCFPU FLAGS_REG)
1591 (compare:CCFPU (match_operand 0 "register_operand" "f")
1592 (match_operand 1 "register_operand" "f")))]
1593 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1594 && TARGET_CMOVE
1595 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1596 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1597 "* return output_fp_compare (insn, operands, true, true);"
1598 [(set_attr "type" "fcmp")
1599 (set (attr "mode")
1600 (cond [(match_operand:SF 1)
1601 (const_string "SF")
1602 (match_operand:DF 1)
1603 (const_string "DF")
1604 ]
1605 (const_string "XF")))
1606 (set_attr "athlon_decode" "vector")
1607 (set_attr "amdfam10_decode" "direct")
1608 (set_attr "bdver1_decode" "direct")])
1609 \f
1610 ;; Push/pop instructions.
1611
1612 (define_insn "*push<mode>2"
1613 [(set (match_operand:DWI 0 "push_operand" "=<")
1614 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1615 ""
1616 "#"
1617 [(set_attr "type" "multi")
1618 (set_attr "mode" "<MODE>")])
1619
1620 (define_split
1621 [(set (match_operand:TI 0 "push_operand")
1622 (match_operand:TI 1 "general_operand"))]
1623 "TARGET_64BIT && reload_completed
1624 && !SSE_REG_P (operands[1])"
1625 [(const_int 0)]
1626 "ix86_split_long_move (operands); DONE;")
1627
1628 (define_insn "*pushdi2_rex64"
1629 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1630 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1631 "TARGET_64BIT"
1632 "@
1633 push{q}\t%1
1634 #"
1635 [(set_attr "type" "push,multi")
1636 (set_attr "mode" "DI")])
1637
1638 ;; Convert impossible pushes of immediate to existing instructions.
1639 ;; First try to get scratch register and go through it. In case this
1640 ;; fails, push sign extended lower part first and then overwrite
1641 ;; upper part by 32bit move.
1642 (define_peephole2
1643 [(match_scratch:DI 2 "r")
1644 (set (match_operand:DI 0 "push_operand")
1645 (match_operand:DI 1 "immediate_operand"))]
1646 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1647 && !x86_64_immediate_operand (operands[1], DImode)"
1648 [(set (match_dup 2) (match_dup 1))
1649 (set (match_dup 0) (match_dup 2))])
1650
1651 ;; We need to define this as both peepholer and splitter for case
1652 ;; peephole2 pass is not run.
1653 ;; "&& 1" is needed to keep it from matching the previous pattern.
1654 (define_peephole2
1655 [(set (match_operand:DI 0 "push_operand")
1656 (match_operand:DI 1 "immediate_operand"))]
1657 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1658 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1659 [(set (match_dup 0) (match_dup 1))
1660 (set (match_dup 2) (match_dup 3))]
1661 {
1662 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1663
1664 operands[1] = gen_lowpart (DImode, operands[2]);
1665 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1666 GEN_INT (4)));
1667 })
1668
1669 (define_split
1670 [(set (match_operand:DI 0 "push_operand")
1671 (match_operand:DI 1 "immediate_operand"))]
1672 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1673 ? epilogue_completed : reload_completed)
1674 && !symbolic_operand (operands[1], DImode)
1675 && !x86_64_immediate_operand (operands[1], DImode)"
1676 [(set (match_dup 0) (match_dup 1))
1677 (set (match_dup 2) (match_dup 3))]
1678 {
1679 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1680
1681 operands[1] = gen_lowpart (DImode, operands[2]);
1682 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1683 GEN_INT (4)));
1684 })
1685
1686 (define_split
1687 [(set (match_operand:DI 0 "push_operand")
1688 (match_operand:DI 1 "general_operand"))]
1689 "!TARGET_64BIT && reload_completed
1690 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1691 [(const_int 0)]
1692 "ix86_split_long_move (operands); DONE;")
1693
1694 (define_insn "*pushsi2"
1695 [(set (match_operand:SI 0 "push_operand" "=<")
1696 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1697 "!TARGET_64BIT"
1698 "push{l}\t%1"
1699 [(set_attr "type" "push")
1700 (set_attr "mode" "SI")])
1701
1702 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1703 ;; "push a byte/word". But actually we use pushl, which has the effect
1704 ;; of rounding the amount pushed up to a word.
1705
1706 ;; For TARGET_64BIT we always round up to 8 bytes.
1707 (define_insn "*push<mode>2_rex64"
1708 [(set (match_operand:SWI124 0 "push_operand" "=X")
1709 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1710 "TARGET_64BIT"
1711 "push{q}\t%q1"
1712 [(set_attr "type" "push")
1713 (set_attr "mode" "DI")])
1714
1715 (define_insn "*push<mode>2"
1716 [(set (match_operand:SWI12 0 "push_operand" "=X")
1717 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1718 "!TARGET_64BIT"
1719 "push{l}\t%k1"
1720 [(set_attr "type" "push")
1721 (set_attr "mode" "SI")])
1722
1723 (define_insn "*push<mode>2_prologue"
1724 [(set (match_operand:W 0 "push_operand" "=<")
1725 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1726 (clobber (mem:BLK (scratch)))]
1727 ""
1728 "push{<imodesuffix>}\t%1"
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "<MODE>")])
1731
1732 (define_insn "*pop<mode>1"
1733 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1734 (match_operand:W 1 "pop_operand" ">"))]
1735 ""
1736 "pop{<imodesuffix>}\t%0"
1737 [(set_attr "type" "pop")
1738 (set_attr "mode" "<MODE>")])
1739
1740 (define_insn "*pop<mode>1_epilogue"
1741 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1742 (match_operand:W 1 "pop_operand" ">"))
1743 (clobber (mem:BLK (scratch)))]
1744 ""
1745 "pop{<imodesuffix>}\t%0"
1746 [(set_attr "type" "pop")
1747 (set_attr "mode" "<MODE>")])
1748 \f
1749 ;; Move instructions.
1750
1751 (define_expand "movoi"
1752 [(set (match_operand:OI 0 "nonimmediate_operand")
1753 (match_operand:OI 1 "general_operand"))]
1754 "TARGET_AVX"
1755 "ix86_expand_move (OImode, operands); DONE;")
1756
1757 (define_expand "movti"
1758 [(set (match_operand:TI 0 "nonimmediate_operand")
1759 (match_operand:TI 1 "nonimmediate_operand"))]
1760 "TARGET_64BIT || TARGET_SSE"
1761 {
1762 if (TARGET_64BIT)
1763 ix86_expand_move (TImode, operands);
1764 else if (push_operand (operands[0], TImode))
1765 ix86_expand_push (TImode, operands[1]);
1766 else
1767 ix86_expand_vector_move (TImode, operands);
1768 DONE;
1769 })
1770
1771 ;; This expands to what emit_move_complex would generate if we didn't
1772 ;; have a movti pattern. Having this avoids problems with reload on
1773 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1774 ;; to have around all the time.
1775 (define_expand "movcdi"
1776 [(set (match_operand:CDI 0 "nonimmediate_operand")
1777 (match_operand:CDI 1 "general_operand"))]
1778 ""
1779 {
1780 if (push_operand (operands[0], CDImode))
1781 emit_move_complex_push (CDImode, operands[0], operands[1]);
1782 else
1783 emit_move_complex_parts (operands[0], operands[1]);
1784 DONE;
1785 })
1786
1787 (define_expand "mov<mode>"
1788 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1789 (match_operand:SWI1248x 1 "general_operand"))]
1790 ""
1791 "ix86_expand_move (<MODE>mode, operands); DONE;")
1792
1793 (define_insn "*mov<mode>_xor"
1794 [(set (match_operand:SWI48 0 "register_operand" "=r")
1795 (match_operand:SWI48 1 "const0_operand"))
1796 (clobber (reg:CC FLAGS_REG))]
1797 "reload_completed"
1798 "xor{l}\t%k0, %k0"
1799 [(set_attr "type" "alu1")
1800 (set_attr "mode" "SI")
1801 (set_attr "length_immediate" "0")])
1802
1803 (define_insn "*mov<mode>_or"
1804 [(set (match_operand:SWI48 0 "register_operand" "=r")
1805 (match_operand:SWI48 1 "const_int_operand"))
1806 (clobber (reg:CC FLAGS_REG))]
1807 "reload_completed
1808 && operands[1] == constm1_rtx"
1809 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1810 [(set_attr "type" "alu1")
1811 (set_attr "mode" "<MODE>")
1812 (set_attr "length_immediate" "1")])
1813
1814 (define_insn "*movoi_internal_avx"
1815 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1816 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1817 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1818 {
1819 switch (which_alternative)
1820 {
1821 case 0:
1822 return standard_sse_constant_opcode (insn, operands[1]);
1823 case 1:
1824 case 2:
1825 if (misaligned_operand (operands[0], OImode)
1826 || misaligned_operand (operands[1], OImode))
1827 {
1828 if (get_attr_mode (insn) == MODE_V8SF)
1829 return "vmovups\t{%1, %0|%0, %1}";
1830 else
1831 return "vmovdqu\t{%1, %0|%0, %1}";
1832 }
1833 else
1834 {
1835 if (get_attr_mode (insn) == MODE_V8SF)
1836 return "vmovaps\t{%1, %0|%0, %1}";
1837 else
1838 return "vmovdqa\t{%1, %0|%0, %1}";
1839 }
1840 default:
1841 gcc_unreachable ();
1842 }
1843 }
1844 [(set_attr "type" "sselog1,ssemov,ssemov")
1845 (set_attr "prefix" "vex")
1846 (set (attr "mode")
1847 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1848 (const_string "V8SF")
1849 (and (eq_attr "alternative" "2")
1850 (match_test "TARGET_SSE_TYPELESS_STORES"))
1851 (const_string "V8SF")
1852 ]
1853 (const_string "OI")))])
1854
1855 (define_insn "*movti_internal_rex64"
1856 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1857 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1858 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1859 {
1860 switch (which_alternative)
1861 {
1862 case 0:
1863 case 1:
1864 return "#";
1865 case 2:
1866 return standard_sse_constant_opcode (insn, operands[1]);
1867 case 3:
1868 case 4:
1869 /* TDmode values are passed as TImode on the stack. Moving them
1870 to stack may result in unaligned memory access. */
1871 if (misaligned_operand (operands[0], TImode)
1872 || misaligned_operand (operands[1], TImode))
1873 {
1874 if (get_attr_mode (insn) == MODE_V4SF)
1875 return "%vmovups\t{%1, %0|%0, %1}";
1876 else
1877 return "%vmovdqu\t{%1, %0|%0, %1}";
1878 }
1879 else
1880 {
1881 if (get_attr_mode (insn) == MODE_V4SF)
1882 return "%vmovaps\t{%1, %0|%0, %1}";
1883 else
1884 return "%vmovdqa\t{%1, %0|%0, %1}";
1885 }
1886 default:
1887 gcc_unreachable ();
1888 }
1889 }
1890 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1891 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1892 (set (attr "mode")
1893 (cond [(eq_attr "alternative" "0,1")
1894 (const_string "DI")
1895 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1896 (const_string "V4SF")
1897 (and (eq_attr "alternative" "4")
1898 (match_test "TARGET_SSE_TYPELESS_STORES"))
1899 (const_string "V4SF")
1900 (match_test "TARGET_AVX")
1901 (const_string "TI")
1902 (match_test "optimize_function_for_size_p (cfun)")
1903 (const_string "V4SF")
1904 ]
1905 (const_string "TI")))])
1906
1907 (define_split
1908 [(set (match_operand:TI 0 "nonimmediate_operand")
1909 (match_operand:TI 1 "general_operand"))]
1910 "reload_completed
1911 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1912 [(const_int 0)]
1913 "ix86_split_long_move (operands); DONE;")
1914
1915 (define_insn "*movti_internal_sse"
1916 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1917 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1918 "TARGET_SSE && !TARGET_64BIT
1919 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1920 {
1921 switch (which_alternative)
1922 {
1923 case 0:
1924 return standard_sse_constant_opcode (insn, operands[1]);
1925 case 1:
1926 case 2:
1927 /* TDmode values are passed as TImode on the stack. Moving them
1928 to stack may result in unaligned memory access. */
1929 if (misaligned_operand (operands[0], TImode)
1930 || misaligned_operand (operands[1], TImode))
1931 {
1932 if (get_attr_mode (insn) == MODE_V4SF)
1933 return "%vmovups\t{%1, %0|%0, %1}";
1934 else
1935 return "%vmovdqu\t{%1, %0|%0, %1}";
1936 }
1937 else
1938 {
1939 if (get_attr_mode (insn) == MODE_V4SF)
1940 return "%vmovaps\t{%1, %0|%0, %1}";
1941 else
1942 return "%vmovdqa\t{%1, %0|%0, %1}";
1943 }
1944 default:
1945 gcc_unreachable ();
1946 }
1947 }
1948 [(set_attr "type" "sselog1,ssemov,ssemov")
1949 (set_attr "prefix" "maybe_vex")
1950 (set (attr "mode")
1951 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1952 (const_string "V4SF")
1953 (and (eq_attr "alternative" "2")
1954 (match_test "TARGET_SSE_TYPELESS_STORES"))
1955 (const_string "V4SF")
1956 (match_test "TARGET_AVX")
1957 (const_string "TI")
1958 (ior (not (match_test "TARGET_SSE2"))
1959 (match_test "optimize_function_for_size_p (cfun)"))
1960 (const_string "V4SF")
1961 ]
1962 (const_string "TI")))])
1963
1964 (define_insn "*movdi_internal_rex64"
1965 [(set (match_operand:DI 0 "nonimmediate_operand"
1966 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1967 (match_operand:DI 1 "general_operand"
1968 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1969 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1970 {
1971 switch (get_attr_type (insn))
1972 {
1973 case TYPE_SSECVT:
1974 if (SSE_REG_P (operands[0]))
1975 return "movq2dq\t{%1, %0|%0, %1}";
1976 else
1977 return "movdq2q\t{%1, %0|%0, %1}";
1978
1979 case TYPE_SSEMOV:
1980 if (get_attr_mode (insn) == MODE_V4SF)
1981 return "%vmovaps\t{%1, %0|%0, %1}";
1982 else if (get_attr_mode (insn) == MODE_TI)
1983 return "%vmovdqa\t{%1, %0|%0, %1}";
1984
1985 /* Handle broken assemblers that require movd instead of movq. */
1986 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1987 return "%vmovd\t{%1, %0|%0, %1}";
1988 else
1989 return "%vmovq\t{%1, %0|%0, %1}";
1990
1991 case TYPE_MMXMOV:
1992 /* Handle broken assemblers that require movd instead of movq. */
1993 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1994 return "movd\t{%1, %0|%0, %1}";
1995 else
1996 return "movq\t{%1, %0|%0, %1}";
1997
1998 case TYPE_SSELOG1:
1999 return standard_sse_constant_opcode (insn, operands[1]);
2000
2001 case TYPE_MMX:
2002 return "pxor\t%0, %0";
2003
2004 case TYPE_MULTI:
2005 return "#";
2006
2007 case TYPE_LEA:
2008 return "lea{q}\t{%E1, %0|%0, %E1}";
2009
2010 default:
2011 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2012 if (get_attr_mode (insn) == MODE_SI)
2013 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2014 else if (which_alternative == 2)
2015 return "movabs{q}\t{%1, %0|%0, %1}";
2016 else if (ix86_use_lea_for_mov (insn, operands))
2017 return "lea{q}\t{%E1, %0|%0, %E1}";
2018 else
2019 return "mov{q}\t{%1, %0|%0, %1}";
2020 }
2021 }
2022 [(set (attr "type")
2023 (cond [(eq_attr "alternative" "4")
2024 (const_string "multi")
2025 (eq_attr "alternative" "5")
2026 (const_string "mmx")
2027 (eq_attr "alternative" "6,7,8,9")
2028 (const_string "mmxmov")
2029 (eq_attr "alternative" "10")
2030 (const_string "sselog1")
2031 (eq_attr "alternative" "11,12,13,14,15")
2032 (const_string "ssemov")
2033 (eq_attr "alternative" "16,17")
2034 (const_string "ssecvt")
2035 (match_operand 1 "pic_32bit_operand")
2036 (const_string "lea")
2037 ]
2038 (const_string "imov")))
2039 (set (attr "modrm")
2040 (if_then_else
2041 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2042 (const_string "0")
2043 (const_string "*")))
2044 (set (attr "length_immediate")
2045 (if_then_else
2046 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2047 (const_string "8")
2048 (const_string "*")))
2049 (set (attr "prefix_rex")
2050 (if_then_else (eq_attr "alternative" "8,9")
2051 (const_string "1")
2052 (const_string "*")))
2053 (set (attr "prefix_data16")
2054 (if_then_else (eq_attr "alternative" "11")
2055 (const_string "1")
2056 (const_string "*")))
2057 (set (attr "prefix")
2058 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2059 (const_string "maybe_vex")
2060 (const_string "orig")))
2061 (set (attr "mode")
2062 (cond [(eq_attr "alternative" "0,4")
2063 (const_string "SI")
2064 (eq_attr "alternative" "10,12")
2065 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2066 (const_string "V4SF")
2067 (match_test "TARGET_AVX")
2068 (const_string "TI")
2069 (match_test "optimize_function_for_size_p (cfun)")
2070 (const_string "V4SF")
2071 ]
2072 (const_string "TI"))
2073 ]
2074 (const_string "DI")))])
2075
2076 ;; Reload patterns to support multi-word load/store
2077 ;; with non-offsetable address.
2078 (define_expand "reload_noff_store"
2079 [(parallel [(match_operand 0 "memory_operand" "=m")
2080 (match_operand 1 "register_operand" "r")
2081 (match_operand:DI 2 "register_operand" "=&r")])]
2082 "TARGET_64BIT"
2083 {
2084 rtx mem = operands[0];
2085 rtx addr = XEXP (mem, 0);
2086
2087 emit_move_insn (operands[2], addr);
2088 mem = replace_equiv_address_nv (mem, operands[2]);
2089
2090 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2091 DONE;
2092 })
2093
2094 (define_expand "reload_noff_load"
2095 [(parallel [(match_operand 0 "register_operand" "=r")
2096 (match_operand 1 "memory_operand" "m")
2097 (match_operand:DI 2 "register_operand" "=r")])]
2098 "TARGET_64BIT"
2099 {
2100 rtx mem = operands[1];
2101 rtx addr = XEXP (mem, 0);
2102
2103 emit_move_insn (operands[2], addr);
2104 mem = replace_equiv_address_nv (mem, operands[2]);
2105
2106 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2107 DONE;
2108 })
2109
2110 ;; Convert impossible stores of immediate to existing instructions.
2111 ;; First try to get scratch register and go through it. In case this
2112 ;; fails, move by 32bit parts.
2113 (define_peephole2
2114 [(match_scratch:DI 2 "r")
2115 (set (match_operand:DI 0 "memory_operand")
2116 (match_operand:DI 1 "immediate_operand"))]
2117 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118 && !x86_64_immediate_operand (operands[1], DImode)"
2119 [(set (match_dup 2) (match_dup 1))
2120 (set (match_dup 0) (match_dup 2))])
2121
2122 ;; We need to define this as both peepholer and splitter for case
2123 ;; peephole2 pass is not run.
2124 ;; "&& 1" is needed to keep it from matching the previous pattern.
2125 (define_peephole2
2126 [(set (match_operand:DI 0 "memory_operand")
2127 (match_operand:DI 1 "immediate_operand"))]
2128 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2129 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2130 [(set (match_dup 2) (match_dup 3))
2131 (set (match_dup 4) (match_dup 5))]
2132 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2133
2134 (define_split
2135 [(set (match_operand:DI 0 "memory_operand")
2136 (match_operand:DI 1 "immediate_operand"))]
2137 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2138 ? epilogue_completed : reload_completed)
2139 && !symbolic_operand (operands[1], DImode)
2140 && !x86_64_immediate_operand (operands[1], DImode)"
2141 [(set (match_dup 2) (match_dup 3))
2142 (set (match_dup 4) (match_dup 5))]
2143 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2144
2145 (define_insn "*movdi_internal"
2146 [(set (match_operand:DI 0 "nonimmediate_operand"
2147 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2148 (match_operand:DI 1 "general_operand"
2149 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2150 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2151 {
2152 switch (get_attr_type (insn))
2153 {
2154 case TYPE_SSECVT:
2155 if (SSE_REG_P (operands[0]))
2156 return "movq2dq\t{%1, %0|%0, %1}";
2157 else
2158 return "movdq2q\t{%1, %0|%0, %1}";
2159
2160 case TYPE_SSEMOV:
2161 switch (get_attr_mode (insn))
2162 {
2163 case MODE_TI:
2164 return "%vmovdqa\t{%1, %0|%0, %1}";
2165 case MODE_DI:
2166 return "%vmovq\t{%1, %0|%0, %1}";
2167 case MODE_V4SF:
2168 return "%vmovaps\t{%1, %0|%0, %1}";
2169 case MODE_V2SF:
2170 return "movlps\t{%1, %0|%0, %1}";
2171 default:
2172 gcc_unreachable ();
2173 }
2174
2175 case TYPE_MMXMOV:
2176 return "movq\t{%1, %0|%0, %1}";
2177
2178 case TYPE_SSELOG1:
2179 return standard_sse_constant_opcode (insn, operands[1]);
2180
2181 case TYPE_MMX:
2182 return "pxor\t%0, %0";
2183
2184 case TYPE_MULTI:
2185 return "#";
2186
2187 default:
2188 gcc_unreachable ();
2189 }
2190 }
2191 [(set (attr "isa")
2192 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2193 (const_string "sse2")
2194 (eq_attr "alternative" "9,10,11,12")
2195 (const_string "noavx")
2196 ]
2197 (const_string "*")))
2198 (set (attr "type")
2199 (cond [(eq_attr "alternative" "0,1")
2200 (const_string "multi")
2201 (eq_attr "alternative" "2")
2202 (const_string "mmx")
2203 (eq_attr "alternative" "3,4")
2204 (const_string "mmxmov")
2205 (eq_attr "alternative" "5,9")
2206 (const_string "sselog1")
2207 (eq_attr "alternative" "13,14")
2208 (const_string "ssecvt")
2209 ]
2210 (const_string "ssemov")))
2211 (set (attr "prefix")
2212 (if_then_else (eq_attr "alternative" "5,6,7,8")
2213 (const_string "maybe_vex")
2214 (const_string "orig")))
2215 (set (attr "mode")
2216 (cond [(eq_attr "alternative" "9,11")
2217 (const_string "V4SF")
2218 (eq_attr "alternative" "10,12")
2219 (const_string "V2SF")
2220 (eq_attr "alternative" "5,7")
2221 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2222 (const_string "V4SF")
2223 (match_test "TARGET_AVX")
2224 (const_string "TI")
2225 (match_test "optimize_function_for_size_p (cfun)")
2226 (const_string "V4SF")
2227 ]
2228 (const_string "TI"))
2229 ]
2230 (const_string "DI")))])
2231
2232 (define_split
2233 [(set (match_operand:DI 0 "nonimmediate_operand")
2234 (match_operand:DI 1 "general_operand"))]
2235 "!TARGET_64BIT && reload_completed
2236 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2237 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2238 [(const_int 0)]
2239 "ix86_split_long_move (operands); DONE;")
2240
2241 (define_insn "*movsi_internal"
2242 [(set (match_operand:SI 0 "nonimmediate_operand"
2243 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2244 (match_operand:SI 1 "general_operand"
2245 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2246 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2247 {
2248 switch (get_attr_type (insn))
2249 {
2250 case TYPE_SSELOG1:
2251 return standard_sse_constant_opcode (insn, operands[1]);
2252
2253 case TYPE_SSEMOV:
2254 switch (get_attr_mode (insn))
2255 {
2256 case MODE_TI:
2257 return "%vmovdqa\t{%1, %0|%0, %1}";
2258 case MODE_V4SF:
2259 return "%vmovaps\t{%1, %0|%0, %1}";
2260 case MODE_SI:
2261 return "%vmovd\t{%1, %0|%0, %1}";
2262 case MODE_SF:
2263 return "%vmovss\t{%1, %0|%0, %1}";
2264 default:
2265 gcc_unreachable ();
2266 }
2267
2268 case TYPE_MMX:
2269 return "pxor\t%0, %0";
2270
2271 case TYPE_MMXMOV:
2272 if (get_attr_mode (insn) == MODE_DI)
2273 return "movq\t{%1, %0|%0, %1}";
2274 return "movd\t{%1, %0|%0, %1}";
2275
2276 case TYPE_LEA:
2277 return "lea{l}\t{%E1, %0|%0, %E1}";
2278
2279 default:
2280 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2281 if (ix86_use_lea_for_mov (insn, operands))
2282 return "lea{l}\t{%E1, %0|%0, %E1}";
2283 else
2284 return "mov{l}\t{%1, %0|%0, %1}";
2285 }
2286 }
2287 [(set (attr "type")
2288 (cond [(eq_attr "alternative" "2")
2289 (const_string "mmx")
2290 (eq_attr "alternative" "3,4,5")
2291 (const_string "mmxmov")
2292 (eq_attr "alternative" "6")
2293 (const_string "sselog1")
2294 (eq_attr "alternative" "7,8,9,10,11")
2295 (const_string "ssemov")
2296 (match_operand 1 "pic_32bit_operand")
2297 (const_string "lea")
2298 ]
2299 (const_string "imov")))
2300 (set (attr "prefix")
2301 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2302 (const_string "orig")
2303 (const_string "maybe_vex")))
2304 (set (attr "prefix_data16")
2305 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2306 (const_string "1")
2307 (const_string "*")))
2308 (set (attr "mode")
2309 (cond [(eq_attr "alternative" "2,3")
2310 (const_string "DI")
2311 (eq_attr "alternative" "6,7")
2312 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2313 (const_string "V4SF")
2314 (match_test "TARGET_AVX")
2315 (const_string "TI")
2316 (ior (not (match_test "TARGET_SSE2"))
2317 (match_test "optimize_function_for_size_p (cfun)"))
2318 (const_string "V4SF")
2319 ]
2320 (const_string "TI"))
2321 (and (eq_attr "alternative" "8,9,10,11")
2322 (not (match_test "TARGET_SSE2")))
2323 (const_string "SF")
2324 ]
2325 (const_string "SI")))])
2326
2327 (define_insn "*movhi_internal"
2328 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2329 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2330 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2331 {
2332 switch (get_attr_type (insn))
2333 {
2334 case TYPE_IMOVX:
2335 /* movzwl is faster than movw on p2 due to partial word stalls,
2336 though not as fast as an aligned movl. */
2337 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2338 default:
2339 if (get_attr_mode (insn) == MODE_SI)
2340 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2341 else
2342 return "mov{w}\t{%1, %0|%0, %1}";
2343 }
2344 }
2345 [(set (attr "type")
2346 (cond [(match_test "optimize_function_for_size_p (cfun)")
2347 (const_string "imov")
2348 (and (eq_attr "alternative" "0")
2349 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2350 (not (match_test "TARGET_HIMODE_MATH"))))
2351 (const_string "imov")
2352 (and (eq_attr "alternative" "1,2")
2353 (match_operand:HI 1 "aligned_operand"))
2354 (const_string "imov")
2355 (and (match_test "TARGET_MOVX")
2356 (eq_attr "alternative" "0,2"))
2357 (const_string "imovx")
2358 ]
2359 (const_string "imov")))
2360 (set (attr "mode")
2361 (cond [(eq_attr "type" "imovx")
2362 (const_string "SI")
2363 (and (eq_attr "alternative" "1,2")
2364 (match_operand:HI 1 "aligned_operand"))
2365 (const_string "SI")
2366 (and (eq_attr "alternative" "0")
2367 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2368 (not (match_test "TARGET_HIMODE_MATH"))))
2369 (const_string "SI")
2370 ]
2371 (const_string "HI")))])
2372
2373 ;; Situation is quite tricky about when to choose full sized (SImode) move
2374 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2375 ;; partial register dependency machines (such as AMD Athlon), where QImode
2376 ;; moves issue extra dependency and for partial register stalls machines
2377 ;; that don't use QImode patterns (and QImode move cause stall on the next
2378 ;; instruction).
2379 ;;
2380 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2381 ;; register stall machines with, where we use QImode instructions, since
2382 ;; partial register stall can be caused there. Then we use movzx.
2383 (define_insn "*movqi_internal"
2384 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2385 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2386 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2387 {
2388 switch (get_attr_type (insn))
2389 {
2390 case TYPE_IMOVX:
2391 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2392 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2393 default:
2394 if (get_attr_mode (insn) == MODE_SI)
2395 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2396 else
2397 return "mov{b}\t{%1, %0|%0, %1}";
2398 }
2399 }
2400 [(set (attr "type")
2401 (cond [(and (eq_attr "alternative" "5")
2402 (not (match_operand:QI 1 "aligned_operand")))
2403 (const_string "imovx")
2404 (match_test "optimize_function_for_size_p (cfun)")
2405 (const_string "imov")
2406 (and (eq_attr "alternative" "3")
2407 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2408 (not (match_test "TARGET_QIMODE_MATH"))))
2409 (const_string "imov")
2410 (eq_attr "alternative" "3,5")
2411 (const_string "imovx")
2412 (and (match_test "TARGET_MOVX")
2413 (eq_attr "alternative" "2"))
2414 (const_string "imovx")
2415 ]
2416 (const_string "imov")))
2417 (set (attr "mode")
2418 (cond [(eq_attr "alternative" "3,4,5")
2419 (const_string "SI")
2420 (eq_attr "alternative" "6")
2421 (const_string "QI")
2422 (eq_attr "type" "imovx")
2423 (const_string "SI")
2424 (and (eq_attr "type" "imov")
2425 (and (eq_attr "alternative" "0,1")
2426 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2427 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2428 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2429 (const_string "SI")
2430 ;; Avoid partial register stalls when not using QImode arithmetic
2431 (and (eq_attr "type" "imov")
2432 (and (eq_attr "alternative" "0,1")
2433 (and (match_test "TARGET_PARTIAL_REG_STALL")
2434 (not (match_test "TARGET_QIMODE_MATH")))))
2435 (const_string "SI")
2436 ]
2437 (const_string "QI")))])
2438
2439 ;; Stores and loads of ax to arbitrary constant address.
2440 ;; We fake an second form of instruction to force reload to load address
2441 ;; into register when rax is not available
2442 (define_insn "*movabs<mode>_1"
2443 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2444 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2445 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2446 "@
2447 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2448 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2449 [(set_attr "type" "imov")
2450 (set_attr "modrm" "0,*")
2451 (set_attr "length_address" "8,0")
2452 (set_attr "length_immediate" "0,*")
2453 (set_attr "memory" "store")
2454 (set_attr "mode" "<MODE>")])
2455
2456 (define_insn "*movabs<mode>_2"
2457 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2458 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2459 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2460 "@
2461 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2462 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2463 [(set_attr "type" "imov")
2464 (set_attr "modrm" "0,*")
2465 (set_attr "length_address" "8,0")
2466 (set_attr "length_immediate" "0")
2467 (set_attr "memory" "load")
2468 (set_attr "mode" "<MODE>")])
2469
2470 (define_insn "swap<mode>"
2471 [(set (match_operand:SWI48 0 "register_operand" "+r")
2472 (match_operand:SWI48 1 "register_operand" "+r"))
2473 (set (match_dup 1)
2474 (match_dup 0))]
2475 ""
2476 "xchg{<imodesuffix>}\t%1, %0"
2477 [(set_attr "type" "imov")
2478 (set_attr "mode" "<MODE>")
2479 (set_attr "pent_pair" "np")
2480 (set_attr "athlon_decode" "vector")
2481 (set_attr "amdfam10_decode" "double")
2482 (set_attr "bdver1_decode" "double")])
2483
2484 (define_insn "*swap<mode>_1"
2485 [(set (match_operand:SWI12 0 "register_operand" "+r")
2486 (match_operand:SWI12 1 "register_operand" "+r"))
2487 (set (match_dup 1)
2488 (match_dup 0))]
2489 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2490 "xchg{l}\t%k1, %k0"
2491 [(set_attr "type" "imov")
2492 (set_attr "mode" "SI")
2493 (set_attr "pent_pair" "np")
2494 (set_attr "athlon_decode" "vector")
2495 (set_attr "amdfam10_decode" "double")
2496 (set_attr "bdver1_decode" "double")])
2497
2498 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2499 ;; is disabled for AMDFAM10
2500 (define_insn "*swap<mode>_2"
2501 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2502 (match_operand:SWI12 1 "register_operand" "+<r>"))
2503 (set (match_dup 1)
2504 (match_dup 0))]
2505 "TARGET_PARTIAL_REG_STALL"
2506 "xchg{<imodesuffix>}\t%1, %0"
2507 [(set_attr "type" "imov")
2508 (set_attr "mode" "<MODE>")
2509 (set_attr "pent_pair" "np")
2510 (set_attr "athlon_decode" "vector")])
2511
2512 (define_expand "movstrict<mode>"
2513 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2514 (match_operand:SWI12 1 "general_operand"))]
2515 ""
2516 {
2517 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2518 FAIL;
2519 if (GET_CODE (operands[0]) == SUBREG
2520 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2521 FAIL;
2522 /* Don't generate memory->memory moves, go through a register */
2523 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2524 operands[1] = force_reg (<MODE>mode, operands[1]);
2525 })
2526
2527 (define_insn "*movstrict<mode>_1"
2528 [(set (strict_low_part
2529 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2530 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2531 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2532 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2533 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2534 [(set_attr "type" "imov")
2535 (set_attr "mode" "<MODE>")])
2536
2537 (define_insn "*movstrict<mode>_xor"
2538 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2539 (match_operand:SWI12 1 "const0_operand"))
2540 (clobber (reg:CC FLAGS_REG))]
2541 "reload_completed"
2542 "xor{<imodesuffix>}\t%0, %0"
2543 [(set_attr "type" "alu1")
2544 (set_attr "mode" "<MODE>")
2545 (set_attr "length_immediate" "0")])
2546
2547 (define_insn "*mov<mode>_extv_1"
2548 [(set (match_operand:SWI24 0 "register_operand" "=R")
2549 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2550 (const_int 8)
2551 (const_int 8)))]
2552 ""
2553 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2554 [(set_attr "type" "imovx")
2555 (set_attr "mode" "SI")])
2556
2557 (define_insn "*movqi_extv_1_rex64"
2558 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2559 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2560 (const_int 8)
2561 (const_int 8)))]
2562 "TARGET_64BIT"
2563 {
2564 switch (get_attr_type (insn))
2565 {
2566 case TYPE_IMOVX:
2567 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2568 default:
2569 return "mov{b}\t{%h1, %0|%0, %h1}";
2570 }
2571 }
2572 [(set (attr "type")
2573 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2574 (match_test "TARGET_MOVX"))
2575 (const_string "imovx")
2576 (const_string "imov")))
2577 (set (attr "mode")
2578 (if_then_else (eq_attr "type" "imovx")
2579 (const_string "SI")
2580 (const_string "QI")))])
2581
2582 (define_insn "*movqi_extv_1"
2583 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2584 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2585 (const_int 8)
2586 (const_int 8)))]
2587 "!TARGET_64BIT"
2588 {
2589 switch (get_attr_type (insn))
2590 {
2591 case TYPE_IMOVX:
2592 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2593 default:
2594 return "mov{b}\t{%h1, %0|%0, %h1}";
2595 }
2596 }
2597 [(set (attr "type")
2598 (if_then_else (and (match_operand:QI 0 "register_operand")
2599 (ior (not (match_operand:QI 0 "QIreg_operand"))
2600 (match_test "TARGET_MOVX")))
2601 (const_string "imovx")
2602 (const_string "imov")))
2603 (set (attr "mode")
2604 (if_then_else (eq_attr "type" "imovx")
2605 (const_string "SI")
2606 (const_string "QI")))])
2607
2608 (define_insn "*mov<mode>_extzv_1"
2609 [(set (match_operand:SWI48 0 "register_operand" "=R")
2610 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2611 (const_int 8)
2612 (const_int 8)))]
2613 ""
2614 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2615 [(set_attr "type" "imovx")
2616 (set_attr "mode" "SI")])
2617
2618 (define_insn "*movqi_extzv_2_rex64"
2619 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2620 (subreg:QI
2621 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2622 (const_int 8)
2623 (const_int 8)) 0))]
2624 "TARGET_64BIT"
2625 {
2626 switch (get_attr_type (insn))
2627 {
2628 case TYPE_IMOVX:
2629 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2630 default:
2631 return "mov{b}\t{%h1, %0|%0, %h1}";
2632 }
2633 }
2634 [(set (attr "type")
2635 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2636 (match_test "TARGET_MOVX"))
2637 (const_string "imovx")
2638 (const_string "imov")))
2639 (set (attr "mode")
2640 (if_then_else (eq_attr "type" "imovx")
2641 (const_string "SI")
2642 (const_string "QI")))])
2643
2644 (define_insn "*movqi_extzv_2"
2645 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2646 (subreg:QI
2647 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2648 (const_int 8)
2649 (const_int 8)) 0))]
2650 "!TARGET_64BIT"
2651 {
2652 switch (get_attr_type (insn))
2653 {
2654 case TYPE_IMOVX:
2655 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2656 default:
2657 return "mov{b}\t{%h1, %0|%0, %h1}";
2658 }
2659 }
2660 [(set (attr "type")
2661 (if_then_else (and (match_operand:QI 0 "register_operand")
2662 (ior (not (match_operand:QI 0 "QIreg_operand"))
2663 (match_test "TARGET_MOVX")))
2664 (const_string "imovx")
2665 (const_string "imov")))
2666 (set (attr "mode")
2667 (if_then_else (eq_attr "type" "imovx")
2668 (const_string "SI")
2669 (const_string "QI")))])
2670
2671 (define_expand "mov<mode>_insv_1"
2672 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2673 (const_int 8)
2674 (const_int 8))
2675 (match_operand:SWI48 1 "nonmemory_operand"))])
2676
2677 (define_insn "*mov<mode>_insv_1_rex64"
2678 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2679 (const_int 8)
2680 (const_int 8))
2681 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2682 "TARGET_64BIT"
2683 "mov{b}\t{%b1, %h0|%h0, %b1}"
2684 [(set_attr "type" "imov")
2685 (set_attr "mode" "QI")])
2686
2687 (define_insn "*movsi_insv_1"
2688 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2689 (const_int 8)
2690 (const_int 8))
2691 (match_operand:SI 1 "general_operand" "Qmn"))]
2692 "!TARGET_64BIT"
2693 "mov{b}\t{%b1, %h0|%h0, %b1}"
2694 [(set_attr "type" "imov")
2695 (set_attr "mode" "QI")])
2696
2697 (define_insn "*movqi_insv_2"
2698 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2699 (const_int 8)
2700 (const_int 8))
2701 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2702 (const_int 8)))]
2703 ""
2704 "mov{b}\t{%h1, %h0|%h0, %h1}"
2705 [(set_attr "type" "imov")
2706 (set_attr "mode" "QI")])
2707 \f
2708 ;; Floating point push instructions.
2709
2710 (define_insn "*pushtf"
2711 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2712 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2713 "TARGET_SSE"
2714 {
2715 /* This insn should be already split before reg-stack. */
2716 gcc_unreachable ();
2717 }
2718 [(set_attr "type" "multi")
2719 (set_attr "unit" "sse,*,*")
2720 (set_attr "mode" "TF,SI,SI")])
2721
2722 ;; %%% Kill this when call knows how to work this out.
2723 (define_split
2724 [(set (match_operand:TF 0 "push_operand")
2725 (match_operand:TF 1 "sse_reg_operand"))]
2726 "TARGET_SSE && reload_completed"
2727 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2728 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2729
2730 (define_insn "*pushxf"
2731 [(set (match_operand:XF 0 "push_operand" "=<,<")
2732 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2733 "optimize_function_for_speed_p (cfun)"
2734 {
2735 /* This insn should be already split before reg-stack. */
2736 gcc_unreachable ();
2737 }
2738 [(set_attr "type" "multi")
2739 (set_attr "unit" "i387,*")
2740 (set_attr "mode" "XF,SI")])
2741
2742 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2743 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2744 ;; Pushing using integer instructions is longer except for constants
2745 ;; and direct memory references (assuming that any given constant is pushed
2746 ;; only once, but this ought to be handled elsewhere).
2747
2748 (define_insn "*pushxf_nointeger"
2749 [(set (match_operand:XF 0 "push_operand" "=<,<")
2750 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2751 "optimize_function_for_size_p (cfun)"
2752 {
2753 /* This insn should be already split before reg-stack. */
2754 gcc_unreachable ();
2755 }
2756 [(set_attr "type" "multi")
2757 (set_attr "unit" "i387,*")
2758 (set_attr "mode" "XF,SI")])
2759
2760 ;; %%% Kill this when call knows how to work this out.
2761 (define_split
2762 [(set (match_operand:XF 0 "push_operand")
2763 (match_operand:XF 1 "fp_register_operand"))]
2764 "reload_completed"
2765 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2766 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2767 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2768
2769 (define_insn "*pushdf_rex64"
2770 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2771 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2772 "TARGET_64BIT"
2773 {
2774 /* This insn should be already split before reg-stack. */
2775 gcc_unreachable ();
2776 }
2777 [(set_attr "type" "multi")
2778 (set_attr "unit" "i387,*,*")
2779 (set_attr "mode" "DF,DI,DF")])
2780
2781 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2782 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2783 ;; On the average, pushdf using integers can be still shorter.
2784
2785 (define_insn "*pushdf"
2786 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2787 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2788 "!TARGET_64BIT"
2789 {
2790 /* This insn should be already split before reg-stack. */
2791 gcc_unreachable ();
2792 }
2793 [(set_attr "isa" "*,*,sse2")
2794 (set_attr "type" "multi")
2795 (set_attr "unit" "i387,*,*")
2796 (set_attr "mode" "DF,DI,DF")])
2797
2798 ;; %%% Kill this when call knows how to work this out.
2799 (define_split
2800 [(set (match_operand:DF 0 "push_operand")
2801 (match_operand:DF 1 "any_fp_register_operand"))]
2802 "reload_completed"
2803 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2804 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2805
2806 (define_insn "*pushsf_rex64"
2807 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2808 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2809 "TARGET_64BIT"
2810 {
2811 /* Anything else should be already split before reg-stack. */
2812 gcc_assert (which_alternative == 1);
2813 return "push{q}\t%q1";
2814 }
2815 [(set_attr "type" "multi,push,multi")
2816 (set_attr "unit" "i387,*,*")
2817 (set_attr "mode" "SF,DI,SF")])
2818
2819 (define_insn "*pushsf"
2820 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2821 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2822 "!TARGET_64BIT"
2823 {
2824 /* Anything else should be already split before reg-stack. */
2825 gcc_assert (which_alternative == 1);
2826 return "push{l}\t%1";
2827 }
2828 [(set_attr "type" "multi,push,multi")
2829 (set_attr "unit" "i387,*,*")
2830 (set_attr "mode" "SF,SI,SF")])
2831
2832 ;; %%% Kill this when call knows how to work this out.
2833 (define_split
2834 [(set (match_operand:SF 0 "push_operand")
2835 (match_operand:SF 1 "any_fp_register_operand"))]
2836 "reload_completed"
2837 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2838 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2839 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2840
2841 (define_split
2842 [(set (match_operand:SF 0 "push_operand")
2843 (match_operand:SF 1 "memory_operand"))]
2844 "reload_completed
2845 && (operands[2] = find_constant_src (insn))"
2846 [(set (match_dup 0) (match_dup 2))])
2847
2848 (define_split
2849 [(set (match_operand 0 "push_operand")
2850 (match_operand 1 "general_operand"))]
2851 "reload_completed
2852 && (GET_MODE (operands[0]) == TFmode
2853 || GET_MODE (operands[0]) == XFmode
2854 || GET_MODE (operands[0]) == DFmode)
2855 && !ANY_FP_REG_P (operands[1])"
2856 [(const_int 0)]
2857 "ix86_split_long_move (operands); DONE;")
2858 \f
2859 ;; Floating point move instructions.
2860
2861 (define_expand "movtf"
2862 [(set (match_operand:TF 0 "nonimmediate_operand")
2863 (match_operand:TF 1 "nonimmediate_operand"))]
2864 "TARGET_SSE"
2865 {
2866 ix86_expand_move (TFmode, operands);
2867 DONE;
2868 })
2869
2870 (define_expand "mov<mode>"
2871 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2872 (match_operand:X87MODEF 1 "general_operand"))]
2873 ""
2874 "ix86_expand_move (<MODE>mode, operands); DONE;")
2875
2876 (define_insn "*movtf_internal"
2877 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2878 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2879 "TARGET_SSE
2880 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2881 && (!can_create_pseudo_p ()
2882 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2883 || GET_CODE (operands[1]) != CONST_DOUBLE
2884 || (optimize_function_for_size_p (cfun)
2885 && standard_sse_constant_p (operands[1])
2886 && !memory_operand (operands[0], TFmode))
2887 || (!TARGET_MEMORY_MISMATCH_STALL
2888 && memory_operand (operands[0], TFmode)))"
2889 {
2890 switch (which_alternative)
2891 {
2892 case 0:
2893 return standard_sse_constant_opcode (insn, operands[1]);
2894 case 1:
2895 case 2:
2896 /* Handle misaligned load/store since we
2897 don't have movmisaligntf pattern. */
2898 if (misaligned_operand (operands[0], TFmode)
2899 || misaligned_operand (operands[1], TFmode))
2900 {
2901 if (get_attr_mode (insn) == MODE_V4SF)
2902 return "%vmovups\t{%1, %0|%0, %1}";
2903 else
2904 return "%vmovdqu\t{%1, %0|%0, %1}";
2905 }
2906 else
2907 {
2908 if (get_attr_mode (insn) == MODE_V4SF)
2909 return "%vmovaps\t{%1, %0|%0, %1}";
2910 else
2911 return "%vmovdqa\t{%1, %0|%0, %1}";
2912 }
2913
2914 case 3:
2915 case 4:
2916 return "#";
2917
2918 default:
2919 gcc_unreachable ();
2920 }
2921 }
2922 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2923 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2924 (set (attr "mode")
2925 (cond [(eq_attr "alternative" "3,4")
2926 (const_string "DI")
2927 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2928 (const_string "V4SF")
2929 (and (eq_attr "alternative" "2")
2930 (match_test "TARGET_SSE_TYPELESS_STORES"))
2931 (const_string "V4SF")
2932 (match_test "TARGET_AVX")
2933 (const_string "TI")
2934 (ior (not (match_test "TARGET_SSE2"))
2935 (match_test "optimize_function_for_size_p (cfun)"))
2936 (const_string "V4SF")
2937 ]
2938 (const_string "TI")))])
2939
2940 ;; Possible store forwarding (partial memory) stall in alternative 4.
2941 (define_insn "*movxf_internal"
2942 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2943 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2944 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2945 && (!can_create_pseudo_p ()
2946 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2947 || GET_CODE (operands[1]) != CONST_DOUBLE
2948 || (optimize_function_for_size_p (cfun)
2949 && standard_80387_constant_p (operands[1]) > 0
2950 && !memory_operand (operands[0], XFmode))
2951 || (!TARGET_MEMORY_MISMATCH_STALL
2952 && memory_operand (operands[0], XFmode)))"
2953 {
2954 switch (which_alternative)
2955 {
2956 case 0:
2957 case 1:
2958 return output_387_reg_move (insn, operands);
2959
2960 case 2:
2961 return standard_80387_constant_opcode (operands[1]);
2962
2963 case 3:
2964 case 4:
2965 return "#";
2966
2967 default:
2968 gcc_unreachable ();
2969 }
2970 }
2971 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2972 (set_attr "mode" "XF,XF,XF,SI,SI")])
2973
2974 (define_insn "*movdf_internal_rex64"
2975 [(set (match_operand:DF 0 "nonimmediate_operand"
2976 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2977 (match_operand:DF 1 "general_operand"
2978 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2979 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2980 && (!can_create_pseudo_p ()
2981 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2982 || GET_CODE (operands[1]) != CONST_DOUBLE
2983 || (optimize_function_for_size_p (cfun)
2984 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2985 && standard_80387_constant_p (operands[1]) > 0)
2986 || (TARGET_SSE2 && TARGET_SSE_MATH
2987 && standard_sse_constant_p (operands[1]))))
2988 || memory_operand (operands[0], DFmode))"
2989 {
2990 switch (which_alternative)
2991 {
2992 case 0:
2993 case 1:
2994 return output_387_reg_move (insn, operands);
2995
2996 case 2:
2997 return standard_80387_constant_opcode (operands[1]);
2998
2999 case 3:
3000 case 4:
3001 return "mov{q}\t{%1, %0|%0, %1}";
3002
3003 case 5:
3004 return "movabs{q}\t{%1, %0|%0, %1}";
3005
3006 case 6:
3007 return "#";
3008
3009 case 7:
3010 return standard_sse_constant_opcode (insn, operands[1]);
3011
3012 case 8:
3013 case 9:
3014 case 10:
3015 switch (get_attr_mode (insn))
3016 {
3017 case MODE_V2DF:
3018 return "%vmovapd\t{%1, %0|%0, %1}";
3019 case MODE_V4SF:
3020 return "%vmovaps\t{%1, %0|%0, %1}";
3021
3022 case MODE_DI:
3023 return "%vmovq\t{%1, %0|%0, %1}";
3024 case MODE_DF:
3025 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3026 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3027 return "%vmovsd\t{%1, %0|%0, %1}";
3028 case MODE_V1DF:
3029 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3030 case MODE_V2SF:
3031 return "%vmovlps\t{%1, %d0|%d0, %1}";
3032 default:
3033 gcc_unreachable ();
3034 }
3035
3036 case 11:
3037 case 12:
3038 /* Handle broken assemblers that require movd instead of movq. */
3039 return "%vmovd\t{%1, %0|%0, %1}";
3040
3041 default:
3042 gcc_unreachable();
3043 }
3044 }
3045 [(set (attr "type")
3046 (cond [(eq_attr "alternative" "0,1,2")
3047 (const_string "fmov")
3048 (eq_attr "alternative" "3,4,5")
3049 (const_string "imov")
3050 (eq_attr "alternative" "6")
3051 (const_string "multi")
3052 (eq_attr "alternative" "7")
3053 (const_string "sselog1")
3054 ]
3055 (const_string "ssemov")))
3056 (set (attr "modrm")
3057 (if_then_else
3058 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3059 (const_string "0")
3060 (const_string "*")))
3061 (set (attr "length_immediate")
3062 (if_then_else
3063 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3064 (const_string "8")
3065 (const_string "*")))
3066 (set (attr "prefix")
3067 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3068 (const_string "orig")
3069 (const_string "maybe_vex")))
3070 (set (attr "prefix_data16")
3071 (if_then_else (eq_attr "mode" "V1DF")
3072 (const_string "1")
3073 (const_string "*")))
3074 (set (attr "mode")
3075 (cond [(eq_attr "alternative" "0,1,2")
3076 (const_string "DF")
3077 (eq_attr "alternative" "3,4,5,6,11,12")
3078 (const_string "DI")
3079
3080 /* xorps is one byte shorter for !TARGET_AVX. */
3081 (eq_attr "alternative" "7")
3082 (cond [(match_test "TARGET_AVX")
3083 (const_string "V2DF")
3084 (match_test "optimize_function_for_size_p (cfun)")
3085 (const_string "V4SF")
3086 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3087 (const_string "TI")
3088 ]
3089 (const_string "V2DF"))
3090
3091 /* For architectures resolving dependencies on
3092 whole SSE registers use APD move to break dependency
3093 chains, otherwise use short move to avoid extra work.
3094
3095 movaps encodes one byte shorter for !TARGET_AVX. */
3096 (eq_attr "alternative" "8")
3097 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3098 (const_string "V4SF")
3099 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3100 (const_string "V2DF")
3101 (match_test "TARGET_AVX")
3102 (const_string "DF")
3103 (match_test "optimize_function_for_size_p (cfun)")
3104 (const_string "V4SF")
3105 ]
3106 (const_string "DF"))
3107 /* For architectures resolving dependencies on register
3108 parts we may avoid extra work to zero out upper part
3109 of register. */
3110 (eq_attr "alternative" "9")
3111 (if_then_else
3112 (match_test "TARGET_SSE_SPLIT_REGS")
3113 (const_string "V1DF")
3114 (const_string "DF"))
3115 ]
3116 (const_string "DF")))])
3117
3118 ;; Possible store forwarding (partial memory) stall in alternative 4.
3119 (define_insn "*movdf_internal"
3120 [(set (match_operand:DF 0 "nonimmediate_operand"
3121 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3122 (match_operand:DF 1 "general_operand"
3123 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3124 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3125 && (!can_create_pseudo_p ()
3126 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3127 || GET_CODE (operands[1]) != CONST_DOUBLE
3128 || (optimize_function_for_size_p (cfun)
3129 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3130 && standard_80387_constant_p (operands[1]) > 0)
3131 || (TARGET_SSE2 && TARGET_SSE_MATH
3132 && standard_sse_constant_p (operands[1])))
3133 && !memory_operand (operands[0], DFmode))
3134 || (!TARGET_MEMORY_MISMATCH_STALL
3135 && memory_operand (operands[0], DFmode)))"
3136 {
3137 switch (which_alternative)
3138 {
3139 case 0:
3140 case 1:
3141 return output_387_reg_move (insn, operands);
3142
3143 case 2:
3144 return standard_80387_constant_opcode (operands[1]);
3145
3146 case 3:
3147 case 4:
3148 return "#";
3149
3150 case 5:
3151 case 9:
3152 return standard_sse_constant_opcode (insn, operands[1]);
3153
3154 case 6:
3155 case 7:
3156 case 8:
3157 case 10:
3158 case 11:
3159 case 12:
3160 switch (get_attr_mode (insn))
3161 {
3162 case MODE_V2DF:
3163 return "%vmovapd\t{%1, %0|%0, %1}";
3164 case MODE_V4SF:
3165 return "%vmovaps\t{%1, %0|%0, %1}";
3166
3167 case MODE_DI:
3168 return "%vmovq\t{%1, %0|%0, %1}";
3169 case MODE_DF:
3170 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3171 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3172 return "%vmovsd\t{%1, %0|%0, %1}";
3173 case MODE_V1DF:
3174 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3175 case MODE_V2SF:
3176 return "%vmovlps\t{%1, %d0|%d0, %1}";
3177 default:
3178 gcc_unreachable ();
3179 }
3180
3181 default:
3182 gcc_unreachable ();
3183 }
3184 }
3185 [(set (attr "isa")
3186 (if_then_else (eq_attr "alternative" "5,6,7,8")
3187 (const_string "sse2")
3188 (const_string "*")))
3189 (set (attr "type")
3190 (cond [(eq_attr "alternative" "0,1,2")
3191 (const_string "fmov")
3192 (eq_attr "alternative" "3,4")
3193 (const_string "multi")
3194 (eq_attr "alternative" "5,9")
3195 (const_string "sselog1")
3196 ]
3197 (const_string "ssemov")))
3198 (set (attr "prefix")
3199 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3200 (const_string "orig")
3201 (const_string "maybe_vex")))
3202 (set (attr "prefix_data16")
3203 (if_then_else (eq_attr "mode" "V1DF")
3204 (const_string "1")
3205 (const_string "*")))
3206 (set (attr "mode")
3207 (cond [(eq_attr "alternative" "0,1,2")
3208 (const_string "DF")
3209 (eq_attr "alternative" "3,4")
3210 (const_string "SI")
3211
3212 /* For SSE1, we have many fewer alternatives. */
3213 (not (match_test "TARGET_SSE2"))
3214 (if_then_else
3215 (eq_attr "alternative" "5,6,9,10")
3216 (const_string "V4SF")
3217 (const_string "V2SF"))
3218
3219 /* xorps is one byte shorter for !TARGET_AVX. */
3220 (eq_attr "alternative" "5,9")
3221 (cond [(match_test "TARGET_AVX")
3222 (const_string "V2DF")
3223 (match_test "optimize_function_for_size_p (cfun)")
3224 (const_string "V4SF")
3225 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3226 (const_string "TI")
3227 ]
3228 (const_string "V2DF"))
3229
3230 /* For architectures resolving dependencies on
3231 whole SSE registers use APD move to break dependency
3232 chains, otherwise use short move to avoid extra work.
3233
3234 movaps encodes one byte shorter for !TARGET_AVX. */
3235 (eq_attr "alternative" "6,10")
3236 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3237 (const_string "V4SF")
3238 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3239 (const_string "V2DF")
3240 (match_test "TARGET_AVX")
3241 (const_string "DF")
3242 (match_test "optimize_function_for_size_p (cfun)")
3243 (const_string "V4SF")
3244 ]
3245 (const_string "DF"))
3246
3247 /* For architectures resolving dependencies on register
3248 parts we may avoid extra work to zero out upper part
3249 of register. */
3250 (eq_attr "alternative" "7,11")
3251 (if_then_else
3252 (match_test "TARGET_SSE_SPLIT_REGS")
3253 (const_string "V1DF")
3254 (const_string "DF"))
3255 ]
3256 (const_string "DF")))])
3257
3258 (define_insn "*movsf_internal"
3259 [(set (match_operand:SF 0 "nonimmediate_operand"
3260 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3261 (match_operand:SF 1 "general_operand"
3262 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3263 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3264 && (!can_create_pseudo_p ()
3265 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3266 || GET_CODE (operands[1]) != CONST_DOUBLE
3267 || (optimize_function_for_size_p (cfun)
3268 && ((!TARGET_SSE_MATH
3269 && standard_80387_constant_p (operands[1]) > 0)
3270 || (TARGET_SSE_MATH
3271 && standard_sse_constant_p (operands[1]))))
3272 || memory_operand (operands[0], SFmode))"
3273 {
3274 switch (which_alternative)
3275 {
3276 case 0:
3277 case 1:
3278 return output_387_reg_move (insn, operands);
3279
3280 case 2:
3281 return standard_80387_constant_opcode (operands[1]);
3282
3283 case 3:
3284 case 4:
3285 return "mov{l}\t{%1, %0|%0, %1}";
3286
3287 case 5:
3288 return standard_sse_constant_opcode (insn, operands[1]);
3289
3290 case 6:
3291 if (get_attr_mode (insn) == MODE_V4SF)
3292 return "%vmovaps\t{%1, %0|%0, %1}";
3293 if (TARGET_AVX)
3294 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3295
3296 case 7:
3297 case 8:
3298 return "%vmovss\t{%1, %0|%0, %1}";
3299
3300 case 9:
3301 case 10:
3302 case 14:
3303 case 15:
3304 return "movd\t{%1, %0|%0, %1}";
3305
3306 case 11:
3307 return "movq\t{%1, %0|%0, %1}";
3308
3309 case 12:
3310 case 13:
3311 return "%vmovd\t{%1, %0|%0, %1}";
3312
3313 default:
3314 gcc_unreachable ();
3315 }
3316 }
3317 [(set (attr "type")
3318 (cond [(eq_attr "alternative" "0,1,2")
3319 (const_string "fmov")
3320 (eq_attr "alternative" "3,4")
3321 (const_string "multi")
3322 (eq_attr "alternative" "5")
3323 (const_string "sselog1")
3324 (eq_attr "alternative" "9,10,11,14,15")
3325 (const_string "mmxmov")
3326 ]
3327 (const_string "ssemov")))
3328 (set (attr "prefix")
3329 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3330 (const_string "maybe_vex")
3331 (const_string "orig")))
3332 (set (attr "mode")
3333 (cond [(eq_attr "alternative" "3,4,9,10")
3334 (const_string "SI")
3335 (eq_attr "alternative" "5")
3336 (cond [(match_test "TARGET_AVX")
3337 (const_string "V4SF")
3338 (ior (not (match_test "TARGET_SSE2"))
3339 (match_test "optimize_function_for_size_p (cfun)"))
3340 (const_string "V4SF")
3341 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3342 (const_string "TI")
3343 ]
3344 (const_string "V4SF"))
3345
3346 /* For architectures resolving dependencies on
3347 whole SSE registers use APS move to break dependency
3348 chains, otherwise use short move to avoid extra work.
3349
3350 Do the same for architectures resolving dependencies on
3351 the parts. While in DF mode it is better to always handle
3352 just register parts, the SF mode is different due to lack
3353 of instructions to load just part of the register. It is
3354 better to maintain the whole registers in single format
3355 to avoid problems on using packed logical operations. */
3356 (eq_attr "alternative" "6")
3357 (if_then_else
3358 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3359 (match_test "TARGET_SSE_SPLIT_REGS"))
3360 (const_string "V4SF")
3361 (const_string "SF"))
3362 (eq_attr "alternative" "11")
3363 (const_string "DI")]
3364 (const_string "SF")))])
3365
3366 (define_split
3367 [(set (match_operand 0 "any_fp_register_operand")
3368 (match_operand 1 "memory_operand"))]
3369 "reload_completed
3370 && (GET_MODE (operands[0]) == TFmode
3371 || GET_MODE (operands[0]) == XFmode
3372 || GET_MODE (operands[0]) == DFmode
3373 || GET_MODE (operands[0]) == SFmode)
3374 && (operands[2] = find_constant_src (insn))"
3375 [(set (match_dup 0) (match_dup 2))]
3376 {
3377 rtx c = operands[2];
3378 int r = REGNO (operands[0]);
3379
3380 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3381 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3382 FAIL;
3383 })
3384
3385 (define_split
3386 [(set (match_operand 0 "any_fp_register_operand")
3387 (float_extend (match_operand 1 "memory_operand")))]
3388 "reload_completed
3389 && (GET_MODE (operands[0]) == TFmode
3390 || GET_MODE (operands[0]) == XFmode
3391 || GET_MODE (operands[0]) == DFmode)
3392 && (operands[2] = find_constant_src (insn))"
3393 [(set (match_dup 0) (match_dup 2))]
3394 {
3395 rtx c = operands[2];
3396 int r = REGNO (operands[0]);
3397
3398 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3399 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3400 FAIL;
3401 })
3402
3403 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3404 (define_split
3405 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3406 (match_operand:X87MODEF 1 "immediate_operand"))]
3407 "reload_completed
3408 && (standard_80387_constant_p (operands[1]) == 8
3409 || standard_80387_constant_p (operands[1]) == 9)"
3410 [(set (match_dup 0)(match_dup 1))
3411 (set (match_dup 0)
3412 (neg:X87MODEF (match_dup 0)))]
3413 {
3414 REAL_VALUE_TYPE r;
3415
3416 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3417 if (real_isnegzero (&r))
3418 operands[1] = CONST0_RTX (<MODE>mode);
3419 else
3420 operands[1] = CONST1_RTX (<MODE>mode);
3421 })
3422
3423 (define_split
3424 [(set (match_operand 0 "nonimmediate_operand")
3425 (match_operand 1 "general_operand"))]
3426 "reload_completed
3427 && (GET_MODE (operands[0]) == TFmode
3428 || GET_MODE (operands[0]) == XFmode
3429 || GET_MODE (operands[0]) == DFmode)
3430 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3431 [(const_int 0)]
3432 "ix86_split_long_move (operands); DONE;")
3433
3434 (define_insn "swapxf"
3435 [(set (match_operand:XF 0 "register_operand" "+f")
3436 (match_operand:XF 1 "register_operand" "+f"))
3437 (set (match_dup 1)
3438 (match_dup 0))]
3439 "TARGET_80387"
3440 {
3441 if (STACK_TOP_P (operands[0]))
3442 return "fxch\t%1";
3443 else
3444 return "fxch\t%0";
3445 }
3446 [(set_attr "type" "fxch")
3447 (set_attr "mode" "XF")])
3448
3449 (define_insn "*swap<mode>"
3450 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3451 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3452 (set (match_dup 1)
3453 (match_dup 0))]
3454 "TARGET_80387 || reload_completed"
3455 {
3456 if (STACK_TOP_P (operands[0]))
3457 return "fxch\t%1";
3458 else
3459 return "fxch\t%0";
3460 }
3461 [(set_attr "type" "fxch")
3462 (set_attr "mode" "<MODE>")])
3463 \f
3464 ;; Zero extension instructions
3465
3466 (define_expand "zero_extendsidi2"
3467 [(set (match_operand:DI 0 "nonimmediate_operand")
3468 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3469
3470 (define_insn "*zero_extendsidi2_rex64"
3471 [(set (match_operand:DI 0 "nonimmediate_operand"
3472 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3473 (zero_extend:DI
3474 (match_operand:SI 1 "x86_64_zext_general_operand"
3475 "rmWz,0,r ,m ,r ,m")))]
3476 "TARGET_64BIT"
3477 "@
3478 mov{l}\t{%1, %k0|%k0, %1}
3479 #
3480 movd\t{%1, %0|%0, %1}
3481 movd\t{%1, %0|%0, %1}
3482 %vmovd\t{%1, %0|%0, %1}
3483 %vmovd\t{%1, %0|%0, %1}"
3484 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3485 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3486 (set_attr "prefix_0f" "0,*,*,*,*,*")
3487 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3488
3489 (define_insn "*zero_extendsidi2"
3490 [(set (match_operand:DI 0 "nonimmediate_operand"
3491 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3492 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3493 "0 ,rm,r ,r ,m ,r ,m")))]
3494 "!TARGET_64BIT"
3495 "@
3496 #
3497 #
3498 #
3499 movd\t{%1, %0|%0, %1}
3500 movd\t{%1, %0|%0, %1}
3501 %vmovd\t{%1, %0|%0, %1}
3502 %vmovd\t{%1, %0|%0, %1}"
3503 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3504 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3505 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3506 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3507
3508 (define_split
3509 [(set (match_operand:DI 0 "memory_operand")
3510 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3511 "reload_completed"
3512 [(set (match_dup 4) (const_int 0))]
3513 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3514
3515 (define_split
3516 [(set (match_operand:DI 0 "register_operand")
3517 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3518 "!TARGET_64BIT && reload_completed
3519 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3520 && true_regnum (operands[0]) == true_regnum (operands[1])"
3521 [(set (match_dup 4) (const_int 0))]
3522 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3523
3524 (define_split
3525 [(set (match_operand:DI 0 "nonimmediate_operand")
3526 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3527 "!TARGET_64BIT && reload_completed
3528 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3529 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3530 [(set (match_dup 3) (match_dup 1))
3531 (set (match_dup 4) (const_int 0))]
3532 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3533
3534 (define_insn "zero_extend<mode>di2"
3535 [(set (match_operand:DI 0 "register_operand" "=r")
3536 (zero_extend:DI
3537 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3538 "TARGET_64BIT"
3539 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3540 [(set_attr "type" "imovx")
3541 (set_attr "mode" "SI")])
3542
3543 (define_expand "zero_extend<mode>si2"
3544 [(set (match_operand:SI 0 "register_operand")
3545 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3546 ""
3547 {
3548 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3549 {
3550 operands[1] = force_reg (<MODE>mode, operands[1]);
3551 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3552 DONE;
3553 }
3554 })
3555
3556 (define_insn_and_split "zero_extend<mode>si2_and"
3557 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3558 (zero_extend:SI
3559 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3560 (clobber (reg:CC FLAGS_REG))]
3561 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3562 "#"
3563 "&& reload_completed"
3564 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3565 (clobber (reg:CC FLAGS_REG))])]
3566 {
3567 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3568 {
3569 ix86_expand_clear (operands[0]);
3570
3571 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3572 emit_insn (gen_movstrict<mode>
3573 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3574 DONE;
3575 }
3576
3577 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3578 }
3579 [(set_attr "type" "alu1")
3580 (set_attr "mode" "SI")])
3581
3582 (define_insn "*zero_extend<mode>si2"
3583 [(set (match_operand:SI 0 "register_operand" "=r")
3584 (zero_extend:SI
3585 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3586 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3587 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3588 [(set_attr "type" "imovx")
3589 (set_attr "mode" "SI")])
3590
3591 (define_expand "zero_extendqihi2"
3592 [(set (match_operand:HI 0 "register_operand")
3593 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3594 ""
3595 {
3596 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3597 {
3598 operands[1] = force_reg (QImode, operands[1]);
3599 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3600 DONE;
3601 }
3602 })
3603
3604 (define_insn_and_split "zero_extendqihi2_and"
3605 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3606 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3607 (clobber (reg:CC FLAGS_REG))]
3608 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3609 "#"
3610 "&& reload_completed"
3611 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3612 (clobber (reg:CC FLAGS_REG))])]
3613 {
3614 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3615 {
3616 ix86_expand_clear (operands[0]);
3617
3618 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3619 emit_insn (gen_movstrictqi
3620 (gen_lowpart (QImode, operands[0]), operands[1]));
3621 DONE;
3622 }
3623
3624 operands[0] = gen_lowpart (SImode, operands[0]);
3625 }
3626 [(set_attr "type" "alu1")
3627 (set_attr "mode" "SI")])
3628
3629 ; zero extend to SImode to avoid partial register stalls
3630 (define_insn "*zero_extendqihi2"
3631 [(set (match_operand:HI 0 "register_operand" "=r")
3632 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3633 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3634 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3635 [(set_attr "type" "imovx")
3636 (set_attr "mode" "SI")])
3637 \f
3638 ;; Sign extension instructions
3639
3640 (define_expand "extendsidi2"
3641 [(set (match_operand:DI 0 "register_operand")
3642 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3643 ""
3644 {
3645 if (!TARGET_64BIT)
3646 {
3647 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3648 DONE;
3649 }
3650 })
3651
3652 (define_insn "*extendsidi2_rex64"
3653 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3654 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3655 "TARGET_64BIT"
3656 "@
3657 {cltq|cdqe}
3658 movs{lq|x}\t{%1, %0|%0, %1}"
3659 [(set_attr "type" "imovx")
3660 (set_attr "mode" "DI")
3661 (set_attr "prefix_0f" "0")
3662 (set_attr "modrm" "0,1")])
3663
3664 (define_insn "extendsidi2_1"
3665 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3666 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3667 (clobber (reg:CC FLAGS_REG))
3668 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3669 "!TARGET_64BIT"
3670 "#")
3671
3672 ;; Extend to memory case when source register does die.
3673 (define_split
3674 [(set (match_operand:DI 0 "memory_operand")
3675 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3676 (clobber (reg:CC FLAGS_REG))
3677 (clobber (match_operand:SI 2 "register_operand"))]
3678 "(reload_completed
3679 && dead_or_set_p (insn, operands[1])
3680 && !reg_mentioned_p (operands[1], operands[0]))"
3681 [(set (match_dup 3) (match_dup 1))
3682 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3683 (clobber (reg:CC FLAGS_REG))])
3684 (set (match_dup 4) (match_dup 1))]
3685 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3686
3687 ;; Extend to memory case when source register does not die.
3688 (define_split
3689 [(set (match_operand:DI 0 "memory_operand")
3690 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3691 (clobber (reg:CC FLAGS_REG))
3692 (clobber (match_operand:SI 2 "register_operand"))]
3693 "reload_completed"
3694 [(const_int 0)]
3695 {
3696 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3697
3698 emit_move_insn (operands[3], operands[1]);
3699
3700 /* Generate a cltd if possible and doing so it profitable. */
3701 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3702 && true_regnum (operands[1]) == AX_REG
3703 && true_regnum (operands[2]) == DX_REG)
3704 {
3705 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3706 }
3707 else
3708 {
3709 emit_move_insn (operands[2], operands[1]);
3710 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3711 }
3712 emit_move_insn (operands[4], operands[2]);
3713 DONE;
3714 })
3715
3716 ;; Extend to register case. Optimize case where source and destination
3717 ;; registers match and cases where we can use cltd.
3718 (define_split
3719 [(set (match_operand:DI 0 "register_operand")
3720 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3721 (clobber (reg:CC FLAGS_REG))
3722 (clobber (match_scratch:SI 2))]
3723 "reload_completed"
3724 [(const_int 0)]
3725 {
3726 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3727
3728 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3729 emit_move_insn (operands[3], operands[1]);
3730
3731 /* Generate a cltd if possible and doing so it profitable. */
3732 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3733 && true_regnum (operands[3]) == AX_REG
3734 && true_regnum (operands[4]) == DX_REG)
3735 {
3736 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3737 DONE;
3738 }
3739
3740 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3741 emit_move_insn (operands[4], operands[1]);
3742
3743 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3744 DONE;
3745 })
3746
3747 (define_insn "extend<mode>di2"
3748 [(set (match_operand:DI 0 "register_operand" "=r")
3749 (sign_extend:DI
3750 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3751 "TARGET_64BIT"
3752 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3753 [(set_attr "type" "imovx")
3754 (set_attr "mode" "DI")])
3755
3756 (define_insn "extendhisi2"
3757 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3758 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3759 ""
3760 {
3761 switch (get_attr_prefix_0f (insn))
3762 {
3763 case 0:
3764 return "{cwtl|cwde}";
3765 default:
3766 return "movs{wl|x}\t{%1, %0|%0, %1}";
3767 }
3768 }
3769 [(set_attr "type" "imovx")
3770 (set_attr "mode" "SI")
3771 (set (attr "prefix_0f")
3772 ;; movsx is short decodable while cwtl is vector decoded.
3773 (if_then_else (and (eq_attr "cpu" "!k6")
3774 (eq_attr "alternative" "0"))
3775 (const_string "0")
3776 (const_string "1")))
3777 (set (attr "modrm")
3778 (if_then_else (eq_attr "prefix_0f" "0")
3779 (const_string "0")
3780 (const_string "1")))])
3781
3782 (define_insn "*extendhisi2_zext"
3783 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3784 (zero_extend:DI
3785 (sign_extend:SI
3786 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3787 "TARGET_64BIT"
3788 {
3789 switch (get_attr_prefix_0f (insn))
3790 {
3791 case 0:
3792 return "{cwtl|cwde}";
3793 default:
3794 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3795 }
3796 }
3797 [(set_attr "type" "imovx")
3798 (set_attr "mode" "SI")
3799 (set (attr "prefix_0f")
3800 ;; movsx is short decodable while cwtl is vector decoded.
3801 (if_then_else (and (eq_attr "cpu" "!k6")
3802 (eq_attr "alternative" "0"))
3803 (const_string "0")
3804 (const_string "1")))
3805 (set (attr "modrm")
3806 (if_then_else (eq_attr "prefix_0f" "0")
3807 (const_string "0")
3808 (const_string "1")))])
3809
3810 (define_insn "extendqisi2"
3811 [(set (match_operand:SI 0 "register_operand" "=r")
3812 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3813 ""
3814 "movs{bl|x}\t{%1, %0|%0, %1}"
3815 [(set_attr "type" "imovx")
3816 (set_attr "mode" "SI")])
3817
3818 (define_insn "*extendqisi2_zext"
3819 [(set (match_operand:DI 0 "register_operand" "=r")
3820 (zero_extend:DI
3821 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3822 "TARGET_64BIT"
3823 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3824 [(set_attr "type" "imovx")
3825 (set_attr "mode" "SI")])
3826
3827 (define_insn "extendqihi2"
3828 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3829 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3830 ""
3831 {
3832 switch (get_attr_prefix_0f (insn))
3833 {
3834 case 0:
3835 return "{cbtw|cbw}";
3836 default:
3837 return "movs{bw|x}\t{%1, %0|%0, %1}";
3838 }
3839 }
3840 [(set_attr "type" "imovx")
3841 (set_attr "mode" "HI")
3842 (set (attr "prefix_0f")
3843 ;; movsx is short decodable while cwtl is vector decoded.
3844 (if_then_else (and (eq_attr "cpu" "!k6")
3845 (eq_attr "alternative" "0"))
3846 (const_string "0")
3847 (const_string "1")))
3848 (set (attr "modrm")
3849 (if_then_else (eq_attr "prefix_0f" "0")
3850 (const_string "0")
3851 (const_string "1")))])
3852 \f
3853 ;; Conversions between float and double.
3854
3855 ;; These are all no-ops in the model used for the 80387.
3856 ;; So just emit moves.
3857
3858 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3859 (define_split
3860 [(set (match_operand:DF 0 "push_operand")
3861 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3862 "reload_completed"
3863 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3864 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3865
3866 (define_split
3867 [(set (match_operand:XF 0 "push_operand")
3868 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3869 "reload_completed"
3870 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3871 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3872 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3873
3874 (define_expand "extendsfdf2"
3875 [(set (match_operand:DF 0 "nonimmediate_operand")
3876 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3877 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3878 {
3879 /* ??? Needed for compress_float_constant since all fp constants
3880 are TARGET_LEGITIMATE_CONSTANT_P. */
3881 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3882 {
3883 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3884 && standard_80387_constant_p (operands[1]) > 0)
3885 {
3886 operands[1] = simplify_const_unary_operation
3887 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3888 emit_move_insn_1 (operands[0], operands[1]);
3889 DONE;
3890 }
3891 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3892 }
3893 })
3894
3895 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3896 cvtss2sd:
3897 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3898 cvtps2pd xmm2,xmm1
3899 We do the conversion post reload to avoid producing of 128bit spills
3900 that might lead to ICE on 32bit target. The sequence unlikely combine
3901 anyway. */
3902 (define_split
3903 [(set (match_operand:DF 0 "register_operand")
3904 (float_extend:DF
3905 (match_operand:SF 1 "nonimmediate_operand")))]
3906 "TARGET_USE_VECTOR_FP_CONVERTS
3907 && optimize_insn_for_speed_p ()
3908 && reload_completed && SSE_REG_P (operands[0])"
3909 [(set (match_dup 2)
3910 (float_extend:V2DF
3911 (vec_select:V2SF
3912 (match_dup 3)
3913 (parallel [(const_int 0) (const_int 1)]))))]
3914 {
3915 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3916 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3917 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3918 Try to avoid move when unpacking can be done in source. */
3919 if (REG_P (operands[1]))
3920 {
3921 /* If it is unsafe to overwrite upper half of source, we need
3922 to move to destination and unpack there. */
3923 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3924 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3925 && true_regnum (operands[0]) != true_regnum (operands[1]))
3926 {
3927 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3928 emit_move_insn (tmp, operands[1]);
3929 }
3930 else
3931 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3932 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3933 operands[3]));
3934 }
3935 else
3936 emit_insn (gen_vec_setv4sf_0 (operands[3],
3937 CONST0_RTX (V4SFmode), operands[1]));
3938 })
3939
3940 (define_insn "*extendsfdf2_mixed"
3941 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3942 (float_extend:DF
3943 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3944 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3945 {
3946 switch (which_alternative)
3947 {
3948 case 0:
3949 case 1:
3950 return output_387_reg_move (insn, operands);
3951
3952 case 2:
3953 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3954
3955 default:
3956 gcc_unreachable ();
3957 }
3958 }
3959 [(set_attr "type" "fmov,fmov,ssecvt")
3960 (set_attr "prefix" "orig,orig,maybe_vex")
3961 (set_attr "mode" "SF,XF,DF")])
3962
3963 (define_insn "*extendsfdf2_sse"
3964 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3965 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3966 "TARGET_SSE2 && TARGET_SSE_MATH"
3967 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3968 [(set_attr "type" "ssecvt")
3969 (set_attr "prefix" "maybe_vex")
3970 (set_attr "mode" "DF")])
3971
3972 (define_insn "*extendsfdf2_i387"
3973 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3974 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3975 "TARGET_80387"
3976 "* return output_387_reg_move (insn, operands);"
3977 [(set_attr "type" "fmov")
3978 (set_attr "mode" "SF,XF")])
3979
3980 (define_expand "extend<mode>xf2"
3981 [(set (match_operand:XF 0 "nonimmediate_operand")
3982 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3983 "TARGET_80387"
3984 {
3985 /* ??? Needed for compress_float_constant since all fp constants
3986 are TARGET_LEGITIMATE_CONSTANT_P. */
3987 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3988 {
3989 if (standard_80387_constant_p (operands[1]) > 0)
3990 {
3991 operands[1] = simplify_const_unary_operation
3992 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3993 emit_move_insn_1 (operands[0], operands[1]);
3994 DONE;
3995 }
3996 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3997 }
3998 })
3999
4000 (define_insn "*extend<mode>xf2_i387"
4001 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4002 (float_extend:XF
4003 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4004 "TARGET_80387"
4005 "* return output_387_reg_move (insn, operands);"
4006 [(set_attr "type" "fmov")
4007 (set_attr "mode" "<MODE>,XF")])
4008
4009 ;; %%% This seems bad bad news.
4010 ;; This cannot output into an f-reg because there is no way to be sure
4011 ;; of truncating in that case. Otherwise this is just like a simple move
4012 ;; insn. So we pretend we can output to a reg in order to get better
4013 ;; register preferencing, but we really use a stack slot.
4014
4015 ;; Conversion from DFmode to SFmode.
4016
4017 (define_expand "truncdfsf2"
4018 [(set (match_operand:SF 0 "nonimmediate_operand")
4019 (float_truncate:SF
4020 (match_operand:DF 1 "nonimmediate_operand")))]
4021 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4022 {
4023 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4024 ;
4025 else if (flag_unsafe_math_optimizations)
4026 ;
4027 else
4028 {
4029 enum ix86_stack_slot slot = (virtuals_instantiated
4030 ? SLOT_TEMP
4031 : SLOT_VIRTUAL);
4032 rtx temp = assign_386_stack_local (SFmode, slot);
4033 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4034 DONE;
4035 }
4036 })
4037
4038 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4039 cvtsd2ss:
4040 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4041 cvtpd2ps xmm2,xmm1
4042 We do the conversion post reload to avoid producing of 128bit spills
4043 that might lead to ICE on 32bit target. The sequence unlikely combine
4044 anyway. */
4045 (define_split
4046 [(set (match_operand:SF 0 "register_operand")
4047 (float_truncate:SF
4048 (match_operand:DF 1 "nonimmediate_operand")))]
4049 "TARGET_USE_VECTOR_FP_CONVERTS
4050 && optimize_insn_for_speed_p ()
4051 && reload_completed && SSE_REG_P (operands[0])"
4052 [(set (match_dup 2)
4053 (vec_concat:V4SF
4054 (float_truncate:V2SF
4055 (match_dup 4))
4056 (match_dup 3)))]
4057 {
4058 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4059 operands[3] = CONST0_RTX (V2SFmode);
4060 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4061 /* Use movsd for loading from memory, unpcklpd for registers.
4062 Try to avoid move when unpacking can be done in source, or SSE3
4063 movddup is available. */
4064 if (REG_P (operands[1]))
4065 {
4066 if (!TARGET_SSE3
4067 && true_regnum (operands[0]) != true_regnum (operands[1])
4068 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4069 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4070 {
4071 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4072 emit_move_insn (tmp, operands[1]);
4073 operands[1] = tmp;
4074 }
4075 else if (!TARGET_SSE3)
4076 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4077 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4078 }
4079 else
4080 emit_insn (gen_sse2_loadlpd (operands[4],
4081 CONST0_RTX (V2DFmode), operands[1]));
4082 })
4083
4084 (define_expand "truncdfsf2_with_temp"
4085 [(parallel [(set (match_operand:SF 0)
4086 (float_truncate:SF (match_operand:DF 1)))
4087 (clobber (match_operand:SF 2))])])
4088
4089 (define_insn "*truncdfsf_fast_mixed"
4090 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4091 (float_truncate:SF
4092 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4093 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4094 {
4095 switch (which_alternative)
4096 {
4097 case 0:
4098 return output_387_reg_move (insn, operands);
4099 case 1:
4100 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4101 default:
4102 gcc_unreachable ();
4103 }
4104 }
4105 [(set_attr "type" "fmov,ssecvt")
4106 (set_attr "prefix" "orig,maybe_vex")
4107 (set_attr "mode" "SF")])
4108
4109 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4110 ;; because nothing we do here is unsafe.
4111 (define_insn "*truncdfsf_fast_sse"
4112 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4113 (float_truncate:SF
4114 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4115 "TARGET_SSE2 && TARGET_SSE_MATH"
4116 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4117 [(set_attr "type" "ssecvt")
4118 (set_attr "prefix" "maybe_vex")
4119 (set_attr "mode" "SF")])
4120
4121 (define_insn "*truncdfsf_fast_i387"
4122 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4123 (float_truncate:SF
4124 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4125 "TARGET_80387 && flag_unsafe_math_optimizations"
4126 "* return output_387_reg_move (insn, operands);"
4127 [(set_attr "type" "fmov")
4128 (set_attr "mode" "SF")])
4129
4130 (define_insn "*truncdfsf_mixed"
4131 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4132 (float_truncate:SF
4133 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4134 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4135 "TARGET_MIX_SSE_I387"
4136 {
4137 switch (which_alternative)
4138 {
4139 case 0:
4140 return output_387_reg_move (insn, operands);
4141 case 1:
4142 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4143
4144 default:
4145 return "#";
4146 }
4147 }
4148 [(set_attr "isa" "*,sse2,*,*,*")
4149 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4150 (set_attr "unit" "*,*,i387,i387,i387")
4151 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4152 (set_attr "mode" "SF")])
4153
4154 (define_insn "*truncdfsf_i387"
4155 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4156 (float_truncate:SF
4157 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4158 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4159 "TARGET_80387"
4160 {
4161 switch (which_alternative)
4162 {
4163 case 0:
4164 return output_387_reg_move (insn, operands);
4165
4166 default:
4167 return "#";
4168 }
4169 }
4170 [(set_attr "type" "fmov,multi,multi,multi")
4171 (set_attr "unit" "*,i387,i387,i387")
4172 (set_attr "mode" "SF")])
4173
4174 (define_insn "*truncdfsf2_i387_1"
4175 [(set (match_operand:SF 0 "memory_operand" "=m")
4176 (float_truncate:SF
4177 (match_operand:DF 1 "register_operand" "f")))]
4178 "TARGET_80387
4179 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4180 && !TARGET_MIX_SSE_I387"
4181 "* return output_387_reg_move (insn, operands);"
4182 [(set_attr "type" "fmov")
4183 (set_attr "mode" "SF")])
4184
4185 (define_split
4186 [(set (match_operand:SF 0 "register_operand")
4187 (float_truncate:SF
4188 (match_operand:DF 1 "fp_register_operand")))
4189 (clobber (match_operand 2))]
4190 "reload_completed"
4191 [(set (match_dup 2) (match_dup 1))
4192 (set (match_dup 0) (match_dup 2))]
4193 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4194
4195 ;; Conversion from XFmode to {SF,DF}mode
4196
4197 (define_expand "truncxf<mode>2"
4198 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4199 (float_truncate:MODEF
4200 (match_operand:XF 1 "register_operand")))
4201 (clobber (match_dup 2))])]
4202 "TARGET_80387"
4203 {
4204 if (flag_unsafe_math_optimizations)
4205 {
4206 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4207 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4208 if (reg != operands[0])
4209 emit_move_insn (operands[0], reg);
4210 DONE;
4211 }
4212 else
4213 {
4214 enum ix86_stack_slot slot = (virtuals_instantiated
4215 ? SLOT_TEMP
4216 : SLOT_VIRTUAL);
4217 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4218 }
4219 })
4220
4221 (define_insn "*truncxfsf2_mixed"
4222 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4223 (float_truncate:SF
4224 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4225 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4226 "TARGET_80387"
4227 {
4228 gcc_assert (!which_alternative);
4229 return output_387_reg_move (insn, operands);
4230 }
4231 [(set_attr "type" "fmov,multi,multi,multi")
4232 (set_attr "unit" "*,i387,i387,i387")
4233 (set_attr "mode" "SF")])
4234
4235 (define_insn "*truncxfdf2_mixed"
4236 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4237 (float_truncate:DF
4238 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4239 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4240 "TARGET_80387"
4241 {
4242 gcc_assert (!which_alternative);
4243 return output_387_reg_move (insn, operands);
4244 }
4245 [(set_attr "isa" "*,*,sse2,*")
4246 (set_attr "type" "fmov,multi,multi,multi")
4247 (set_attr "unit" "*,i387,i387,i387")
4248 (set_attr "mode" "DF")])
4249
4250 (define_insn "truncxf<mode>2_i387_noop"
4251 [(set (match_operand:MODEF 0 "register_operand" "=f")
4252 (float_truncate:MODEF
4253 (match_operand:XF 1 "register_operand" "f")))]
4254 "TARGET_80387 && flag_unsafe_math_optimizations"
4255 "* return output_387_reg_move (insn, operands);"
4256 [(set_attr "type" "fmov")
4257 (set_attr "mode" "<MODE>")])
4258
4259 (define_insn "*truncxf<mode>2_i387"
4260 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4261 (float_truncate:MODEF
4262 (match_operand:XF 1 "register_operand" "f")))]
4263 "TARGET_80387"
4264 "* return output_387_reg_move (insn, operands);"
4265 [(set_attr "type" "fmov")
4266 (set_attr "mode" "<MODE>")])
4267
4268 (define_split
4269 [(set (match_operand:MODEF 0 "register_operand")
4270 (float_truncate:MODEF
4271 (match_operand:XF 1 "register_operand")))
4272 (clobber (match_operand:MODEF 2 "memory_operand"))]
4273 "TARGET_80387 && reload_completed"
4274 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4275 (set (match_dup 0) (match_dup 2))])
4276
4277 (define_split
4278 [(set (match_operand:MODEF 0 "memory_operand")
4279 (float_truncate:MODEF
4280 (match_operand:XF 1 "register_operand")))
4281 (clobber (match_operand:MODEF 2 "memory_operand"))]
4282 "TARGET_80387"
4283 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4284 \f
4285 ;; Signed conversion to DImode.
4286
4287 (define_expand "fix_truncxfdi2"
4288 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4289 (fix:DI (match_operand:XF 1 "register_operand")))
4290 (clobber (reg:CC FLAGS_REG))])]
4291 "TARGET_80387"
4292 {
4293 if (TARGET_FISTTP)
4294 {
4295 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4296 DONE;
4297 }
4298 })
4299
4300 (define_expand "fix_trunc<mode>di2"
4301 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4302 (fix:DI (match_operand:MODEF 1 "register_operand")))
4303 (clobber (reg:CC FLAGS_REG))])]
4304 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4305 {
4306 if (TARGET_FISTTP
4307 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4308 {
4309 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4310 DONE;
4311 }
4312 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4313 {
4314 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4315 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4316 if (out != operands[0])
4317 emit_move_insn (operands[0], out);
4318 DONE;
4319 }
4320 })
4321
4322 ;; Signed conversion to SImode.
4323
4324 (define_expand "fix_truncxfsi2"
4325 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4326 (fix:SI (match_operand:XF 1 "register_operand")))
4327 (clobber (reg:CC FLAGS_REG))])]
4328 "TARGET_80387"
4329 {
4330 if (TARGET_FISTTP)
4331 {
4332 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4333 DONE;
4334 }
4335 })
4336
4337 (define_expand "fix_trunc<mode>si2"
4338 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4339 (fix:SI (match_operand:MODEF 1 "register_operand")))
4340 (clobber (reg:CC FLAGS_REG))])]
4341 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4342 {
4343 if (TARGET_FISTTP
4344 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4345 {
4346 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4347 DONE;
4348 }
4349 if (SSE_FLOAT_MODE_P (<MODE>mode))
4350 {
4351 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4352 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4353 if (out != operands[0])
4354 emit_move_insn (operands[0], out);
4355 DONE;
4356 }
4357 })
4358
4359 ;; Signed conversion to HImode.
4360
4361 (define_expand "fix_trunc<mode>hi2"
4362 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4363 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4364 (clobber (reg:CC FLAGS_REG))])]
4365 "TARGET_80387
4366 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4367 {
4368 if (TARGET_FISTTP)
4369 {
4370 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4371 DONE;
4372 }
4373 })
4374
4375 ;; Unsigned conversion to SImode.
4376
4377 (define_expand "fixuns_trunc<mode>si2"
4378 [(parallel
4379 [(set (match_operand:SI 0 "register_operand")
4380 (unsigned_fix:SI
4381 (match_operand:MODEF 1 "nonimmediate_operand")))
4382 (use (match_dup 2))
4383 (clobber (match_scratch:<ssevecmode> 3))
4384 (clobber (match_scratch:<ssevecmode> 4))])]
4385 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4386 {
4387 enum machine_mode mode = <MODE>mode;
4388 enum machine_mode vecmode = <ssevecmode>mode;
4389 REAL_VALUE_TYPE TWO31r;
4390 rtx two31;
4391
4392 if (optimize_insn_for_size_p ())
4393 FAIL;
4394
4395 real_ldexp (&TWO31r, &dconst1, 31);
4396 two31 = const_double_from_real_value (TWO31r, mode);
4397 two31 = ix86_build_const_vector (vecmode, true, two31);
4398 operands[2] = force_reg (vecmode, two31);
4399 })
4400
4401 (define_insn_and_split "*fixuns_trunc<mode>_1"
4402 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4403 (unsigned_fix:SI
4404 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4405 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4406 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4407 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4408 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4409 && optimize_function_for_speed_p (cfun)"
4410 "#"
4411 "&& reload_completed"
4412 [(const_int 0)]
4413 {
4414 ix86_split_convert_uns_si_sse (operands);
4415 DONE;
4416 })
4417
4418 ;; Unsigned conversion to HImode.
4419 ;; Without these patterns, we'll try the unsigned SI conversion which
4420 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4421
4422 (define_expand "fixuns_trunc<mode>hi2"
4423 [(set (match_dup 2)
4424 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4425 (set (match_operand:HI 0 "nonimmediate_operand")
4426 (subreg:HI (match_dup 2) 0))]
4427 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4428 "operands[2] = gen_reg_rtx (SImode);")
4429
4430 ;; When SSE is available, it is always faster to use it!
4431 (define_insn "fix_trunc<mode>di_sse"
4432 [(set (match_operand:DI 0 "register_operand" "=r,r")
4433 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4434 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4435 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4436 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4437 [(set_attr "type" "sseicvt")
4438 (set_attr "prefix" "maybe_vex")
4439 (set_attr "prefix_rex" "1")
4440 (set_attr "mode" "<MODE>")
4441 (set_attr "athlon_decode" "double,vector")
4442 (set_attr "amdfam10_decode" "double,double")
4443 (set_attr "bdver1_decode" "double,double")])
4444
4445 (define_insn "fix_trunc<mode>si_sse"
4446 [(set (match_operand:SI 0 "register_operand" "=r,r")
4447 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4448 "SSE_FLOAT_MODE_P (<MODE>mode)
4449 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4450 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4451 [(set_attr "type" "sseicvt")
4452 (set_attr "prefix" "maybe_vex")
4453 (set_attr "mode" "<MODE>")
4454 (set_attr "athlon_decode" "double,vector")
4455 (set_attr "amdfam10_decode" "double,double")
4456 (set_attr "bdver1_decode" "double,double")])
4457
4458 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4459 (define_peephole2
4460 [(set (match_operand:MODEF 0 "register_operand")
4461 (match_operand:MODEF 1 "memory_operand"))
4462 (set (match_operand:SWI48x 2 "register_operand")
4463 (fix:SWI48x (match_dup 0)))]
4464 "TARGET_SHORTEN_X87_SSE
4465 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4466 && peep2_reg_dead_p (2, operands[0])"
4467 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4468
4469 ;; Avoid vector decoded forms of the instruction.
4470 (define_peephole2
4471 [(match_scratch:DF 2 "x")
4472 (set (match_operand:SWI48x 0 "register_operand")
4473 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4474 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4475 [(set (match_dup 2) (match_dup 1))
4476 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4477
4478 (define_peephole2
4479 [(match_scratch:SF 2 "x")
4480 (set (match_operand:SWI48x 0 "register_operand")
4481 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4482 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4483 [(set (match_dup 2) (match_dup 1))
4484 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4485
4486 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4487 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4488 (fix:SWI248x (match_operand 1 "register_operand")))]
4489 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4490 && TARGET_FISTTP
4491 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4492 && (TARGET_64BIT || <MODE>mode != DImode))
4493 && TARGET_SSE_MATH)
4494 && can_create_pseudo_p ()"
4495 "#"
4496 "&& 1"
4497 [(const_int 0)]
4498 {
4499 if (memory_operand (operands[0], VOIDmode))
4500 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4501 else
4502 {
4503 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4504 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4505 operands[1],
4506 operands[2]));
4507 }
4508 DONE;
4509 }
4510 [(set_attr "type" "fisttp")
4511 (set_attr "mode" "<MODE>")])
4512
4513 (define_insn "fix_trunc<mode>_i387_fisttp"
4514 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4515 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4516 (clobber (match_scratch:XF 2 "=&1f"))]
4517 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4518 && TARGET_FISTTP
4519 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4520 && (TARGET_64BIT || <MODE>mode != DImode))
4521 && TARGET_SSE_MATH)"
4522 "* return output_fix_trunc (insn, operands, true);"
4523 [(set_attr "type" "fisttp")
4524 (set_attr "mode" "<MODE>")])
4525
4526 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4527 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4528 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4529 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4530 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4531 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4532 && TARGET_FISTTP
4533 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4534 && (TARGET_64BIT || <MODE>mode != DImode))
4535 && TARGET_SSE_MATH)"
4536 "#"
4537 [(set_attr "type" "fisttp")
4538 (set_attr "mode" "<MODE>")])
4539
4540 (define_split
4541 [(set (match_operand:SWI248x 0 "register_operand")
4542 (fix:SWI248x (match_operand 1 "register_operand")))
4543 (clobber (match_operand:SWI248x 2 "memory_operand"))
4544 (clobber (match_scratch 3))]
4545 "reload_completed"
4546 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4547 (clobber (match_dup 3))])
4548 (set (match_dup 0) (match_dup 2))])
4549
4550 (define_split
4551 [(set (match_operand:SWI248x 0 "memory_operand")
4552 (fix:SWI248x (match_operand 1 "register_operand")))
4553 (clobber (match_operand:SWI248x 2 "memory_operand"))
4554 (clobber (match_scratch 3))]
4555 "reload_completed"
4556 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4557 (clobber (match_dup 3))])])
4558
4559 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4560 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4561 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4562 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4563 ;; function in i386.c.
4564 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4565 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4566 (fix:SWI248x (match_operand 1 "register_operand")))
4567 (clobber (reg:CC FLAGS_REG))]
4568 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4569 && !TARGET_FISTTP
4570 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4571 && (TARGET_64BIT || <MODE>mode != DImode))
4572 && can_create_pseudo_p ()"
4573 "#"
4574 "&& 1"
4575 [(const_int 0)]
4576 {
4577 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4578
4579 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4580 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4581 if (memory_operand (operands[0], VOIDmode))
4582 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4583 operands[2], operands[3]));
4584 else
4585 {
4586 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4587 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4588 operands[2], operands[3],
4589 operands[4]));
4590 }
4591 DONE;
4592 }
4593 [(set_attr "type" "fistp")
4594 (set_attr "i387_cw" "trunc")
4595 (set_attr "mode" "<MODE>")])
4596
4597 (define_insn "fix_truncdi_i387"
4598 [(set (match_operand:DI 0 "memory_operand" "=m")
4599 (fix:DI (match_operand 1 "register_operand" "f")))
4600 (use (match_operand:HI 2 "memory_operand" "m"))
4601 (use (match_operand:HI 3 "memory_operand" "m"))
4602 (clobber (match_scratch:XF 4 "=&1f"))]
4603 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4604 && !TARGET_FISTTP
4605 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4606 "* return output_fix_trunc (insn, operands, false);"
4607 [(set_attr "type" "fistp")
4608 (set_attr "i387_cw" "trunc")
4609 (set_attr "mode" "DI")])
4610
4611 (define_insn "fix_truncdi_i387_with_temp"
4612 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4613 (fix:DI (match_operand 1 "register_operand" "f,f")))
4614 (use (match_operand:HI 2 "memory_operand" "m,m"))
4615 (use (match_operand:HI 3 "memory_operand" "m,m"))
4616 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4617 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4618 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4619 && !TARGET_FISTTP
4620 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4621 "#"
4622 [(set_attr "type" "fistp")
4623 (set_attr "i387_cw" "trunc")
4624 (set_attr "mode" "DI")])
4625
4626 (define_split
4627 [(set (match_operand:DI 0 "register_operand")
4628 (fix:DI (match_operand 1 "register_operand")))
4629 (use (match_operand:HI 2 "memory_operand"))
4630 (use (match_operand:HI 3 "memory_operand"))
4631 (clobber (match_operand:DI 4 "memory_operand"))
4632 (clobber (match_scratch 5))]
4633 "reload_completed"
4634 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4635 (use (match_dup 2))
4636 (use (match_dup 3))
4637 (clobber (match_dup 5))])
4638 (set (match_dup 0) (match_dup 4))])
4639
4640 (define_split
4641 [(set (match_operand:DI 0 "memory_operand")
4642 (fix:DI (match_operand 1 "register_operand")))
4643 (use (match_operand:HI 2 "memory_operand"))
4644 (use (match_operand:HI 3 "memory_operand"))
4645 (clobber (match_operand:DI 4 "memory_operand"))
4646 (clobber (match_scratch 5))]
4647 "reload_completed"
4648 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4649 (use (match_dup 2))
4650 (use (match_dup 3))
4651 (clobber (match_dup 5))])])
4652
4653 (define_insn "fix_trunc<mode>_i387"
4654 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4655 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4656 (use (match_operand:HI 2 "memory_operand" "m"))
4657 (use (match_operand:HI 3 "memory_operand" "m"))]
4658 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4659 && !TARGET_FISTTP
4660 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4661 "* return output_fix_trunc (insn, operands, false);"
4662 [(set_attr "type" "fistp")
4663 (set_attr "i387_cw" "trunc")
4664 (set_attr "mode" "<MODE>")])
4665
4666 (define_insn "fix_trunc<mode>_i387_with_temp"
4667 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4668 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4669 (use (match_operand:HI 2 "memory_operand" "m,m"))
4670 (use (match_operand:HI 3 "memory_operand" "m,m"))
4671 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4672 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4673 && !TARGET_FISTTP
4674 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4675 "#"
4676 [(set_attr "type" "fistp")
4677 (set_attr "i387_cw" "trunc")
4678 (set_attr "mode" "<MODE>")])
4679
4680 (define_split
4681 [(set (match_operand:SWI24 0 "register_operand")
4682 (fix:SWI24 (match_operand 1 "register_operand")))
4683 (use (match_operand:HI 2 "memory_operand"))
4684 (use (match_operand:HI 3 "memory_operand"))
4685 (clobber (match_operand:SWI24 4 "memory_operand"))]
4686 "reload_completed"
4687 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4688 (use (match_dup 2))
4689 (use (match_dup 3))])
4690 (set (match_dup 0) (match_dup 4))])
4691
4692 (define_split
4693 [(set (match_operand:SWI24 0 "memory_operand")
4694 (fix:SWI24 (match_operand 1 "register_operand")))
4695 (use (match_operand:HI 2 "memory_operand"))
4696 (use (match_operand:HI 3 "memory_operand"))
4697 (clobber (match_operand:SWI24 4 "memory_operand"))]
4698 "reload_completed"
4699 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4700 (use (match_dup 2))
4701 (use (match_dup 3))])])
4702
4703 (define_insn "x86_fnstcw_1"
4704 [(set (match_operand:HI 0 "memory_operand" "=m")
4705 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4706 "TARGET_80387"
4707 "fnstcw\t%0"
4708 [(set (attr "length")
4709 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4710 (set_attr "mode" "HI")
4711 (set_attr "unit" "i387")
4712 (set_attr "bdver1_decode" "vector")])
4713
4714 (define_insn "x86_fldcw_1"
4715 [(set (reg:HI FPCR_REG)
4716 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4717 "TARGET_80387"
4718 "fldcw\t%0"
4719 [(set (attr "length")
4720 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4721 (set_attr "mode" "HI")
4722 (set_attr "unit" "i387")
4723 (set_attr "athlon_decode" "vector")
4724 (set_attr "amdfam10_decode" "vector")
4725 (set_attr "bdver1_decode" "vector")])
4726 \f
4727 ;; Conversion between fixed point and floating point.
4728
4729 ;; Even though we only accept memory inputs, the backend _really_
4730 ;; wants to be able to do this between registers.
4731
4732 (define_expand "floathi<mode>2"
4733 [(set (match_operand:X87MODEF 0 "register_operand")
4734 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4735 "TARGET_80387
4736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4737 || TARGET_MIX_SSE_I387)")
4738
4739 ;; Pre-reload splitter to add memory clobber to the pattern.
4740 (define_insn_and_split "*floathi<mode>2_1"
4741 [(set (match_operand:X87MODEF 0 "register_operand")
4742 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4743 "TARGET_80387
4744 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4745 || TARGET_MIX_SSE_I387)
4746 && can_create_pseudo_p ()"
4747 "#"
4748 "&& 1"
4749 [(parallel [(set (match_dup 0)
4750 (float:X87MODEF (match_dup 1)))
4751 (clobber (match_dup 2))])]
4752 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4753
4754 (define_insn "*floathi<mode>2_i387_with_temp"
4755 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4756 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4757 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4758 "TARGET_80387
4759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4760 || TARGET_MIX_SSE_I387)"
4761 "#"
4762 [(set_attr "type" "fmov,multi")
4763 (set_attr "mode" "<MODE>")
4764 (set_attr "unit" "*,i387")
4765 (set_attr "fp_int_src" "true")])
4766
4767 (define_insn "*floathi<mode>2_i387"
4768 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4769 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4770 "TARGET_80387
4771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4772 || TARGET_MIX_SSE_I387)"
4773 "fild%Z1\t%1"
4774 [(set_attr "type" "fmov")
4775 (set_attr "mode" "<MODE>")
4776 (set_attr "fp_int_src" "true")])
4777
4778 (define_split
4779 [(set (match_operand:X87MODEF 0 "register_operand")
4780 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4781 (clobber (match_operand:HI 2 "memory_operand"))]
4782 "TARGET_80387
4783 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4784 || TARGET_MIX_SSE_I387)
4785 && reload_completed"
4786 [(set (match_dup 2) (match_dup 1))
4787 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4788
4789 (define_split
4790 [(set (match_operand:X87MODEF 0 "register_operand")
4791 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4792 (clobber (match_operand:HI 2 "memory_operand"))]
4793 "TARGET_80387
4794 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4795 || TARGET_MIX_SSE_I387)
4796 && reload_completed"
4797 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4798
4799 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4800 [(set (match_operand:X87MODEF 0 "register_operand")
4801 (float:X87MODEF
4802 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4803 "TARGET_80387
4804 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4805 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4806 {
4807 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4808 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4809 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4810 {
4811 rtx reg = gen_reg_rtx (XFmode);
4812 rtx (*insn)(rtx, rtx);
4813
4814 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4815
4816 if (<X87MODEF:MODE>mode == SFmode)
4817 insn = gen_truncxfsf2;
4818 else if (<X87MODEF:MODE>mode == DFmode)
4819 insn = gen_truncxfdf2;
4820 else
4821 gcc_unreachable ();
4822
4823 emit_insn (insn (operands[0], reg));
4824 DONE;
4825 }
4826 })
4827
4828 ;; Pre-reload splitter to add memory clobber to the pattern.
4829 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4830 [(set (match_operand:X87MODEF 0 "register_operand")
4831 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4832 "((TARGET_80387
4833 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4834 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4835 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4836 || TARGET_MIX_SSE_I387))
4837 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4838 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4839 && ((<SWI48x:MODE>mode == SImode
4840 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4841 && optimize_function_for_speed_p (cfun)
4842 && flag_trapping_math)
4843 || !(TARGET_INTER_UNIT_CONVERSIONS
4844 || optimize_function_for_size_p (cfun)))))
4845 && can_create_pseudo_p ()"
4846 "#"
4847 "&& 1"
4848 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4849 (clobber (match_dup 2))])]
4850 {
4851 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4852
4853 /* Avoid store forwarding (partial memory) stall penalty
4854 by passing DImode value through XMM registers. */
4855 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4856 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4857 && optimize_function_for_speed_p (cfun))
4858 {
4859 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4860 operands[1],
4861 operands[2]));
4862 DONE;
4863 }
4864 })
4865
4866 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4867 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4868 (float:MODEF
4869 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4870 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4871 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4872 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4873 "#"
4874 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4875 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4876 (set_attr "unit" "*,i387,*,*,*")
4877 (set_attr "athlon_decode" "*,*,double,direct,double")
4878 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4879 (set_attr "bdver1_decode" "*,*,double,direct,double")
4880 (set_attr "fp_int_src" "true")])
4881
4882 (define_insn "*floatsi<mode>2_vector_mixed"
4883 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4884 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4885 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4886 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4887 "@
4888 fild%Z1\t%1
4889 #"
4890 [(set_attr "type" "fmov,sseicvt")
4891 (set_attr "mode" "<MODE>,<ssevecmode>")
4892 (set_attr "unit" "i387,*")
4893 (set_attr "athlon_decode" "*,direct")
4894 (set_attr "amdfam10_decode" "*,double")
4895 (set_attr "bdver1_decode" "*,direct")
4896 (set_attr "fp_int_src" "true")])
4897
4898 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4899 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4900 (float:MODEF
4901 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4902 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4903 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4904 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4905 "#"
4906 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4907 (set_attr "mode" "<MODEF:MODE>")
4908 (set_attr "unit" "*,i387,*,*")
4909 (set_attr "athlon_decode" "*,*,double,direct")
4910 (set_attr "amdfam10_decode" "*,*,vector,double")
4911 (set_attr "bdver1_decode" "*,*,double,direct")
4912 (set_attr "fp_int_src" "true")])
4913
4914 (define_split
4915 [(set (match_operand:MODEF 0 "register_operand")
4916 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4917 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4918 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4919 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4920 && TARGET_INTER_UNIT_CONVERSIONS
4921 && reload_completed
4922 && (SSE_REG_P (operands[0])
4923 || (GET_CODE (operands[0]) == SUBREG
4924 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4925 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4926
4927 (define_split
4928 [(set (match_operand:MODEF 0 "register_operand")
4929 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4930 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4931 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4932 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4933 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4934 && reload_completed
4935 && (SSE_REG_P (operands[0])
4936 || (GET_CODE (operands[0]) == SUBREG
4937 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4938 [(set (match_dup 2) (match_dup 1))
4939 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4940
4941 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4942 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4943 (float:MODEF
4944 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4945 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4946 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4947 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4948 "@
4949 fild%Z1\t%1
4950 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4951 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4952 [(set_attr "type" "fmov,sseicvt,sseicvt")
4953 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4954 (set_attr "mode" "<MODEF:MODE>")
4955 (set (attr "prefix_rex")
4956 (if_then_else
4957 (and (eq_attr "prefix" "maybe_vex")
4958 (match_test "<SWI48x:MODE>mode == DImode"))
4959 (const_string "1")
4960 (const_string "*")))
4961 (set_attr "unit" "i387,*,*")
4962 (set_attr "athlon_decode" "*,double,direct")
4963 (set_attr "amdfam10_decode" "*,vector,double")
4964 (set_attr "bdver1_decode" "*,double,direct")
4965 (set_attr "fp_int_src" "true")])
4966
4967 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4968 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4969 (float:MODEF
4970 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4971 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4972 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4973 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4974 "@
4975 fild%Z1\t%1
4976 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4977 [(set_attr "type" "fmov,sseicvt")
4978 (set_attr "prefix" "orig,maybe_vex")
4979 (set_attr "mode" "<MODEF:MODE>")
4980 (set (attr "prefix_rex")
4981 (if_then_else
4982 (and (eq_attr "prefix" "maybe_vex")
4983 (match_test "<SWI48x:MODE>mode == DImode"))
4984 (const_string "1")
4985 (const_string "*")))
4986 (set_attr "athlon_decode" "*,direct")
4987 (set_attr "amdfam10_decode" "*,double")
4988 (set_attr "bdver1_decode" "*,direct")
4989 (set_attr "fp_int_src" "true")])
4990
4991 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4992 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4993 (float:MODEF
4994 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4995 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4996 "TARGET_SSE2 && TARGET_SSE_MATH
4997 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4998 "#"
4999 [(set_attr "type" "sseicvt")
5000 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5001 (set_attr "athlon_decode" "double,direct,double")
5002 (set_attr "amdfam10_decode" "vector,double,double")
5003 (set_attr "bdver1_decode" "double,direct,double")
5004 (set_attr "fp_int_src" "true")])
5005
5006 (define_insn "*floatsi<mode>2_vector_sse"
5007 [(set (match_operand:MODEF 0 "register_operand" "=x")
5008 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5009 "TARGET_SSE2 && TARGET_SSE_MATH
5010 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5011 "#"
5012 [(set_attr "type" "sseicvt")
5013 (set_attr "mode" "<MODE>")
5014 (set_attr "athlon_decode" "direct")
5015 (set_attr "amdfam10_decode" "double")
5016 (set_attr "bdver1_decode" "direct")
5017 (set_attr "fp_int_src" "true")])
5018
5019 (define_split
5020 [(set (match_operand:MODEF 0 "register_operand")
5021 (float:MODEF (match_operand:SI 1 "register_operand")))
5022 (clobber (match_operand:SI 2 "memory_operand"))]
5023 "TARGET_SSE2 && TARGET_SSE_MATH
5024 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5025 && reload_completed
5026 && (SSE_REG_P (operands[0])
5027 || (GET_CODE (operands[0]) == SUBREG
5028 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5029 [(const_int 0)]
5030 {
5031 rtx op1 = operands[1];
5032
5033 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5034 <MODE>mode, 0);
5035 if (GET_CODE (op1) == SUBREG)
5036 op1 = SUBREG_REG (op1);
5037
5038 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5039 {
5040 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5041 emit_insn (gen_sse2_loadld (operands[4],
5042 CONST0_RTX (V4SImode), operands[1]));
5043 }
5044 /* We can ignore possible trapping value in the
5045 high part of SSE register for non-trapping math. */
5046 else if (SSE_REG_P (op1) && !flag_trapping_math)
5047 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5048 else
5049 {
5050 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5051 emit_move_insn (operands[2], operands[1]);
5052 emit_insn (gen_sse2_loadld (operands[4],
5053 CONST0_RTX (V4SImode), operands[2]));
5054 }
5055 if (<ssevecmode>mode == V4SFmode)
5056 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5057 else
5058 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5059 DONE;
5060 })
5061
5062 (define_split
5063 [(set (match_operand:MODEF 0 "register_operand")
5064 (float:MODEF (match_operand:SI 1 "memory_operand")))
5065 (clobber (match_operand:SI 2 "memory_operand"))]
5066 "TARGET_SSE2 && TARGET_SSE_MATH
5067 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5068 && reload_completed
5069 && (SSE_REG_P (operands[0])
5070 || (GET_CODE (operands[0]) == SUBREG
5071 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5072 [(const_int 0)]
5073 {
5074 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5075 <MODE>mode, 0);
5076 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5077
5078 emit_insn (gen_sse2_loadld (operands[4],
5079 CONST0_RTX (V4SImode), operands[1]));
5080 if (<ssevecmode>mode == V4SFmode)
5081 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5082 else
5083 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5084 DONE;
5085 })
5086
5087 (define_split
5088 [(set (match_operand:MODEF 0 "register_operand")
5089 (float:MODEF (match_operand:SI 1 "register_operand")))]
5090 "TARGET_SSE2 && TARGET_SSE_MATH
5091 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5092 && reload_completed
5093 && (SSE_REG_P (operands[0])
5094 || (GET_CODE (operands[0]) == SUBREG
5095 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5096 [(const_int 0)]
5097 {
5098 rtx op1 = operands[1];
5099
5100 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5101 <MODE>mode, 0);
5102 if (GET_CODE (op1) == SUBREG)
5103 op1 = SUBREG_REG (op1);
5104
5105 if (GENERAL_REG_P (op1))
5106 {
5107 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5108 if (TARGET_INTER_UNIT_MOVES)
5109 emit_insn (gen_sse2_loadld (operands[4],
5110 CONST0_RTX (V4SImode), operands[1]));
5111 else
5112 {
5113 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5114 operands[1]);
5115 emit_insn (gen_sse2_loadld (operands[4],
5116 CONST0_RTX (V4SImode), operands[5]));
5117 ix86_free_from_memory (GET_MODE (operands[1]));
5118 }
5119 }
5120 /* We can ignore possible trapping value in the
5121 high part of SSE register for non-trapping math. */
5122 else if (SSE_REG_P (op1) && !flag_trapping_math)
5123 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5124 else
5125 gcc_unreachable ();
5126 if (<ssevecmode>mode == V4SFmode)
5127 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5128 else
5129 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5130 DONE;
5131 })
5132
5133 (define_split
5134 [(set (match_operand:MODEF 0 "register_operand")
5135 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5136 "TARGET_SSE2 && TARGET_SSE_MATH
5137 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5138 && reload_completed
5139 && (SSE_REG_P (operands[0])
5140 || (GET_CODE (operands[0]) == SUBREG
5141 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5142 [(const_int 0)]
5143 {
5144 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5145 <MODE>mode, 0);
5146 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5147
5148 emit_insn (gen_sse2_loadld (operands[4],
5149 CONST0_RTX (V4SImode), operands[1]));
5150 if (<ssevecmode>mode == V4SFmode)
5151 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5152 else
5153 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5154 DONE;
5155 })
5156
5157 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5158 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5159 (float:MODEF
5160 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5161 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5162 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5163 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5164 "#"
5165 [(set_attr "type" "sseicvt")
5166 (set_attr "mode" "<MODEF:MODE>")
5167 (set_attr "athlon_decode" "double,direct")
5168 (set_attr "amdfam10_decode" "vector,double")
5169 (set_attr "bdver1_decode" "double,direct")
5170 (set_attr "fp_int_src" "true")])
5171
5172 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5173 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5174 (float:MODEF
5175 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5176 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5177 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5178 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5179 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5180 [(set_attr "type" "sseicvt")
5181 (set_attr "prefix" "maybe_vex")
5182 (set_attr "mode" "<MODEF:MODE>")
5183 (set (attr "prefix_rex")
5184 (if_then_else
5185 (and (eq_attr "prefix" "maybe_vex")
5186 (match_test "<SWI48x:MODE>mode == DImode"))
5187 (const_string "1")
5188 (const_string "*")))
5189 (set_attr "athlon_decode" "double,direct")
5190 (set_attr "amdfam10_decode" "vector,double")
5191 (set_attr "bdver1_decode" "double,direct")
5192 (set_attr "fp_int_src" "true")])
5193
5194 (define_split
5195 [(set (match_operand:MODEF 0 "register_operand")
5196 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5197 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5198 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5199 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5200 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5201 && reload_completed
5202 && (SSE_REG_P (operands[0])
5203 || (GET_CODE (operands[0]) == SUBREG
5204 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5205 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5206
5207 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5208 [(set (match_operand:MODEF 0 "register_operand" "=x")
5209 (float:MODEF
5210 (match_operand:SWI48x 1 "memory_operand" "m")))]
5211 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5212 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5213 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5214 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5215 [(set_attr "type" "sseicvt")
5216 (set_attr "prefix" "maybe_vex")
5217 (set_attr "mode" "<MODEF:MODE>")
5218 (set (attr "prefix_rex")
5219 (if_then_else
5220 (and (eq_attr "prefix" "maybe_vex")
5221 (match_test "<SWI48x:MODE>mode == DImode"))
5222 (const_string "1")
5223 (const_string "*")))
5224 (set_attr "athlon_decode" "direct")
5225 (set_attr "amdfam10_decode" "double")
5226 (set_attr "bdver1_decode" "direct")
5227 (set_attr "fp_int_src" "true")])
5228
5229 (define_split
5230 [(set (match_operand:MODEF 0 "register_operand")
5231 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5232 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5233 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5234 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5235 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5236 && reload_completed
5237 && (SSE_REG_P (operands[0])
5238 || (GET_CODE (operands[0]) == SUBREG
5239 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5240 [(set (match_dup 2) (match_dup 1))
5241 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5242
5243 (define_split
5244 [(set (match_operand:MODEF 0 "register_operand")
5245 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5246 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5247 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5248 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5249 && reload_completed
5250 && (SSE_REG_P (operands[0])
5251 || (GET_CODE (operands[0]) == SUBREG
5252 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5253 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5254
5255 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5256 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5257 (float:X87MODEF
5258 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5259 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5260 "TARGET_80387
5261 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5262 "@
5263 fild%Z1\t%1
5264 #"
5265 [(set_attr "type" "fmov,multi")
5266 (set_attr "mode" "<X87MODEF:MODE>")
5267 (set_attr "unit" "*,i387")
5268 (set_attr "fp_int_src" "true")])
5269
5270 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5271 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5272 (float:X87MODEF
5273 (match_operand:SWI48x 1 "memory_operand" "m")))]
5274 "TARGET_80387
5275 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5276 "fild%Z1\t%1"
5277 [(set_attr "type" "fmov")
5278 (set_attr "mode" "<X87MODEF:MODE>")
5279 (set_attr "fp_int_src" "true")])
5280
5281 (define_split
5282 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5283 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5284 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5285 "TARGET_80387
5286 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5287 && reload_completed"
5288 [(set (match_dup 2) (match_dup 1))
5289 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5290
5291 (define_split
5292 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5293 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5294 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5295 "TARGET_80387
5296 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5297 && reload_completed"
5298 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5299
5300 ;; Avoid store forwarding (partial memory) stall penalty
5301 ;; by passing DImode value through XMM registers. */
5302
5303 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5304 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5305 (float:X87MODEF
5306 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5307 (clobber (match_scratch:V4SI 3 "=X,x"))
5308 (clobber (match_scratch:V4SI 4 "=X,x"))
5309 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5310 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5311 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5312 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5313 "#"
5314 [(set_attr "type" "multi")
5315 (set_attr "mode" "<X87MODEF:MODE>")
5316 (set_attr "unit" "i387")
5317 (set_attr "fp_int_src" "true")])
5318
5319 (define_split
5320 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5321 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5322 (clobber (match_scratch:V4SI 3))
5323 (clobber (match_scratch:V4SI 4))
5324 (clobber (match_operand:DI 2 "memory_operand"))]
5325 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5326 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5327 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5328 && reload_completed"
5329 [(set (match_dup 2) (match_dup 3))
5330 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5331 {
5332 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5333 Assemble the 64-bit DImode value in an xmm register. */
5334 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5335 gen_rtx_SUBREG (SImode, operands[1], 0)));
5336 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5337 gen_rtx_SUBREG (SImode, operands[1], 4)));
5338 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5339 operands[4]));
5340
5341 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5342 })
5343
5344 (define_split
5345 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5346 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5347 (clobber (match_scratch:V4SI 3))
5348 (clobber (match_scratch:V4SI 4))
5349 (clobber (match_operand:DI 2 "memory_operand"))]
5350 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5351 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5352 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5353 && reload_completed"
5354 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5355
5356 ;; Avoid store forwarding (partial memory) stall penalty by extending
5357 ;; SImode value to DImode through XMM register instead of pushing two
5358 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5359 ;; targets benefit from this optimization. Also note that fild
5360 ;; loads from memory only.
5361
5362 (define_insn "*floatunssi<mode>2_1"
5363 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5364 (unsigned_float:X87MODEF
5365 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5366 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5367 (clobber (match_scratch:SI 3 "=X,x"))]
5368 "!TARGET_64BIT
5369 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5370 && TARGET_SSE"
5371 "#"
5372 [(set_attr "type" "multi")
5373 (set_attr "mode" "<MODE>")])
5374
5375 (define_split
5376 [(set (match_operand:X87MODEF 0 "register_operand")
5377 (unsigned_float:X87MODEF
5378 (match_operand:SI 1 "register_operand")))
5379 (clobber (match_operand:DI 2 "memory_operand"))
5380 (clobber (match_scratch:SI 3))]
5381 "!TARGET_64BIT
5382 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5383 && TARGET_SSE
5384 && reload_completed"
5385 [(set (match_dup 2) (match_dup 1))
5386 (set (match_dup 0)
5387 (float:X87MODEF (match_dup 2)))]
5388 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5389
5390 (define_split
5391 [(set (match_operand:X87MODEF 0 "register_operand")
5392 (unsigned_float:X87MODEF
5393 (match_operand:SI 1 "memory_operand")))
5394 (clobber (match_operand:DI 2 "memory_operand"))
5395 (clobber (match_scratch:SI 3))]
5396 "!TARGET_64BIT
5397 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5398 && TARGET_SSE
5399 && reload_completed"
5400 [(set (match_dup 2) (match_dup 3))
5401 (set (match_dup 0)
5402 (float:X87MODEF (match_dup 2)))]
5403 {
5404 emit_move_insn (operands[3], operands[1]);
5405 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5406 })
5407
5408 (define_expand "floatunssi<mode>2"
5409 [(parallel
5410 [(set (match_operand:X87MODEF 0 "register_operand")
5411 (unsigned_float:X87MODEF
5412 (match_operand:SI 1 "nonimmediate_operand")))
5413 (clobber (match_dup 2))
5414 (clobber (match_scratch:SI 3))])]
5415 "!TARGET_64BIT
5416 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5417 && TARGET_SSE)
5418 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5419 {
5420 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5421 {
5422 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5423 DONE;
5424 }
5425 else
5426 {
5427 enum ix86_stack_slot slot = (virtuals_instantiated
5428 ? SLOT_TEMP
5429 : SLOT_VIRTUAL);
5430 operands[2] = assign_386_stack_local (DImode, slot);
5431 }
5432 })
5433
5434 (define_expand "floatunsdisf2"
5435 [(use (match_operand:SF 0 "register_operand"))
5436 (use (match_operand:DI 1 "nonimmediate_operand"))]
5437 "TARGET_64BIT && TARGET_SSE_MATH"
5438 "x86_emit_floatuns (operands); DONE;")
5439
5440 (define_expand "floatunsdidf2"
5441 [(use (match_operand:DF 0 "register_operand"))
5442 (use (match_operand:DI 1 "nonimmediate_operand"))]
5443 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5444 && TARGET_SSE2 && TARGET_SSE_MATH"
5445 {
5446 if (TARGET_64BIT)
5447 x86_emit_floatuns (operands);
5448 else
5449 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5450 DONE;
5451 })
5452 \f
5453 ;; Add instructions
5454
5455 (define_expand "add<mode>3"
5456 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5457 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5458 (match_operand:SDWIM 2 "<general_operand>")))]
5459 ""
5460 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5461
5462 (define_insn_and_split "*add<dwi>3_doubleword"
5463 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5464 (plus:<DWI>
5465 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5466 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5467 (clobber (reg:CC FLAGS_REG))]
5468 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5469 "#"
5470 "reload_completed"
5471 [(parallel [(set (reg:CC FLAGS_REG)
5472 (unspec:CC [(match_dup 1) (match_dup 2)]
5473 UNSPEC_ADD_CARRY))
5474 (set (match_dup 0)
5475 (plus:DWIH (match_dup 1) (match_dup 2)))])
5476 (parallel [(set (match_dup 3)
5477 (plus:DWIH
5478 (match_dup 4)
5479 (plus:DWIH
5480 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5481 (match_dup 5))))
5482 (clobber (reg:CC FLAGS_REG))])]
5483 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5484
5485 (define_insn "*add<mode>3_cc"
5486 [(set (reg:CC FLAGS_REG)
5487 (unspec:CC
5488 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5489 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5490 UNSPEC_ADD_CARRY))
5491 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5492 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5493 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5494 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5495 [(set_attr "type" "alu")
5496 (set_attr "mode" "<MODE>")])
5497
5498 (define_insn "addqi3_cc"
5499 [(set (reg:CC FLAGS_REG)
5500 (unspec:CC
5501 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5502 (match_operand:QI 2 "general_operand" "qn,qm")]
5503 UNSPEC_ADD_CARRY))
5504 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5505 (plus:QI (match_dup 1) (match_dup 2)))]
5506 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5507 "add{b}\t{%2, %0|%0, %2}"
5508 [(set_attr "type" "alu")
5509 (set_attr "mode" "QI")])
5510
5511 (define_insn_and_split "*lea_1"
5512 [(set (match_operand:SI 0 "register_operand" "=r")
5513 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5514 "TARGET_64BIT"
5515 "lea{l}\t{%E1, %0|%0, %E1}"
5516 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5517 [(const_int 0)]
5518 {
5519 ix86_split_lea_for_addr (operands, SImode);
5520 DONE;
5521 }
5522 [(set_attr "type" "lea")
5523 (set_attr "mode" "SI")])
5524
5525 (define_insn_and_split "*lea<mode>_2"
5526 [(set (match_operand:SWI48 0 "register_operand" "=r")
5527 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5528 ""
5529 "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5530 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5531 [(const_int 0)]
5532 {
5533 ix86_split_lea_for_addr (operands, <MODE>mode);
5534 DONE;
5535 }
5536 [(set_attr "type" "lea")
5537 (set_attr "mode" "<MODE>")])
5538
5539 (define_insn "*lea_3_zext"
5540 [(set (match_operand:DI 0 "register_operand" "=r")
5541 (zero_extend:DI
5542 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5543 "TARGET_64BIT"
5544 "lea{l}\t{%E1, %k0|%k0, %E1}"
5545 [(set_attr "type" "lea")
5546 (set_attr "mode" "SI")])
5547
5548 (define_insn "*lea_4_zext"
5549 [(set (match_operand:DI 0 "register_operand" "=r")
5550 (zero_extend:DI
5551 (match_operand:SI 1 "lea_address_operand" "j")))]
5552 "TARGET_64BIT"
5553 "lea{l}\t{%E1, %k0|%k0, %E1}"
5554 [(set_attr "type" "lea")
5555 (set_attr "mode" "SI")])
5556
5557 (define_insn "*lea_5_zext"
5558 [(set (match_operand:DI 0 "register_operand" "=r")
5559 (and:DI
5560 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5561 (match_operand:DI 2 "const_32bit_mask" "n")))]
5562 "TARGET_64BIT"
5563 "lea{l}\t{%E1, %k0|%k0, %E1}"
5564 [(set_attr "type" "lea")
5565 (set_attr "mode" "SI")])
5566
5567 (define_insn "*lea_6_zext"
5568 [(set (match_operand:DI 0 "register_operand" "=r")
5569 (and:DI
5570 (match_operand:DI 1 "lea_address_operand" "p")
5571 (match_operand:DI 2 "const_32bit_mask" "n")))]
5572 "TARGET_64BIT"
5573 "lea{l}\t{%E1, %k0|%k0, %E1}"
5574 [(set_attr "type" "lea")
5575 (set_attr "mode" "SI")])
5576
5577 (define_insn "*add<mode>_1"
5578 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5579 (plus:SWI48
5580 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5581 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5582 (clobber (reg:CC FLAGS_REG))]
5583 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5584 {
5585 switch (get_attr_type (insn))
5586 {
5587 case TYPE_LEA:
5588 return "#";
5589
5590 case TYPE_INCDEC:
5591 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5592 if (operands[2] == const1_rtx)
5593 return "inc{<imodesuffix>}\t%0";
5594 else
5595 {
5596 gcc_assert (operands[2] == constm1_rtx);
5597 return "dec{<imodesuffix>}\t%0";
5598 }
5599
5600 default:
5601 /* For most processors, ADD is faster than LEA. This alternative
5602 was added to use ADD as much as possible. */
5603 if (which_alternative == 2)
5604 {
5605 rtx tmp;
5606 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5607 }
5608
5609 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5610 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5611 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5612
5613 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5614 }
5615 }
5616 [(set (attr "type")
5617 (cond [(eq_attr "alternative" "3")
5618 (const_string "lea")
5619 (match_operand:SWI48 2 "incdec_operand")
5620 (const_string "incdec")
5621 ]
5622 (const_string "alu")))
5623 (set (attr "length_immediate")
5624 (if_then_else
5625 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5626 (const_string "1")
5627 (const_string "*")))
5628 (set_attr "mode" "<MODE>")])
5629
5630 ;; It may seem that nonimmediate operand is proper one for operand 1.
5631 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5632 ;; we take care in ix86_binary_operator_ok to not allow two memory
5633 ;; operands so proper swapping will be done in reload. This allow
5634 ;; patterns constructed from addsi_1 to match.
5635
5636 (define_insn "addsi_1_zext"
5637 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5638 (zero_extend:DI
5639 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5640 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5641 (clobber (reg:CC FLAGS_REG))]
5642 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5643 {
5644 switch (get_attr_type (insn))
5645 {
5646 case TYPE_LEA:
5647 return "#";
5648
5649 case TYPE_INCDEC:
5650 if (operands[2] == const1_rtx)
5651 return "inc{l}\t%k0";
5652 else
5653 {
5654 gcc_assert (operands[2] == constm1_rtx);
5655 return "dec{l}\t%k0";
5656 }
5657
5658 default:
5659 /* For most processors, ADD is faster than LEA. This alternative
5660 was added to use ADD as much as possible. */
5661 if (which_alternative == 1)
5662 {
5663 rtx tmp;
5664 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5665 }
5666
5667 if (x86_maybe_negate_const_int (&operands[2], SImode))
5668 return "sub{l}\t{%2, %k0|%k0, %2}";
5669
5670 return "add{l}\t{%2, %k0|%k0, %2}";
5671 }
5672 }
5673 [(set (attr "type")
5674 (cond [(eq_attr "alternative" "2")
5675 (const_string "lea")
5676 (match_operand:SI 2 "incdec_operand")
5677 (const_string "incdec")
5678 ]
5679 (const_string "alu")))
5680 (set (attr "length_immediate")
5681 (if_then_else
5682 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5683 (const_string "1")
5684 (const_string "*")))
5685 (set_attr "mode" "SI")])
5686
5687 (define_insn "*addhi_1"
5688 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5689 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5690 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5691 (clobber (reg:CC FLAGS_REG))]
5692 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5693 {
5694 switch (get_attr_type (insn))
5695 {
5696 case TYPE_LEA:
5697 return "#";
5698
5699 case TYPE_INCDEC:
5700 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5701 if (operands[2] == const1_rtx)
5702 return "inc{w}\t%0";
5703 else
5704 {
5705 gcc_assert (operands[2] == constm1_rtx);
5706 return "dec{w}\t%0";
5707 }
5708
5709 default:
5710 /* For most processors, ADD is faster than LEA. This alternative
5711 was added to use ADD as much as possible. */
5712 if (which_alternative == 2)
5713 {
5714 rtx tmp;
5715 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5716 }
5717
5718 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5719 if (x86_maybe_negate_const_int (&operands[2], HImode))
5720 return "sub{w}\t{%2, %0|%0, %2}";
5721
5722 return "add{w}\t{%2, %0|%0, %2}";
5723 }
5724 }
5725 [(set (attr "type")
5726 (cond [(eq_attr "alternative" "3")
5727 (const_string "lea")
5728 (match_operand:HI 2 "incdec_operand")
5729 (const_string "incdec")
5730 ]
5731 (const_string "alu")))
5732 (set (attr "length_immediate")
5733 (if_then_else
5734 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5735 (const_string "1")
5736 (const_string "*")))
5737 (set_attr "mode" "HI,HI,HI,SI")])
5738
5739 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5740 (define_insn "*addqi_1"
5741 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5742 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5743 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5744 (clobber (reg:CC FLAGS_REG))]
5745 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5746 {
5747 bool widen = (which_alternative == 3 || which_alternative == 4);
5748
5749 switch (get_attr_type (insn))
5750 {
5751 case TYPE_LEA:
5752 return "#";
5753
5754 case TYPE_INCDEC:
5755 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5756 if (operands[2] == const1_rtx)
5757 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5758 else
5759 {
5760 gcc_assert (operands[2] == constm1_rtx);
5761 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5762 }
5763
5764 default:
5765 /* For most processors, ADD is faster than LEA. These alternatives
5766 were added to use ADD as much as possible. */
5767 if (which_alternative == 2 || which_alternative == 4)
5768 {
5769 rtx tmp;
5770 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5771 }
5772
5773 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5774 if (x86_maybe_negate_const_int (&operands[2], QImode))
5775 {
5776 if (widen)
5777 return "sub{l}\t{%2, %k0|%k0, %2}";
5778 else
5779 return "sub{b}\t{%2, %0|%0, %2}";
5780 }
5781 if (widen)
5782 return "add{l}\t{%k2, %k0|%k0, %k2}";
5783 else
5784 return "add{b}\t{%2, %0|%0, %2}";
5785 }
5786 }
5787 [(set (attr "type")
5788 (cond [(eq_attr "alternative" "5")
5789 (const_string "lea")
5790 (match_operand:QI 2 "incdec_operand")
5791 (const_string "incdec")
5792 ]
5793 (const_string "alu")))
5794 (set (attr "length_immediate")
5795 (if_then_else
5796 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5797 (const_string "1")
5798 (const_string "*")))
5799 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5800
5801 (define_insn "*addqi_1_slp"
5802 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5803 (plus:QI (match_dup 0)
5804 (match_operand:QI 1 "general_operand" "qn,qm")))
5805 (clobber (reg:CC FLAGS_REG))]
5806 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5808 {
5809 switch (get_attr_type (insn))
5810 {
5811 case TYPE_INCDEC:
5812 if (operands[1] == const1_rtx)
5813 return "inc{b}\t%0";
5814 else
5815 {
5816 gcc_assert (operands[1] == constm1_rtx);
5817 return "dec{b}\t%0";
5818 }
5819
5820 default:
5821 if (x86_maybe_negate_const_int (&operands[1], QImode))
5822 return "sub{b}\t{%1, %0|%0, %1}";
5823
5824 return "add{b}\t{%1, %0|%0, %1}";
5825 }
5826 }
5827 [(set (attr "type")
5828 (if_then_else (match_operand:QI 1 "incdec_operand")
5829 (const_string "incdec")
5830 (const_string "alu1")))
5831 (set (attr "memory")
5832 (if_then_else (match_operand 1 "memory_operand")
5833 (const_string "load")
5834 (const_string "none")))
5835 (set_attr "mode" "QI")])
5836
5837 ;; Split non destructive adds if we cannot use lea.
5838 (define_split
5839 [(set (match_operand:SWI48 0 "register_operand")
5840 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5841 (match_operand:SWI48 2 "nonmemory_operand")))
5842 (clobber (reg:CC FLAGS_REG))]
5843 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5844 [(set (match_dup 0) (match_dup 1))
5845 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5846 (clobber (reg:CC FLAGS_REG))])])
5847
5848 ;; Convert add to the lea pattern to avoid flags dependency.
5849 (define_split
5850 [(set (match_operand:SWI 0 "register_operand")
5851 (plus:SWI (match_operand:SWI 1 "register_operand")
5852 (match_operand:SWI 2 "<nonmemory_operand>")))
5853 (clobber (reg:CC FLAGS_REG))]
5854 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5855 [(const_int 0)]
5856 {
5857 enum machine_mode mode = <MODE>mode;
5858 rtx pat;
5859
5860 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5861 {
5862 mode = SImode;
5863 operands[0] = gen_lowpart (mode, operands[0]);
5864 operands[1] = gen_lowpart (mode, operands[1]);
5865 operands[2] = gen_lowpart (mode, operands[2]);
5866 }
5867
5868 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5869
5870 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5871 DONE;
5872 })
5873
5874 ;; Convert add to the lea pattern to avoid flags dependency.
5875 (define_split
5876 [(set (match_operand:DI 0 "register_operand")
5877 (zero_extend:DI
5878 (plus:SI (match_operand:SI 1 "register_operand")
5879 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5880 (clobber (reg:CC FLAGS_REG))]
5881 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5882 [(set (match_dup 0)
5883 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5884
5885 (define_insn "*add<mode>_2"
5886 [(set (reg FLAGS_REG)
5887 (compare
5888 (plus:SWI
5889 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5890 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5891 (const_int 0)))
5892 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5893 (plus:SWI (match_dup 1) (match_dup 2)))]
5894 "ix86_match_ccmode (insn, CCGOCmode)
5895 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5896 {
5897 switch (get_attr_type (insn))
5898 {
5899 case TYPE_INCDEC:
5900 if (operands[2] == const1_rtx)
5901 return "inc{<imodesuffix>}\t%0";
5902 else
5903 {
5904 gcc_assert (operands[2] == constm1_rtx);
5905 return "dec{<imodesuffix>}\t%0";
5906 }
5907
5908 default:
5909 if (which_alternative == 2)
5910 {
5911 rtx tmp;
5912 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5913 }
5914
5915 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5916 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5917 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5918
5919 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5920 }
5921 }
5922 [(set (attr "type")
5923 (if_then_else (match_operand:SWI 2 "incdec_operand")
5924 (const_string "incdec")
5925 (const_string "alu")))
5926 (set (attr "length_immediate")
5927 (if_then_else
5928 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5929 (const_string "1")
5930 (const_string "*")))
5931 (set_attr "mode" "<MODE>")])
5932
5933 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5934 (define_insn "*addsi_2_zext"
5935 [(set (reg FLAGS_REG)
5936 (compare
5937 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5938 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5939 (const_int 0)))
5940 (set (match_operand:DI 0 "register_operand" "=r,r")
5941 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5942 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5943 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5944 {
5945 switch (get_attr_type (insn))
5946 {
5947 case TYPE_INCDEC:
5948 if (operands[2] == const1_rtx)
5949 return "inc{l}\t%k0";
5950 else
5951 {
5952 gcc_assert (operands[2] == constm1_rtx);
5953 return "dec{l}\t%k0";
5954 }
5955
5956 default:
5957 if (which_alternative == 1)
5958 {
5959 rtx tmp;
5960 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5961 }
5962
5963 if (x86_maybe_negate_const_int (&operands[2], SImode))
5964 return "sub{l}\t{%2, %k0|%k0, %2}";
5965
5966 return "add{l}\t{%2, %k0|%k0, %2}";
5967 }
5968 }
5969 [(set (attr "type")
5970 (if_then_else (match_operand:SI 2 "incdec_operand")
5971 (const_string "incdec")
5972 (const_string "alu")))
5973 (set (attr "length_immediate")
5974 (if_then_else
5975 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5976 (const_string "1")
5977 (const_string "*")))
5978 (set_attr "mode" "SI")])
5979
5980 (define_insn "*add<mode>_3"
5981 [(set (reg FLAGS_REG)
5982 (compare
5983 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5984 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5985 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5986 "ix86_match_ccmode (insn, CCZmode)
5987 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5988 {
5989 switch (get_attr_type (insn))
5990 {
5991 case TYPE_INCDEC:
5992 if (operands[2] == const1_rtx)
5993 return "inc{<imodesuffix>}\t%0";
5994 else
5995 {
5996 gcc_assert (operands[2] == constm1_rtx);
5997 return "dec{<imodesuffix>}\t%0";
5998 }
5999
6000 default:
6001 if (which_alternative == 1)
6002 {
6003 rtx tmp;
6004 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6005 }
6006
6007 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6008 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6009 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6010
6011 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6012 }
6013 }
6014 [(set (attr "type")
6015 (if_then_else (match_operand:SWI 2 "incdec_operand")
6016 (const_string "incdec")
6017 (const_string "alu")))
6018 (set (attr "length_immediate")
6019 (if_then_else
6020 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6021 (const_string "1")
6022 (const_string "*")))
6023 (set_attr "mode" "<MODE>")])
6024
6025 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6026 (define_insn "*addsi_3_zext"
6027 [(set (reg FLAGS_REG)
6028 (compare
6029 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6030 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6031 (set (match_operand:DI 0 "register_operand" "=r,r")
6032 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6033 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6034 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6035 {
6036 switch (get_attr_type (insn))
6037 {
6038 case TYPE_INCDEC:
6039 if (operands[2] == const1_rtx)
6040 return "inc{l}\t%k0";
6041 else
6042 {
6043 gcc_assert (operands[2] == constm1_rtx);
6044 return "dec{l}\t%k0";
6045 }
6046
6047 default:
6048 if (which_alternative == 1)
6049 {
6050 rtx tmp;
6051 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6052 }
6053
6054 if (x86_maybe_negate_const_int (&operands[2], SImode))
6055 return "sub{l}\t{%2, %k0|%k0, %2}";
6056
6057 return "add{l}\t{%2, %k0|%k0, %2}";
6058 }
6059 }
6060 [(set (attr "type")
6061 (if_then_else (match_operand:SI 2 "incdec_operand")
6062 (const_string "incdec")
6063 (const_string "alu")))
6064 (set (attr "length_immediate")
6065 (if_then_else
6066 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6067 (const_string "1")
6068 (const_string "*")))
6069 (set_attr "mode" "SI")])
6070
6071 ; For comparisons against 1, -1 and 128, we may generate better code
6072 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6073 ; is matched then. We can't accept general immediate, because for
6074 ; case of overflows, the result is messed up.
6075 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6076 ; only for comparisons not depending on it.
6077
6078 (define_insn "*adddi_4"
6079 [(set (reg FLAGS_REG)
6080 (compare
6081 (match_operand:DI 1 "nonimmediate_operand" "0")
6082 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6083 (clobber (match_scratch:DI 0 "=rm"))]
6084 "TARGET_64BIT
6085 && ix86_match_ccmode (insn, CCGCmode)"
6086 {
6087 switch (get_attr_type (insn))
6088 {
6089 case TYPE_INCDEC:
6090 if (operands[2] == constm1_rtx)
6091 return "inc{q}\t%0";
6092 else
6093 {
6094 gcc_assert (operands[2] == const1_rtx);
6095 return "dec{q}\t%0";
6096 }
6097
6098 default:
6099 if (x86_maybe_negate_const_int (&operands[2], DImode))
6100 return "add{q}\t{%2, %0|%0, %2}";
6101
6102 return "sub{q}\t{%2, %0|%0, %2}";
6103 }
6104 }
6105 [(set (attr "type")
6106 (if_then_else (match_operand:DI 2 "incdec_operand")
6107 (const_string "incdec")
6108 (const_string "alu")))
6109 (set (attr "length_immediate")
6110 (if_then_else
6111 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6112 (const_string "1")
6113 (const_string "*")))
6114 (set_attr "mode" "DI")])
6115
6116 ; For comparisons against 1, -1 and 128, we may generate better code
6117 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6118 ; is matched then. We can't accept general immediate, because for
6119 ; case of overflows, the result is messed up.
6120 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6121 ; only for comparisons not depending on it.
6122
6123 (define_insn "*add<mode>_4"
6124 [(set (reg FLAGS_REG)
6125 (compare
6126 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6127 (match_operand:SWI124 2 "const_int_operand" "n")))
6128 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6129 "ix86_match_ccmode (insn, CCGCmode)"
6130 {
6131 switch (get_attr_type (insn))
6132 {
6133 case TYPE_INCDEC:
6134 if (operands[2] == constm1_rtx)
6135 return "inc{<imodesuffix>}\t%0";
6136 else
6137 {
6138 gcc_assert (operands[2] == const1_rtx);
6139 return "dec{<imodesuffix>}\t%0";
6140 }
6141
6142 default:
6143 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6144 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6145
6146 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6147 }
6148 }
6149 [(set (attr "type")
6150 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6151 (const_string "incdec")
6152 (const_string "alu")))
6153 (set (attr "length_immediate")
6154 (if_then_else
6155 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6156 (const_string "1")
6157 (const_string "*")))
6158 (set_attr "mode" "<MODE>")])
6159
6160 (define_insn "*add<mode>_5"
6161 [(set (reg FLAGS_REG)
6162 (compare
6163 (plus:SWI
6164 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6165 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6166 (const_int 0)))
6167 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6168 "ix86_match_ccmode (insn, CCGOCmode)
6169 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6170 {
6171 switch (get_attr_type (insn))
6172 {
6173 case TYPE_INCDEC:
6174 if (operands[2] == const1_rtx)
6175 return "inc{<imodesuffix>}\t%0";
6176 else
6177 {
6178 gcc_assert (operands[2] == constm1_rtx);
6179 return "dec{<imodesuffix>}\t%0";
6180 }
6181
6182 default:
6183 if (which_alternative == 1)
6184 {
6185 rtx tmp;
6186 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6187 }
6188
6189 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6190 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6191 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6192
6193 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6194 }
6195 }
6196 [(set (attr "type")
6197 (if_then_else (match_operand:SWI 2 "incdec_operand")
6198 (const_string "incdec")
6199 (const_string "alu")))
6200 (set (attr "length_immediate")
6201 (if_then_else
6202 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6203 (const_string "1")
6204 (const_string "*")))
6205 (set_attr "mode" "<MODE>")])
6206
6207 (define_insn "*addqi_ext_1_rex64"
6208 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6209 (const_int 8)
6210 (const_int 8))
6211 (plus:SI
6212 (zero_extract:SI
6213 (match_operand 1 "ext_register_operand" "0")
6214 (const_int 8)
6215 (const_int 8))
6216 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6217 (clobber (reg:CC FLAGS_REG))]
6218 "TARGET_64BIT"
6219 {
6220 switch (get_attr_type (insn))
6221 {
6222 case TYPE_INCDEC:
6223 if (operands[2] == const1_rtx)
6224 return "inc{b}\t%h0";
6225 else
6226 {
6227 gcc_assert (operands[2] == constm1_rtx);
6228 return "dec{b}\t%h0";
6229 }
6230
6231 default:
6232 return "add{b}\t{%2, %h0|%h0, %2}";
6233 }
6234 }
6235 [(set (attr "type")
6236 (if_then_else (match_operand:QI 2 "incdec_operand")
6237 (const_string "incdec")
6238 (const_string "alu")))
6239 (set_attr "modrm" "1")
6240 (set_attr "mode" "QI")])
6241
6242 (define_insn "addqi_ext_1"
6243 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6244 (const_int 8)
6245 (const_int 8))
6246 (plus:SI
6247 (zero_extract:SI
6248 (match_operand 1 "ext_register_operand" "0")
6249 (const_int 8)
6250 (const_int 8))
6251 (match_operand:QI 2 "general_operand" "Qmn")))
6252 (clobber (reg:CC FLAGS_REG))]
6253 "!TARGET_64BIT"
6254 {
6255 switch (get_attr_type (insn))
6256 {
6257 case TYPE_INCDEC:
6258 if (operands[2] == const1_rtx)
6259 return "inc{b}\t%h0";
6260 else
6261 {
6262 gcc_assert (operands[2] == constm1_rtx);
6263 return "dec{b}\t%h0";
6264 }
6265
6266 default:
6267 return "add{b}\t{%2, %h0|%h0, %2}";
6268 }
6269 }
6270 [(set (attr "type")
6271 (if_then_else (match_operand:QI 2 "incdec_operand")
6272 (const_string "incdec")
6273 (const_string "alu")))
6274 (set_attr "modrm" "1")
6275 (set_attr "mode" "QI")])
6276
6277 (define_insn "*addqi_ext_2"
6278 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6279 (const_int 8)
6280 (const_int 8))
6281 (plus:SI
6282 (zero_extract:SI
6283 (match_operand 1 "ext_register_operand" "%0")
6284 (const_int 8)
6285 (const_int 8))
6286 (zero_extract:SI
6287 (match_operand 2 "ext_register_operand" "Q")
6288 (const_int 8)
6289 (const_int 8))))
6290 (clobber (reg:CC FLAGS_REG))]
6291 ""
6292 "add{b}\t{%h2, %h0|%h0, %h2}"
6293 [(set_attr "type" "alu")
6294 (set_attr "mode" "QI")])
6295
6296 ;; The lea patterns for modes less than 32 bits need to be matched by
6297 ;; several insns converted to real lea by splitters.
6298
6299 (define_insn_and_split "*lea_general_1"
6300 [(set (match_operand 0 "register_operand" "=r")
6301 (plus (plus (match_operand 1 "index_register_operand" "l")
6302 (match_operand 2 "register_operand" "r"))
6303 (match_operand 3 "immediate_operand" "i")))]
6304 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6305 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6306 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6307 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6308 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6309 || GET_MODE (operands[3]) == VOIDmode)"
6310 "#"
6311 "&& reload_completed"
6312 [(const_int 0)]
6313 {
6314 enum machine_mode mode = SImode;
6315 rtx pat;
6316
6317 operands[0] = gen_lowpart (mode, operands[0]);
6318 operands[1] = gen_lowpart (mode, operands[1]);
6319 operands[2] = gen_lowpart (mode, operands[2]);
6320 operands[3] = gen_lowpart (mode, operands[3]);
6321
6322 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6323 operands[3]);
6324
6325 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6326 DONE;
6327 }
6328 [(set_attr "type" "lea")
6329 (set_attr "mode" "SI")])
6330
6331 (define_insn_and_split "*lea_general_2"
6332 [(set (match_operand 0 "register_operand" "=r")
6333 (plus (mult (match_operand 1 "index_register_operand" "l")
6334 (match_operand 2 "const248_operand" "n"))
6335 (match_operand 3 "nonmemory_operand" "ri")))]
6336 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6337 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6338 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6339 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6340 || GET_MODE (operands[3]) == VOIDmode)"
6341 "#"
6342 "&& reload_completed"
6343 [(const_int 0)]
6344 {
6345 enum machine_mode mode = SImode;
6346 rtx pat;
6347
6348 operands[0] = gen_lowpart (mode, operands[0]);
6349 operands[1] = gen_lowpart (mode, operands[1]);
6350 operands[3] = gen_lowpart (mode, operands[3]);
6351
6352 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6353 operands[3]);
6354
6355 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6356 DONE;
6357 }
6358 [(set_attr "type" "lea")
6359 (set_attr "mode" "SI")])
6360
6361 (define_insn_and_split "*lea_general_3"
6362 [(set (match_operand 0 "register_operand" "=r")
6363 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6364 (match_operand 2 "const248_operand" "n"))
6365 (match_operand 3 "register_operand" "r"))
6366 (match_operand 4 "immediate_operand" "i")))]
6367 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6368 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6369 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6370 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6371 "#"
6372 "&& reload_completed"
6373 [(const_int 0)]
6374 {
6375 enum machine_mode mode = SImode;
6376 rtx pat;
6377
6378 operands[0] = gen_lowpart (mode, operands[0]);
6379 operands[1] = gen_lowpart (mode, operands[1]);
6380 operands[3] = gen_lowpart (mode, operands[3]);
6381 operands[4] = gen_lowpart (mode, operands[4]);
6382
6383 pat = gen_rtx_PLUS (mode,
6384 gen_rtx_PLUS (mode,
6385 gen_rtx_MULT (mode, operands[1],
6386 operands[2]),
6387 operands[3]),
6388 operands[4]);
6389
6390 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6391 DONE;
6392 }
6393 [(set_attr "type" "lea")
6394 (set_attr "mode" "SI")])
6395
6396 (define_insn_and_split "*lea_general_4"
6397 [(set (match_operand 0 "register_operand" "=r")
6398 (any_or (ashift
6399 (match_operand 1 "index_register_operand" "l")
6400 (match_operand 2 "const_int_operand" "n"))
6401 (match_operand 3 "const_int_operand" "n")))]
6402 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6403 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6404 || GET_MODE (operands[0]) == SImode
6405 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6406 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6407 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6408 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6409 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6410 "#"
6411 "&& reload_completed"
6412 [(const_int 0)]
6413 {
6414 enum machine_mode mode = GET_MODE (operands[0]);
6415 rtx pat;
6416
6417 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6418 {
6419 mode = SImode;
6420 operands[0] = gen_lowpart (mode, operands[0]);
6421 operands[1] = gen_lowpart (mode, operands[1]);
6422 }
6423
6424 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6425
6426 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6427 INTVAL (operands[3]));
6428
6429 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6430 DONE;
6431 }
6432 [(set_attr "type" "lea")
6433 (set (attr "mode")
6434 (if_then_else (match_operand:DI 0)
6435 (const_string "DI")
6436 (const_string "SI")))])
6437 \f
6438 ;; Subtract instructions
6439
6440 (define_expand "sub<mode>3"
6441 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6442 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6443 (match_operand:SDWIM 2 "<general_operand>")))]
6444 ""
6445 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6446
6447 (define_insn_and_split "*sub<dwi>3_doubleword"
6448 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6449 (minus:<DWI>
6450 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6451 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6452 (clobber (reg:CC FLAGS_REG))]
6453 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6454 "#"
6455 "reload_completed"
6456 [(parallel [(set (reg:CC FLAGS_REG)
6457 (compare:CC (match_dup 1) (match_dup 2)))
6458 (set (match_dup 0)
6459 (minus:DWIH (match_dup 1) (match_dup 2)))])
6460 (parallel [(set (match_dup 3)
6461 (minus:DWIH
6462 (match_dup 4)
6463 (plus:DWIH
6464 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6465 (match_dup 5))))
6466 (clobber (reg:CC FLAGS_REG))])]
6467 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6468
6469 (define_insn "*sub<mode>_1"
6470 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6471 (minus:SWI
6472 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6473 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6474 (clobber (reg:CC FLAGS_REG))]
6475 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6476 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6477 [(set_attr "type" "alu")
6478 (set_attr "mode" "<MODE>")])
6479
6480 (define_insn "*subsi_1_zext"
6481 [(set (match_operand:DI 0 "register_operand" "=r")
6482 (zero_extend:DI
6483 (minus:SI (match_operand:SI 1 "register_operand" "0")
6484 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6485 (clobber (reg:CC FLAGS_REG))]
6486 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6487 "sub{l}\t{%2, %k0|%k0, %2}"
6488 [(set_attr "type" "alu")
6489 (set_attr "mode" "SI")])
6490
6491 (define_insn "*subqi_1_slp"
6492 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6493 (minus:QI (match_dup 0)
6494 (match_operand:QI 1 "general_operand" "qn,qm")))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6497 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6498 "sub{b}\t{%1, %0|%0, %1}"
6499 [(set_attr "type" "alu1")
6500 (set_attr "mode" "QI")])
6501
6502 (define_insn "*sub<mode>_2"
6503 [(set (reg FLAGS_REG)
6504 (compare
6505 (minus:SWI
6506 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6507 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6508 (const_int 0)))
6509 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6510 (minus:SWI (match_dup 1) (match_dup 2)))]
6511 "ix86_match_ccmode (insn, CCGOCmode)
6512 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6513 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6514 [(set_attr "type" "alu")
6515 (set_attr "mode" "<MODE>")])
6516
6517 (define_insn "*subsi_2_zext"
6518 [(set (reg FLAGS_REG)
6519 (compare
6520 (minus:SI (match_operand:SI 1 "register_operand" "0")
6521 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6522 (const_int 0)))
6523 (set (match_operand:DI 0 "register_operand" "=r")
6524 (zero_extend:DI
6525 (minus:SI (match_dup 1)
6526 (match_dup 2))))]
6527 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6528 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6529 "sub{l}\t{%2, %k0|%k0, %2}"
6530 [(set_attr "type" "alu")
6531 (set_attr "mode" "SI")])
6532
6533 (define_insn "*sub<mode>_3"
6534 [(set (reg FLAGS_REG)
6535 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6536 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6537 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6538 (minus:SWI (match_dup 1) (match_dup 2)))]
6539 "ix86_match_ccmode (insn, CCmode)
6540 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6541 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6542 [(set_attr "type" "alu")
6543 (set_attr "mode" "<MODE>")])
6544
6545 (define_insn "*subsi_3_zext"
6546 [(set (reg FLAGS_REG)
6547 (compare (match_operand:SI 1 "register_operand" "0")
6548 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6549 (set (match_operand:DI 0 "register_operand" "=r")
6550 (zero_extend:DI
6551 (minus:SI (match_dup 1)
6552 (match_dup 2))))]
6553 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6554 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6555 "sub{l}\t{%2, %1|%1, %2}"
6556 [(set_attr "type" "alu")
6557 (set_attr "mode" "SI")])
6558 \f
6559 ;; Add with carry and subtract with borrow
6560
6561 (define_expand "<plusminus_insn><mode>3_carry"
6562 [(parallel
6563 [(set (match_operand:SWI 0 "nonimmediate_operand")
6564 (plusminus:SWI
6565 (match_operand:SWI 1 "nonimmediate_operand")
6566 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6567 [(match_operand 3 "flags_reg_operand")
6568 (const_int 0)])
6569 (match_operand:SWI 2 "<general_operand>"))))
6570 (clobber (reg:CC FLAGS_REG))])]
6571 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6572
6573 (define_insn "*<plusminus_insn><mode>3_carry"
6574 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6575 (plusminus:SWI
6576 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6577 (plus:SWI
6578 (match_operator 3 "ix86_carry_flag_operator"
6579 [(reg FLAGS_REG) (const_int 0)])
6580 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6581 (clobber (reg:CC FLAGS_REG))]
6582 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6583 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6584 [(set_attr "type" "alu")
6585 (set_attr "use_carry" "1")
6586 (set_attr "pent_pair" "pu")
6587 (set_attr "mode" "<MODE>")])
6588
6589 (define_insn "*addsi3_carry_zext"
6590 [(set (match_operand:DI 0 "register_operand" "=r")
6591 (zero_extend:DI
6592 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6593 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6594 [(reg FLAGS_REG) (const_int 0)])
6595 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6598 "adc{l}\t{%2, %k0|%k0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "use_carry" "1")
6601 (set_attr "pent_pair" "pu")
6602 (set_attr "mode" "SI")])
6603
6604 (define_insn "*subsi3_carry_zext"
6605 [(set (match_operand:DI 0 "register_operand" "=r")
6606 (zero_extend:DI
6607 (minus:SI (match_operand:SI 1 "register_operand" "0")
6608 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6609 [(reg FLAGS_REG) (const_int 0)])
6610 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6613 "sbb{l}\t{%2, %k0|%k0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "pent_pair" "pu")
6616 (set_attr "mode" "SI")])
6617 \f
6618 ;; Overflow setting add and subtract instructions
6619
6620 (define_insn "*add<mode>3_cconly_overflow"
6621 [(set (reg:CCC FLAGS_REG)
6622 (compare:CCC
6623 (plus:SWI
6624 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6625 (match_operand:SWI 2 "<general_operand>" "<g>"))
6626 (match_dup 1)))
6627 (clobber (match_scratch:SWI 0 "=<r>"))]
6628 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6629 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "mode" "<MODE>")])
6632
6633 (define_insn "*sub<mode>3_cconly_overflow"
6634 [(set (reg:CCC FLAGS_REG)
6635 (compare:CCC
6636 (minus:SWI
6637 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6638 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6639 (match_dup 0)))]
6640 ""
6641 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6642 [(set_attr "type" "icmp")
6643 (set_attr "mode" "<MODE>")])
6644
6645 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6646 [(set (reg:CCC FLAGS_REG)
6647 (compare:CCC
6648 (plusminus:SWI
6649 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6650 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6651 (match_dup 1)))
6652 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6653 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6654 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6655 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6656 [(set_attr "type" "alu")
6657 (set_attr "mode" "<MODE>")])
6658
6659 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6660 [(set (reg:CCC FLAGS_REG)
6661 (compare:CCC
6662 (plusminus:SI
6663 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6664 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6665 (match_dup 1)))
6666 (set (match_operand:DI 0 "register_operand" "=r")
6667 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6668 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6669 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "mode" "SI")])
6672
6673 ;; The patterns that match these are at the end of this file.
6674
6675 (define_expand "<plusminus_insn>xf3"
6676 [(set (match_operand:XF 0 "register_operand")
6677 (plusminus:XF
6678 (match_operand:XF 1 "register_operand")
6679 (match_operand:XF 2 "register_operand")))]
6680 "TARGET_80387")
6681
6682 (define_expand "<plusminus_insn><mode>3"
6683 [(set (match_operand:MODEF 0 "register_operand")
6684 (plusminus:MODEF
6685 (match_operand:MODEF 1 "register_operand")
6686 (match_operand:MODEF 2 "nonimmediate_operand")))]
6687 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6688 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6689 \f
6690 ;; Multiply instructions
6691
6692 (define_expand "mul<mode>3"
6693 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6694 (mult:SWIM248
6695 (match_operand:SWIM248 1 "register_operand")
6696 (match_operand:SWIM248 2 "<general_operand>")))
6697 (clobber (reg:CC FLAGS_REG))])])
6698
6699 (define_expand "mulqi3"
6700 [(parallel [(set (match_operand:QI 0 "register_operand")
6701 (mult:QI
6702 (match_operand:QI 1 "register_operand")
6703 (match_operand:QI 2 "nonimmediate_operand")))
6704 (clobber (reg:CC FLAGS_REG))])]
6705 "TARGET_QIMODE_MATH")
6706
6707 ;; On AMDFAM10
6708 ;; IMUL reg32/64, reg32/64, imm8 Direct
6709 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6710 ;; IMUL reg32/64, reg32/64, imm32 Direct
6711 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6712 ;; IMUL reg32/64, reg32/64 Direct
6713 ;; IMUL reg32/64, mem32/64 Direct
6714 ;;
6715 ;; On BDVER1, all above IMULs use DirectPath
6716
6717 (define_insn "*mul<mode>3_1"
6718 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6719 (mult:SWI48
6720 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6721 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6722 (clobber (reg:CC FLAGS_REG))]
6723 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6724 "@
6725 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6726 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6727 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6728 [(set_attr "type" "imul")
6729 (set_attr "prefix_0f" "0,0,1")
6730 (set (attr "athlon_decode")
6731 (cond [(eq_attr "cpu" "athlon")
6732 (const_string "vector")
6733 (eq_attr "alternative" "1")
6734 (const_string "vector")
6735 (and (eq_attr "alternative" "2")
6736 (match_operand 1 "memory_operand"))
6737 (const_string "vector")]
6738 (const_string "direct")))
6739 (set (attr "amdfam10_decode")
6740 (cond [(and (eq_attr "alternative" "0,1")
6741 (match_operand 1 "memory_operand"))
6742 (const_string "vector")]
6743 (const_string "direct")))
6744 (set_attr "bdver1_decode" "direct")
6745 (set_attr "mode" "<MODE>")])
6746
6747 (define_insn "*mulsi3_1_zext"
6748 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6749 (zero_extend:DI
6750 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6751 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6752 (clobber (reg:CC FLAGS_REG))]
6753 "TARGET_64BIT
6754 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6755 "@
6756 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6757 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6758 imul{l}\t{%2, %k0|%k0, %2}"
6759 [(set_attr "type" "imul")
6760 (set_attr "prefix_0f" "0,0,1")
6761 (set (attr "athlon_decode")
6762 (cond [(eq_attr "cpu" "athlon")
6763 (const_string "vector")
6764 (eq_attr "alternative" "1")
6765 (const_string "vector")
6766 (and (eq_attr "alternative" "2")
6767 (match_operand 1 "memory_operand"))
6768 (const_string "vector")]
6769 (const_string "direct")))
6770 (set (attr "amdfam10_decode")
6771 (cond [(and (eq_attr "alternative" "0,1")
6772 (match_operand 1 "memory_operand"))
6773 (const_string "vector")]
6774 (const_string "direct")))
6775 (set_attr "bdver1_decode" "direct")
6776 (set_attr "mode" "SI")])
6777
6778 ;; On AMDFAM10
6779 ;; IMUL reg16, reg16, imm8 VectorPath
6780 ;; IMUL reg16, mem16, imm8 VectorPath
6781 ;; IMUL reg16, reg16, imm16 VectorPath
6782 ;; IMUL reg16, mem16, imm16 VectorPath
6783 ;; IMUL reg16, reg16 Direct
6784 ;; IMUL reg16, mem16 Direct
6785 ;;
6786 ;; On BDVER1, all HI MULs use DoublePath
6787
6788 (define_insn "*mulhi3_1"
6789 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6790 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6791 (match_operand:HI 2 "general_operand" "K,n,mr")))
6792 (clobber (reg:CC FLAGS_REG))]
6793 "TARGET_HIMODE_MATH
6794 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6795 "@
6796 imul{w}\t{%2, %1, %0|%0, %1, %2}
6797 imul{w}\t{%2, %1, %0|%0, %1, %2}
6798 imul{w}\t{%2, %0|%0, %2}"
6799 [(set_attr "type" "imul")
6800 (set_attr "prefix_0f" "0,0,1")
6801 (set (attr "athlon_decode")
6802 (cond [(eq_attr "cpu" "athlon")
6803 (const_string "vector")
6804 (eq_attr "alternative" "1,2")
6805 (const_string "vector")]
6806 (const_string "direct")))
6807 (set (attr "amdfam10_decode")
6808 (cond [(eq_attr "alternative" "0,1")
6809 (const_string "vector")]
6810 (const_string "direct")))
6811 (set_attr "bdver1_decode" "double")
6812 (set_attr "mode" "HI")])
6813
6814 ;;On AMDFAM10 and BDVER1
6815 ;; MUL reg8 Direct
6816 ;; MUL mem8 Direct
6817
6818 (define_insn "*mulqi3_1"
6819 [(set (match_operand:QI 0 "register_operand" "=a")
6820 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6821 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6822 (clobber (reg:CC FLAGS_REG))]
6823 "TARGET_QIMODE_MATH
6824 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6825 "mul{b}\t%2"
6826 [(set_attr "type" "imul")
6827 (set_attr "length_immediate" "0")
6828 (set (attr "athlon_decode")
6829 (if_then_else (eq_attr "cpu" "athlon")
6830 (const_string "vector")
6831 (const_string "direct")))
6832 (set_attr "amdfam10_decode" "direct")
6833 (set_attr "bdver1_decode" "direct")
6834 (set_attr "mode" "QI")])
6835
6836 (define_expand "<u>mul<mode><dwi>3"
6837 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6838 (mult:<DWI>
6839 (any_extend:<DWI>
6840 (match_operand:DWIH 1 "nonimmediate_operand"))
6841 (any_extend:<DWI>
6842 (match_operand:DWIH 2 "register_operand"))))
6843 (clobber (reg:CC FLAGS_REG))])])
6844
6845 (define_expand "<u>mulqihi3"
6846 [(parallel [(set (match_operand:HI 0 "register_operand")
6847 (mult:HI
6848 (any_extend:HI
6849 (match_operand:QI 1 "nonimmediate_operand"))
6850 (any_extend:HI
6851 (match_operand:QI 2 "register_operand"))))
6852 (clobber (reg:CC FLAGS_REG))])]
6853 "TARGET_QIMODE_MATH")
6854
6855 (define_insn "*bmi2_umulditi3_1"
6856 [(set (match_operand:DI 0 "register_operand" "=r")
6857 (mult:DI
6858 (match_operand:DI 2 "nonimmediate_operand" "%d")
6859 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6860 (set (match_operand:DI 1 "register_operand" "=r")
6861 (truncate:DI
6862 (lshiftrt:TI
6863 (mult:TI (zero_extend:TI (match_dup 2))
6864 (zero_extend:TI (match_dup 3)))
6865 (const_int 64))))]
6866 "TARGET_64BIT && TARGET_BMI2
6867 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6868 "mulx\t{%3, %0, %1|%1, %0, %3}"
6869 [(set_attr "type" "imulx")
6870 (set_attr "prefix" "vex")
6871 (set_attr "mode" "DI")])
6872
6873 (define_insn "*bmi2_umulsidi3_1"
6874 [(set (match_operand:SI 0 "register_operand" "=r")
6875 (mult:SI
6876 (match_operand:SI 2 "nonimmediate_operand" "%d")
6877 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6878 (set (match_operand:SI 1 "register_operand" "=r")
6879 (truncate:SI
6880 (lshiftrt:DI
6881 (mult:DI (zero_extend:DI (match_dup 2))
6882 (zero_extend:DI (match_dup 3)))
6883 (const_int 32))))]
6884 "!TARGET_64BIT && TARGET_BMI2
6885 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6886 "mulx\t{%3, %0, %1|%1, %0, %3}"
6887 [(set_attr "type" "imulx")
6888 (set_attr "prefix" "vex")
6889 (set_attr "mode" "SI")])
6890
6891 (define_insn "*umul<mode><dwi>3_1"
6892 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6893 (mult:<DWI>
6894 (zero_extend:<DWI>
6895 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6896 (zero_extend:<DWI>
6897 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6898 (clobber (reg:CC FLAGS_REG))]
6899 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6900 "@
6901 #
6902 mul{<imodesuffix>}\t%2"
6903 [(set_attr "isa" "bmi2,*")
6904 (set_attr "type" "imulx,imul")
6905 (set_attr "length_immediate" "*,0")
6906 (set (attr "athlon_decode")
6907 (cond [(eq_attr "alternative" "1")
6908 (if_then_else (eq_attr "cpu" "athlon")
6909 (const_string "vector")
6910 (const_string "double"))]
6911 (const_string "*")))
6912 (set_attr "amdfam10_decode" "*,double")
6913 (set_attr "bdver1_decode" "*,direct")
6914 (set_attr "prefix" "vex,orig")
6915 (set_attr "mode" "<MODE>")])
6916
6917 ;; Convert mul to the mulx pattern to avoid flags dependency.
6918 (define_split
6919 [(set (match_operand:<DWI> 0 "register_operand")
6920 (mult:<DWI>
6921 (zero_extend:<DWI>
6922 (match_operand:DWIH 1 "register_operand"))
6923 (zero_extend:<DWI>
6924 (match_operand:DWIH 2 "nonimmediate_operand"))))
6925 (clobber (reg:CC FLAGS_REG))]
6926 "TARGET_BMI2 && reload_completed
6927 && true_regnum (operands[1]) == DX_REG"
6928 [(parallel [(set (match_dup 3)
6929 (mult:DWIH (match_dup 1) (match_dup 2)))
6930 (set (match_dup 4)
6931 (truncate:DWIH
6932 (lshiftrt:<DWI>
6933 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6934 (zero_extend:<DWI> (match_dup 2)))
6935 (match_dup 5))))])]
6936 {
6937 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6938
6939 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6940 })
6941
6942 (define_insn "*mul<mode><dwi>3_1"
6943 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6944 (mult:<DWI>
6945 (sign_extend:<DWI>
6946 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6947 (sign_extend:<DWI>
6948 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6951 "imul{<imodesuffix>}\t%2"
6952 [(set_attr "type" "imul")
6953 (set_attr "length_immediate" "0")
6954 (set (attr "athlon_decode")
6955 (if_then_else (eq_attr "cpu" "athlon")
6956 (const_string "vector")
6957 (const_string "double")))
6958 (set_attr "amdfam10_decode" "double")
6959 (set_attr "bdver1_decode" "direct")
6960 (set_attr "mode" "<MODE>")])
6961
6962 (define_insn "*<u>mulqihi3_1"
6963 [(set (match_operand:HI 0 "register_operand" "=a")
6964 (mult:HI
6965 (any_extend:HI
6966 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6967 (any_extend:HI
6968 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6969 (clobber (reg:CC FLAGS_REG))]
6970 "TARGET_QIMODE_MATH
6971 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6972 "<sgnprefix>mul{b}\t%2"
6973 [(set_attr "type" "imul")
6974 (set_attr "length_immediate" "0")
6975 (set (attr "athlon_decode")
6976 (if_then_else (eq_attr "cpu" "athlon")
6977 (const_string "vector")
6978 (const_string "direct")))
6979 (set_attr "amdfam10_decode" "direct")
6980 (set_attr "bdver1_decode" "direct")
6981 (set_attr "mode" "QI")])
6982
6983 (define_expand "<s>mul<mode>3_highpart"
6984 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6985 (truncate:SWI48
6986 (lshiftrt:<DWI>
6987 (mult:<DWI>
6988 (any_extend:<DWI>
6989 (match_operand:SWI48 1 "nonimmediate_operand"))
6990 (any_extend:<DWI>
6991 (match_operand:SWI48 2 "register_operand")))
6992 (match_dup 4))))
6993 (clobber (match_scratch:SWI48 3))
6994 (clobber (reg:CC FLAGS_REG))])]
6995 ""
6996 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6997
6998 (define_insn "*<s>muldi3_highpart_1"
6999 [(set (match_operand:DI 0 "register_operand" "=d")
7000 (truncate:DI
7001 (lshiftrt:TI
7002 (mult:TI
7003 (any_extend:TI
7004 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7005 (any_extend:TI
7006 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7007 (const_int 64))))
7008 (clobber (match_scratch:DI 3 "=1"))
7009 (clobber (reg:CC FLAGS_REG))]
7010 "TARGET_64BIT
7011 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7012 "<sgnprefix>mul{q}\t%2"
7013 [(set_attr "type" "imul")
7014 (set_attr "length_immediate" "0")
7015 (set (attr "athlon_decode")
7016 (if_then_else (eq_attr "cpu" "athlon")
7017 (const_string "vector")
7018 (const_string "double")))
7019 (set_attr "amdfam10_decode" "double")
7020 (set_attr "bdver1_decode" "direct")
7021 (set_attr "mode" "DI")])
7022
7023 (define_insn "*<s>mulsi3_highpart_1"
7024 [(set (match_operand:SI 0 "register_operand" "=d")
7025 (truncate:SI
7026 (lshiftrt:DI
7027 (mult:DI
7028 (any_extend:DI
7029 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7030 (any_extend:DI
7031 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7032 (const_int 32))))
7033 (clobber (match_scratch:SI 3 "=1"))
7034 (clobber (reg:CC FLAGS_REG))]
7035 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7036 "<sgnprefix>mul{l}\t%2"
7037 [(set_attr "type" "imul")
7038 (set_attr "length_immediate" "0")
7039 (set (attr "athlon_decode")
7040 (if_then_else (eq_attr "cpu" "athlon")
7041 (const_string "vector")
7042 (const_string "double")))
7043 (set_attr "amdfam10_decode" "double")
7044 (set_attr "bdver1_decode" "direct")
7045 (set_attr "mode" "SI")])
7046
7047 (define_insn "*<s>mulsi3_highpart_zext"
7048 [(set (match_operand:DI 0 "register_operand" "=d")
7049 (zero_extend:DI (truncate:SI
7050 (lshiftrt:DI
7051 (mult:DI (any_extend:DI
7052 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7053 (any_extend:DI
7054 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7055 (const_int 32)))))
7056 (clobber (match_scratch:SI 3 "=1"))
7057 (clobber (reg:CC FLAGS_REG))]
7058 "TARGET_64BIT
7059 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7060 "<sgnprefix>mul{l}\t%2"
7061 [(set_attr "type" "imul")
7062 (set_attr "length_immediate" "0")
7063 (set (attr "athlon_decode")
7064 (if_then_else (eq_attr "cpu" "athlon")
7065 (const_string "vector")
7066 (const_string "double")))
7067 (set_attr "amdfam10_decode" "double")
7068 (set_attr "bdver1_decode" "direct")
7069 (set_attr "mode" "SI")])
7070
7071 ;; The patterns that match these are at the end of this file.
7072
7073 (define_expand "mulxf3"
7074 [(set (match_operand:XF 0 "register_operand")
7075 (mult:XF (match_operand:XF 1 "register_operand")
7076 (match_operand:XF 2 "register_operand")))]
7077 "TARGET_80387")
7078
7079 (define_expand "mul<mode>3"
7080 [(set (match_operand:MODEF 0 "register_operand")
7081 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7082 (match_operand:MODEF 2 "nonimmediate_operand")))]
7083 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7084 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7085 \f
7086 ;; Divide instructions
7087
7088 ;; The patterns that match these are at the end of this file.
7089
7090 (define_expand "divxf3"
7091 [(set (match_operand:XF 0 "register_operand")
7092 (div:XF (match_operand:XF 1 "register_operand")
7093 (match_operand:XF 2 "register_operand")))]
7094 "TARGET_80387")
7095
7096 (define_expand "divdf3"
7097 [(set (match_operand:DF 0 "register_operand")
7098 (div:DF (match_operand:DF 1 "register_operand")
7099 (match_operand:DF 2 "nonimmediate_operand")))]
7100 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7101 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7102
7103 (define_expand "divsf3"
7104 [(set (match_operand:SF 0 "register_operand")
7105 (div:SF (match_operand:SF 1 "register_operand")
7106 (match_operand:SF 2 "nonimmediate_operand")))]
7107 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7108 || TARGET_SSE_MATH"
7109 {
7110 if (TARGET_SSE_MATH
7111 && TARGET_RECIP_DIV
7112 && optimize_insn_for_speed_p ()
7113 && flag_finite_math_only && !flag_trapping_math
7114 && flag_unsafe_math_optimizations)
7115 {
7116 ix86_emit_swdivsf (operands[0], operands[1],
7117 operands[2], SFmode);
7118 DONE;
7119 }
7120 })
7121 \f
7122 ;; Divmod instructions.
7123
7124 (define_expand "divmod<mode>4"
7125 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7126 (div:SWIM248
7127 (match_operand:SWIM248 1 "register_operand")
7128 (match_operand:SWIM248 2 "nonimmediate_operand")))
7129 (set (match_operand:SWIM248 3 "register_operand")
7130 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7131 (clobber (reg:CC FLAGS_REG))])])
7132
7133 ;; Split with 8bit unsigned divide:
7134 ;; if (dividend an divisor are in [0-255])
7135 ;; use 8bit unsigned integer divide
7136 ;; else
7137 ;; use original integer divide
7138 (define_split
7139 [(set (match_operand:SWI48 0 "register_operand")
7140 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7141 (match_operand:SWI48 3 "nonimmediate_operand")))
7142 (set (match_operand:SWI48 1 "register_operand")
7143 (mod:SWI48 (match_dup 2) (match_dup 3)))
7144 (clobber (reg:CC FLAGS_REG))]
7145 "TARGET_USE_8BIT_IDIV
7146 && TARGET_QIMODE_MATH
7147 && can_create_pseudo_p ()
7148 && !optimize_insn_for_size_p ()"
7149 [(const_int 0)]
7150 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7151
7152 (define_insn_and_split "divmod<mode>4_1"
7153 [(set (match_operand:SWI48 0 "register_operand" "=a")
7154 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7155 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7156 (set (match_operand:SWI48 1 "register_operand" "=&d")
7157 (mod:SWI48 (match_dup 2) (match_dup 3)))
7158 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7159 (clobber (reg:CC FLAGS_REG))]
7160 ""
7161 "#"
7162 "reload_completed"
7163 [(parallel [(set (match_dup 1)
7164 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7165 (clobber (reg:CC FLAGS_REG))])
7166 (parallel [(set (match_dup 0)
7167 (div:SWI48 (match_dup 2) (match_dup 3)))
7168 (set (match_dup 1)
7169 (mod:SWI48 (match_dup 2) (match_dup 3)))
7170 (use (match_dup 1))
7171 (clobber (reg:CC FLAGS_REG))])]
7172 {
7173 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7174
7175 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7176 operands[4] = operands[2];
7177 else
7178 {
7179 /* Avoid use of cltd in favor of a mov+shift. */
7180 emit_move_insn (operands[1], operands[2]);
7181 operands[4] = operands[1];
7182 }
7183 }
7184 [(set_attr "type" "multi")
7185 (set_attr "mode" "<MODE>")])
7186
7187 (define_insn_and_split "*divmod<mode>4"
7188 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7189 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7190 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7191 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7192 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7193 (clobber (reg:CC FLAGS_REG))]
7194 ""
7195 "#"
7196 "reload_completed"
7197 [(parallel [(set (match_dup 1)
7198 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7199 (clobber (reg:CC FLAGS_REG))])
7200 (parallel [(set (match_dup 0)
7201 (div:SWIM248 (match_dup 2) (match_dup 3)))
7202 (set (match_dup 1)
7203 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7204 (use (match_dup 1))
7205 (clobber (reg:CC FLAGS_REG))])]
7206 {
7207 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7208
7209 if (<MODE>mode != HImode
7210 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7211 operands[4] = operands[2];
7212 else
7213 {
7214 /* Avoid use of cltd in favor of a mov+shift. */
7215 emit_move_insn (operands[1], operands[2]);
7216 operands[4] = operands[1];
7217 }
7218 }
7219 [(set_attr "type" "multi")
7220 (set_attr "mode" "<MODE>")])
7221
7222 (define_insn "*divmod<mode>4_noext"
7223 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7224 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7225 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7226 (set (match_operand:SWIM248 1 "register_operand" "=d")
7227 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7228 (use (match_operand:SWIM248 4 "register_operand" "1"))
7229 (clobber (reg:CC FLAGS_REG))]
7230 ""
7231 "idiv{<imodesuffix>}\t%3"
7232 [(set_attr "type" "idiv")
7233 (set_attr "mode" "<MODE>")])
7234
7235 (define_expand "divmodqi4"
7236 [(parallel [(set (match_operand:QI 0 "register_operand")
7237 (div:QI
7238 (match_operand:QI 1 "register_operand")
7239 (match_operand:QI 2 "nonimmediate_operand")))
7240 (set (match_operand:QI 3 "register_operand")
7241 (mod:QI (match_dup 1) (match_dup 2)))
7242 (clobber (reg:CC FLAGS_REG))])]
7243 "TARGET_QIMODE_MATH"
7244 {
7245 rtx div, mod, insn;
7246 rtx tmp0, tmp1;
7247
7248 tmp0 = gen_reg_rtx (HImode);
7249 tmp1 = gen_reg_rtx (HImode);
7250
7251 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7252 in AX. */
7253 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7254 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7255
7256 /* Extract remainder from AH. */
7257 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7258 insn = emit_move_insn (operands[3], tmp1);
7259
7260 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7261 set_unique_reg_note (insn, REG_EQUAL, mod);
7262
7263 /* Extract quotient from AL. */
7264 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7265
7266 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7267 set_unique_reg_note (insn, REG_EQUAL, div);
7268
7269 DONE;
7270 })
7271
7272 ;; Divide AX by r/m8, with result stored in
7273 ;; AL <- Quotient
7274 ;; AH <- Remainder
7275 ;; Change div/mod to HImode and extend the second argument to HImode
7276 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7277 ;; combine may fail.
7278 (define_insn "divmodhiqi3"
7279 [(set (match_operand:HI 0 "register_operand" "=a")
7280 (ior:HI
7281 (ashift:HI
7282 (zero_extend:HI
7283 (truncate:QI
7284 (mod:HI (match_operand:HI 1 "register_operand" "0")
7285 (sign_extend:HI
7286 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7287 (const_int 8))
7288 (zero_extend:HI
7289 (truncate:QI
7290 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7291 (clobber (reg:CC FLAGS_REG))]
7292 "TARGET_QIMODE_MATH"
7293 "idiv{b}\t%2"
7294 [(set_attr "type" "idiv")
7295 (set_attr "mode" "QI")])
7296
7297 (define_expand "udivmod<mode>4"
7298 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7299 (udiv:SWIM248
7300 (match_operand:SWIM248 1 "register_operand")
7301 (match_operand:SWIM248 2 "nonimmediate_operand")))
7302 (set (match_operand:SWIM248 3 "register_operand")
7303 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7304 (clobber (reg:CC FLAGS_REG))])])
7305
7306 ;; Split with 8bit unsigned divide:
7307 ;; if (dividend an divisor are in [0-255])
7308 ;; use 8bit unsigned integer divide
7309 ;; else
7310 ;; use original integer divide
7311 (define_split
7312 [(set (match_operand:SWI48 0 "register_operand")
7313 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7314 (match_operand:SWI48 3 "nonimmediate_operand")))
7315 (set (match_operand:SWI48 1 "register_operand")
7316 (umod:SWI48 (match_dup 2) (match_dup 3)))
7317 (clobber (reg:CC FLAGS_REG))]
7318 "TARGET_USE_8BIT_IDIV
7319 && TARGET_QIMODE_MATH
7320 && can_create_pseudo_p ()
7321 && !optimize_insn_for_size_p ()"
7322 [(const_int 0)]
7323 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7324
7325 (define_insn_and_split "udivmod<mode>4_1"
7326 [(set (match_operand:SWI48 0 "register_operand" "=a")
7327 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7328 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7329 (set (match_operand:SWI48 1 "register_operand" "=&d")
7330 (umod:SWI48 (match_dup 2) (match_dup 3)))
7331 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7332 (clobber (reg:CC FLAGS_REG))]
7333 ""
7334 "#"
7335 "reload_completed"
7336 [(set (match_dup 1) (const_int 0))
7337 (parallel [(set (match_dup 0)
7338 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7339 (set (match_dup 1)
7340 (umod:SWI48 (match_dup 2) (match_dup 3)))
7341 (use (match_dup 1))
7342 (clobber (reg:CC FLAGS_REG))])]
7343 ""
7344 [(set_attr "type" "multi")
7345 (set_attr "mode" "<MODE>")])
7346
7347 (define_insn_and_split "*udivmod<mode>4"
7348 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7349 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7350 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7351 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7352 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7353 (clobber (reg:CC FLAGS_REG))]
7354 ""
7355 "#"
7356 "reload_completed"
7357 [(set (match_dup 1) (const_int 0))
7358 (parallel [(set (match_dup 0)
7359 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7360 (set (match_dup 1)
7361 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7362 (use (match_dup 1))
7363 (clobber (reg:CC FLAGS_REG))])]
7364 ""
7365 [(set_attr "type" "multi")
7366 (set_attr "mode" "<MODE>")])
7367
7368 (define_insn "*udivmod<mode>4_noext"
7369 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7370 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7371 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7372 (set (match_operand:SWIM248 1 "register_operand" "=d")
7373 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7374 (use (match_operand:SWIM248 4 "register_operand" "1"))
7375 (clobber (reg:CC FLAGS_REG))]
7376 ""
7377 "div{<imodesuffix>}\t%3"
7378 [(set_attr "type" "idiv")
7379 (set_attr "mode" "<MODE>")])
7380
7381 (define_expand "udivmodqi4"
7382 [(parallel [(set (match_operand:QI 0 "register_operand")
7383 (udiv:QI
7384 (match_operand:QI 1 "register_operand")
7385 (match_operand:QI 2 "nonimmediate_operand")))
7386 (set (match_operand:QI 3 "register_operand")
7387 (umod:QI (match_dup 1) (match_dup 2)))
7388 (clobber (reg:CC FLAGS_REG))])]
7389 "TARGET_QIMODE_MATH"
7390 {
7391 rtx div, mod, insn;
7392 rtx tmp0, tmp1;
7393
7394 tmp0 = gen_reg_rtx (HImode);
7395 tmp1 = gen_reg_rtx (HImode);
7396
7397 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7398 in AX. */
7399 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7400 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7401
7402 /* Extract remainder from AH. */
7403 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7404 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7405 insn = emit_move_insn (operands[3], tmp1);
7406
7407 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7408 set_unique_reg_note (insn, REG_EQUAL, mod);
7409
7410 /* Extract quotient from AL. */
7411 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7412
7413 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7414 set_unique_reg_note (insn, REG_EQUAL, div);
7415
7416 DONE;
7417 })
7418
7419 (define_insn "udivmodhiqi3"
7420 [(set (match_operand:HI 0 "register_operand" "=a")
7421 (ior:HI
7422 (ashift:HI
7423 (zero_extend:HI
7424 (truncate:QI
7425 (mod:HI (match_operand:HI 1 "register_operand" "0")
7426 (zero_extend:HI
7427 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7428 (const_int 8))
7429 (zero_extend:HI
7430 (truncate:QI
7431 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7432 (clobber (reg:CC FLAGS_REG))]
7433 "TARGET_QIMODE_MATH"
7434 "div{b}\t%2"
7435 [(set_attr "type" "idiv")
7436 (set_attr "mode" "QI")])
7437
7438 ;; We cannot use div/idiv for double division, because it causes
7439 ;; "division by zero" on the overflow and that's not what we expect
7440 ;; from truncate. Because true (non truncating) double division is
7441 ;; never generated, we can't create this insn anyway.
7442 ;
7443 ;(define_insn ""
7444 ; [(set (match_operand:SI 0 "register_operand" "=a")
7445 ; (truncate:SI
7446 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7447 ; (zero_extend:DI
7448 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7449 ; (set (match_operand:SI 3 "register_operand" "=d")
7450 ; (truncate:SI
7451 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7452 ; (clobber (reg:CC FLAGS_REG))]
7453 ; ""
7454 ; "div{l}\t{%2, %0|%0, %2}"
7455 ; [(set_attr "type" "idiv")])
7456 \f
7457 ;;- Logical AND instructions
7458
7459 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7460 ;; Note that this excludes ah.
7461
7462 (define_expand "testsi_ccno_1"
7463 [(set (reg:CCNO FLAGS_REG)
7464 (compare:CCNO
7465 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7466 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7467 (const_int 0)))])
7468
7469 (define_expand "testqi_ccz_1"
7470 [(set (reg:CCZ FLAGS_REG)
7471 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7472 (match_operand:QI 1 "nonmemory_operand"))
7473 (const_int 0)))])
7474
7475 (define_expand "testdi_ccno_1"
7476 [(set (reg:CCNO FLAGS_REG)
7477 (compare:CCNO
7478 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7479 (match_operand:DI 1 "x86_64_szext_general_operand"))
7480 (const_int 0)))]
7481 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7482
7483 (define_insn "*testdi_1"
7484 [(set (reg FLAGS_REG)
7485 (compare
7486 (and:DI
7487 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7488 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7489 (const_int 0)))]
7490 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7491 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7492 "@
7493 test{l}\t{%k1, %k0|%k0, %k1}
7494 test{l}\t{%k1, %k0|%k0, %k1}
7495 test{q}\t{%1, %0|%0, %1}
7496 test{q}\t{%1, %0|%0, %1}
7497 test{q}\t{%1, %0|%0, %1}"
7498 [(set_attr "type" "test")
7499 (set_attr "modrm" "0,1,0,1,1")
7500 (set_attr "mode" "SI,SI,DI,DI,DI")])
7501
7502 (define_insn "*testqi_1_maybe_si"
7503 [(set (reg FLAGS_REG)
7504 (compare
7505 (and:QI
7506 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7507 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7508 (const_int 0)))]
7509 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7510 && ix86_match_ccmode (insn,
7511 CONST_INT_P (operands[1])
7512 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7513 {
7514 if (which_alternative == 3)
7515 {
7516 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7517 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7518 return "test{l}\t{%1, %k0|%k0, %1}";
7519 }
7520 return "test{b}\t{%1, %0|%0, %1}";
7521 }
7522 [(set_attr "type" "test")
7523 (set_attr "modrm" "0,1,1,1")
7524 (set_attr "mode" "QI,QI,QI,SI")
7525 (set_attr "pent_pair" "uv,np,uv,np")])
7526
7527 (define_insn "*test<mode>_1"
7528 [(set (reg FLAGS_REG)
7529 (compare
7530 (and:SWI124
7531 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7532 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7533 (const_int 0)))]
7534 "ix86_match_ccmode (insn, CCNOmode)
7535 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7536 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7537 [(set_attr "type" "test")
7538 (set_attr "modrm" "0,1,1")
7539 (set_attr "mode" "<MODE>")
7540 (set_attr "pent_pair" "uv,np,uv")])
7541
7542 (define_expand "testqi_ext_ccno_0"
7543 [(set (reg:CCNO FLAGS_REG)
7544 (compare:CCNO
7545 (and:SI
7546 (zero_extract:SI
7547 (match_operand 0 "ext_register_operand")
7548 (const_int 8)
7549 (const_int 8))
7550 (match_operand 1 "const_int_operand"))
7551 (const_int 0)))])
7552
7553 (define_insn "*testqi_ext_0"
7554 [(set (reg FLAGS_REG)
7555 (compare
7556 (and:SI
7557 (zero_extract:SI
7558 (match_operand 0 "ext_register_operand" "Q")
7559 (const_int 8)
7560 (const_int 8))
7561 (match_operand 1 "const_int_operand" "n"))
7562 (const_int 0)))]
7563 "ix86_match_ccmode (insn, CCNOmode)"
7564 "test{b}\t{%1, %h0|%h0, %1}"
7565 [(set_attr "type" "test")
7566 (set_attr "mode" "QI")
7567 (set_attr "length_immediate" "1")
7568 (set_attr "modrm" "1")
7569 (set_attr "pent_pair" "np")])
7570
7571 (define_insn "*testqi_ext_1_rex64"
7572 [(set (reg FLAGS_REG)
7573 (compare
7574 (and:SI
7575 (zero_extract:SI
7576 (match_operand 0 "ext_register_operand" "Q")
7577 (const_int 8)
7578 (const_int 8))
7579 (zero_extend:SI
7580 (match_operand:QI 1 "register_operand" "Q")))
7581 (const_int 0)))]
7582 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7583 "test{b}\t{%1, %h0|%h0, %1}"
7584 [(set_attr "type" "test")
7585 (set_attr "mode" "QI")])
7586
7587 (define_insn "*testqi_ext_1"
7588 [(set (reg FLAGS_REG)
7589 (compare
7590 (and:SI
7591 (zero_extract:SI
7592 (match_operand 0 "ext_register_operand" "Q")
7593 (const_int 8)
7594 (const_int 8))
7595 (zero_extend:SI
7596 (match_operand:QI 1 "general_operand" "Qm")))
7597 (const_int 0)))]
7598 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7599 "test{b}\t{%1, %h0|%h0, %1}"
7600 [(set_attr "type" "test")
7601 (set_attr "mode" "QI")])
7602
7603 (define_insn "*testqi_ext_2"
7604 [(set (reg FLAGS_REG)
7605 (compare
7606 (and:SI
7607 (zero_extract:SI
7608 (match_operand 0 "ext_register_operand" "Q")
7609 (const_int 8)
7610 (const_int 8))
7611 (zero_extract:SI
7612 (match_operand 1 "ext_register_operand" "Q")
7613 (const_int 8)
7614 (const_int 8)))
7615 (const_int 0)))]
7616 "ix86_match_ccmode (insn, CCNOmode)"
7617 "test{b}\t{%h1, %h0|%h0, %h1}"
7618 [(set_attr "type" "test")
7619 (set_attr "mode" "QI")])
7620
7621 (define_insn "*testqi_ext_3_rex64"
7622 [(set (reg FLAGS_REG)
7623 (compare (zero_extract:DI
7624 (match_operand 0 "nonimmediate_operand" "rm")
7625 (match_operand:DI 1 "const_int_operand")
7626 (match_operand:DI 2 "const_int_operand"))
7627 (const_int 0)))]
7628 "TARGET_64BIT
7629 && ix86_match_ccmode (insn, CCNOmode)
7630 && INTVAL (operands[1]) > 0
7631 && INTVAL (operands[2]) >= 0
7632 /* Ensure that resulting mask is zero or sign extended operand. */
7633 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7634 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7635 && INTVAL (operands[1]) > 32))
7636 && (GET_MODE (operands[0]) == SImode
7637 || GET_MODE (operands[0]) == DImode
7638 || GET_MODE (operands[0]) == HImode
7639 || GET_MODE (operands[0]) == QImode)"
7640 "#")
7641
7642 ;; Combine likes to form bit extractions for some tests. Humor it.
7643 (define_insn "*testqi_ext_3"
7644 [(set (reg FLAGS_REG)
7645 (compare (zero_extract:SI
7646 (match_operand 0 "nonimmediate_operand" "rm")
7647 (match_operand:SI 1 "const_int_operand")
7648 (match_operand:SI 2 "const_int_operand"))
7649 (const_int 0)))]
7650 "ix86_match_ccmode (insn, CCNOmode)
7651 && INTVAL (operands[1]) > 0
7652 && INTVAL (operands[2]) >= 0
7653 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7654 && (GET_MODE (operands[0]) == SImode
7655 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7656 || GET_MODE (operands[0]) == HImode
7657 || GET_MODE (operands[0]) == QImode)"
7658 "#")
7659
7660 (define_split
7661 [(set (match_operand 0 "flags_reg_operand")
7662 (match_operator 1 "compare_operator"
7663 [(zero_extract
7664 (match_operand 2 "nonimmediate_operand")
7665 (match_operand 3 "const_int_operand")
7666 (match_operand 4 "const_int_operand"))
7667 (const_int 0)]))]
7668 "ix86_match_ccmode (insn, CCNOmode)"
7669 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7670 {
7671 rtx val = operands[2];
7672 HOST_WIDE_INT len = INTVAL (operands[3]);
7673 HOST_WIDE_INT pos = INTVAL (operands[4]);
7674 HOST_WIDE_INT mask;
7675 enum machine_mode mode, submode;
7676
7677 mode = GET_MODE (val);
7678 if (MEM_P (val))
7679 {
7680 /* ??? Combine likes to put non-volatile mem extractions in QImode
7681 no matter the size of the test. So find a mode that works. */
7682 if (! MEM_VOLATILE_P (val))
7683 {
7684 mode = smallest_mode_for_size (pos + len, MODE_INT);
7685 val = adjust_address (val, mode, 0);
7686 }
7687 }
7688 else if (GET_CODE (val) == SUBREG
7689 && (submode = GET_MODE (SUBREG_REG (val)),
7690 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7691 && pos + len <= GET_MODE_BITSIZE (submode)
7692 && GET_MODE_CLASS (submode) == MODE_INT)
7693 {
7694 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7695 mode = submode;
7696 val = SUBREG_REG (val);
7697 }
7698 else if (mode == HImode && pos + len <= 8)
7699 {
7700 /* Small HImode tests can be converted to QImode. */
7701 mode = QImode;
7702 val = gen_lowpart (QImode, val);
7703 }
7704
7705 if (len == HOST_BITS_PER_WIDE_INT)
7706 mask = -1;
7707 else
7708 mask = ((HOST_WIDE_INT)1 << len) - 1;
7709 mask <<= pos;
7710
7711 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7712 })
7713
7714 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7715 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7716 ;; this is relatively important trick.
7717 ;; Do the conversion only post-reload to avoid limiting of the register class
7718 ;; to QI regs.
7719 (define_split
7720 [(set (match_operand 0 "flags_reg_operand")
7721 (match_operator 1 "compare_operator"
7722 [(and (match_operand 2 "register_operand")
7723 (match_operand 3 "const_int_operand"))
7724 (const_int 0)]))]
7725 "reload_completed
7726 && QI_REG_P (operands[2])
7727 && GET_MODE (operands[2]) != QImode
7728 && ((ix86_match_ccmode (insn, CCZmode)
7729 && !(INTVAL (operands[3]) & ~(255 << 8)))
7730 || (ix86_match_ccmode (insn, CCNOmode)
7731 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7732 [(set (match_dup 0)
7733 (match_op_dup 1
7734 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7735 (match_dup 3))
7736 (const_int 0)]))]
7737 {
7738 operands[2] = gen_lowpart (SImode, operands[2]);
7739 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7740 })
7741
7742 (define_split
7743 [(set (match_operand 0 "flags_reg_operand")
7744 (match_operator 1 "compare_operator"
7745 [(and (match_operand 2 "nonimmediate_operand")
7746 (match_operand 3 "const_int_operand"))
7747 (const_int 0)]))]
7748 "reload_completed
7749 && GET_MODE (operands[2]) != QImode
7750 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7751 && ((ix86_match_ccmode (insn, CCZmode)
7752 && !(INTVAL (operands[3]) & ~255))
7753 || (ix86_match_ccmode (insn, CCNOmode)
7754 && !(INTVAL (operands[3]) & ~127)))"
7755 [(set (match_dup 0)
7756 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7757 (const_int 0)]))]
7758 {
7759 operands[2] = gen_lowpart (QImode, operands[2]);
7760 operands[3] = gen_lowpart (QImode, operands[3]);
7761 })
7762
7763 ;; %%% This used to optimize known byte-wide and operations to memory,
7764 ;; and sometimes to QImode registers. If this is considered useful,
7765 ;; it should be done with splitters.
7766
7767 (define_expand "and<mode>3"
7768 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7769 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7770 (match_operand:SWIM 2 "<general_szext_operand>")))]
7771 ""
7772 {
7773 enum machine_mode mode = <MODE>mode;
7774 rtx (*insn) (rtx, rtx);
7775
7776 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7777 {
7778 HOST_WIDE_INT ival = INTVAL (operands[2]);
7779
7780 if (ival == (HOST_WIDE_INT) 0xffffffff)
7781 mode = SImode;
7782 else if (ival == 0xffff)
7783 mode = HImode;
7784 else if (ival == 0xff)
7785 mode = QImode;
7786 }
7787
7788 if (mode == <MODE>mode)
7789 {
7790 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7791 DONE;
7792 }
7793
7794 if (<MODE>mode == DImode)
7795 insn = (mode == SImode)
7796 ? gen_zero_extendsidi2
7797 : (mode == HImode)
7798 ? gen_zero_extendhidi2
7799 : gen_zero_extendqidi2;
7800 else if (<MODE>mode == SImode)
7801 insn = (mode == HImode)
7802 ? gen_zero_extendhisi2
7803 : gen_zero_extendqisi2;
7804 else if (<MODE>mode == HImode)
7805 insn = gen_zero_extendqihi2;
7806 else
7807 gcc_unreachable ();
7808
7809 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7810 DONE;
7811 })
7812
7813 (define_insn "*anddi_1"
7814 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7815 (and:DI
7816 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7817 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7818 (clobber (reg:CC FLAGS_REG))]
7819 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7820 {
7821 switch (get_attr_type (insn))
7822 {
7823 case TYPE_IMOVX:
7824 return "#";
7825
7826 default:
7827 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7828 if (get_attr_mode (insn) == MODE_SI)
7829 return "and{l}\t{%k2, %k0|%k0, %k2}";
7830 else
7831 return "and{q}\t{%2, %0|%0, %2}";
7832 }
7833 }
7834 [(set_attr "type" "alu,alu,alu,imovx")
7835 (set_attr "length_immediate" "*,*,*,0")
7836 (set (attr "prefix_rex")
7837 (if_then_else
7838 (and (eq_attr "type" "imovx")
7839 (and (match_test "INTVAL (operands[2]) == 0xff")
7840 (match_operand 1 "ext_QIreg_operand")))
7841 (const_string "1")
7842 (const_string "*")))
7843 (set_attr "mode" "SI,DI,DI,SI")])
7844
7845 (define_insn "*andsi_1"
7846 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7847 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7848 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7849 (clobber (reg:CC FLAGS_REG))]
7850 "ix86_binary_operator_ok (AND, SImode, operands)"
7851 {
7852 switch (get_attr_type (insn))
7853 {
7854 case TYPE_IMOVX:
7855 return "#";
7856
7857 default:
7858 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7859 return "and{l}\t{%2, %0|%0, %2}";
7860 }
7861 }
7862 [(set_attr "type" "alu,alu,imovx")
7863 (set (attr "prefix_rex")
7864 (if_then_else
7865 (and (eq_attr "type" "imovx")
7866 (and (match_test "INTVAL (operands[2]) == 0xff")
7867 (match_operand 1 "ext_QIreg_operand")))
7868 (const_string "1")
7869 (const_string "*")))
7870 (set_attr "length_immediate" "*,*,0")
7871 (set_attr "mode" "SI")])
7872
7873 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7874 (define_insn "*andsi_1_zext"
7875 [(set (match_operand:DI 0 "register_operand" "=r")
7876 (zero_extend:DI
7877 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7878 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7879 (clobber (reg:CC FLAGS_REG))]
7880 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7881 "and{l}\t{%2, %k0|%k0, %2}"
7882 [(set_attr "type" "alu")
7883 (set_attr "mode" "SI")])
7884
7885 (define_insn "*andhi_1"
7886 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7887 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7888 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7889 (clobber (reg:CC FLAGS_REG))]
7890 "ix86_binary_operator_ok (AND, HImode, operands)"
7891 {
7892 switch (get_attr_type (insn))
7893 {
7894 case TYPE_IMOVX:
7895 return "#";
7896
7897 default:
7898 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7899 return "and{w}\t{%2, %0|%0, %2}";
7900 }
7901 }
7902 [(set_attr "type" "alu,alu,imovx")
7903 (set_attr "length_immediate" "*,*,0")
7904 (set (attr "prefix_rex")
7905 (if_then_else
7906 (and (eq_attr "type" "imovx")
7907 (match_operand 1 "ext_QIreg_operand"))
7908 (const_string "1")
7909 (const_string "*")))
7910 (set_attr "mode" "HI,HI,SI")])
7911
7912 ;; %%% Potential partial reg stall on alternative 2. What to do?
7913 (define_insn "*andqi_1"
7914 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7915 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7916 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7917 (clobber (reg:CC FLAGS_REG))]
7918 "ix86_binary_operator_ok (AND, QImode, operands)"
7919 "@
7920 and{b}\t{%2, %0|%0, %2}
7921 and{b}\t{%2, %0|%0, %2}
7922 and{l}\t{%k2, %k0|%k0, %k2}"
7923 [(set_attr "type" "alu")
7924 (set_attr "mode" "QI,QI,SI")])
7925
7926 (define_insn "*andqi_1_slp"
7927 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7928 (and:QI (match_dup 0)
7929 (match_operand:QI 1 "general_operand" "qn,qmn")))
7930 (clobber (reg:CC FLAGS_REG))]
7931 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7932 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7933 "and{b}\t{%1, %0|%0, %1}"
7934 [(set_attr "type" "alu1")
7935 (set_attr "mode" "QI")])
7936
7937 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7938 (define_split
7939 [(set (match_operand:DI 0 "register_operand")
7940 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7941 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7942 (clobber (reg:CC FLAGS_REG))]
7943 "TARGET_64BIT"
7944 [(parallel [(set (match_dup 0)
7945 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7946 (clobber (reg:CC FLAGS_REG))])]
7947 "operands[2] = gen_lowpart (SImode, operands[2]);")
7948
7949 (define_split
7950 [(set (match_operand:SWI248 0 "register_operand")
7951 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7952 (match_operand:SWI248 2 "const_int_operand")))
7953 (clobber (reg:CC FLAGS_REG))]
7954 "reload_completed
7955 && true_regnum (operands[0]) != true_regnum (operands[1])"
7956 [(const_int 0)]
7957 {
7958 HOST_WIDE_INT ival = INTVAL (operands[2]);
7959 enum machine_mode mode;
7960 rtx (*insn) (rtx, rtx);
7961
7962 if (ival == (HOST_WIDE_INT) 0xffffffff)
7963 mode = SImode;
7964 else if (ival == 0xffff)
7965 mode = HImode;
7966 else
7967 {
7968 gcc_assert (ival == 0xff);
7969 mode = QImode;
7970 }
7971
7972 if (<MODE>mode == DImode)
7973 insn = (mode == SImode)
7974 ? gen_zero_extendsidi2
7975 : (mode == HImode)
7976 ? gen_zero_extendhidi2
7977 : gen_zero_extendqidi2;
7978 else
7979 {
7980 if (<MODE>mode != SImode)
7981 /* Zero extend to SImode to avoid partial register stalls. */
7982 operands[0] = gen_lowpart (SImode, operands[0]);
7983
7984 insn = (mode == HImode)
7985 ? gen_zero_extendhisi2
7986 : gen_zero_extendqisi2;
7987 }
7988 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7989 DONE;
7990 })
7991
7992 (define_split
7993 [(set (match_operand 0 "register_operand")
7994 (and (match_dup 0)
7995 (const_int -65536)))
7996 (clobber (reg:CC FLAGS_REG))]
7997 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7998 || optimize_function_for_size_p (cfun)"
7999 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8000 "operands[1] = gen_lowpart (HImode, operands[0]);")
8001
8002 (define_split
8003 [(set (match_operand 0 "ext_register_operand")
8004 (and (match_dup 0)
8005 (const_int -256)))
8006 (clobber (reg:CC FLAGS_REG))]
8007 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8008 && reload_completed"
8009 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8010 "operands[1] = gen_lowpart (QImode, operands[0]);")
8011
8012 (define_split
8013 [(set (match_operand 0 "ext_register_operand")
8014 (and (match_dup 0)
8015 (const_int -65281)))
8016 (clobber (reg:CC FLAGS_REG))]
8017 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8018 && reload_completed"
8019 [(parallel [(set (zero_extract:SI (match_dup 0)
8020 (const_int 8)
8021 (const_int 8))
8022 (xor:SI
8023 (zero_extract:SI (match_dup 0)
8024 (const_int 8)
8025 (const_int 8))
8026 (zero_extract:SI (match_dup 0)
8027 (const_int 8)
8028 (const_int 8))))
8029 (clobber (reg:CC FLAGS_REG))])]
8030 "operands[0] = gen_lowpart (SImode, operands[0]);")
8031
8032 (define_insn "*anddi_2"
8033 [(set (reg FLAGS_REG)
8034 (compare
8035 (and:DI
8036 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8037 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8038 (const_int 0)))
8039 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8040 (and:DI (match_dup 1) (match_dup 2)))]
8041 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8042 && ix86_binary_operator_ok (AND, DImode, operands)"
8043 "@
8044 and{l}\t{%k2, %k0|%k0, %k2}
8045 and{q}\t{%2, %0|%0, %2}
8046 and{q}\t{%2, %0|%0, %2}"
8047 [(set_attr "type" "alu")
8048 (set_attr "mode" "SI,DI,DI")])
8049
8050 (define_insn "*andqi_2_maybe_si"
8051 [(set (reg FLAGS_REG)
8052 (compare (and:QI
8053 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8054 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8055 (const_int 0)))
8056 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8057 (and:QI (match_dup 1) (match_dup 2)))]
8058 "ix86_binary_operator_ok (AND, QImode, operands)
8059 && ix86_match_ccmode (insn,
8060 CONST_INT_P (operands[2])
8061 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8062 {
8063 if (which_alternative == 2)
8064 {
8065 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8066 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8067 return "and{l}\t{%2, %k0|%k0, %2}";
8068 }
8069 return "and{b}\t{%2, %0|%0, %2}";
8070 }
8071 [(set_attr "type" "alu")
8072 (set_attr "mode" "QI,QI,SI")])
8073
8074 (define_insn "*and<mode>_2"
8075 [(set (reg FLAGS_REG)
8076 (compare (and:SWI124
8077 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8078 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8079 (const_int 0)))
8080 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8081 (and:SWI124 (match_dup 1) (match_dup 2)))]
8082 "ix86_match_ccmode (insn, CCNOmode)
8083 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8084 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8085 [(set_attr "type" "alu")
8086 (set_attr "mode" "<MODE>")])
8087
8088 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8089 (define_insn "*andsi_2_zext"
8090 [(set (reg FLAGS_REG)
8091 (compare (and:SI
8092 (match_operand:SI 1 "nonimmediate_operand" "%0")
8093 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8094 (const_int 0)))
8095 (set (match_operand:DI 0 "register_operand" "=r")
8096 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8097 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8098 && ix86_binary_operator_ok (AND, SImode, operands)"
8099 "and{l}\t{%2, %k0|%k0, %2}"
8100 [(set_attr "type" "alu")
8101 (set_attr "mode" "SI")])
8102
8103 (define_insn "*andqi_2_slp"
8104 [(set (reg FLAGS_REG)
8105 (compare (and:QI
8106 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8107 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8108 (const_int 0)))
8109 (set (strict_low_part (match_dup 0))
8110 (and:QI (match_dup 0) (match_dup 1)))]
8111 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8112 && ix86_match_ccmode (insn, CCNOmode)
8113 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8114 "and{b}\t{%1, %0|%0, %1}"
8115 [(set_attr "type" "alu1")
8116 (set_attr "mode" "QI")])
8117
8118 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8119 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8120 ;; for a QImode operand, which of course failed.
8121 (define_insn "andqi_ext_0"
8122 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8123 (const_int 8)
8124 (const_int 8))
8125 (and:SI
8126 (zero_extract:SI
8127 (match_operand 1 "ext_register_operand" "0")
8128 (const_int 8)
8129 (const_int 8))
8130 (match_operand 2 "const_int_operand" "n")))
8131 (clobber (reg:CC FLAGS_REG))]
8132 ""
8133 "and{b}\t{%2, %h0|%h0, %2}"
8134 [(set_attr "type" "alu")
8135 (set_attr "length_immediate" "1")
8136 (set_attr "modrm" "1")
8137 (set_attr "mode" "QI")])
8138
8139 ;; Generated by peephole translating test to and. This shows up
8140 ;; often in fp comparisons.
8141 (define_insn "*andqi_ext_0_cc"
8142 [(set (reg FLAGS_REG)
8143 (compare
8144 (and:SI
8145 (zero_extract:SI
8146 (match_operand 1 "ext_register_operand" "0")
8147 (const_int 8)
8148 (const_int 8))
8149 (match_operand 2 "const_int_operand" "n"))
8150 (const_int 0)))
8151 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8152 (const_int 8)
8153 (const_int 8))
8154 (and:SI
8155 (zero_extract:SI
8156 (match_dup 1)
8157 (const_int 8)
8158 (const_int 8))
8159 (match_dup 2)))]
8160 "ix86_match_ccmode (insn, CCNOmode)"
8161 "and{b}\t{%2, %h0|%h0, %2}"
8162 [(set_attr "type" "alu")
8163 (set_attr "length_immediate" "1")
8164 (set_attr "modrm" "1")
8165 (set_attr "mode" "QI")])
8166
8167 (define_insn "*andqi_ext_1_rex64"
8168 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8169 (const_int 8)
8170 (const_int 8))
8171 (and:SI
8172 (zero_extract:SI
8173 (match_operand 1 "ext_register_operand" "0")
8174 (const_int 8)
8175 (const_int 8))
8176 (zero_extend:SI
8177 (match_operand 2 "ext_register_operand" "Q"))))
8178 (clobber (reg:CC FLAGS_REG))]
8179 "TARGET_64BIT"
8180 "and{b}\t{%2, %h0|%h0, %2}"
8181 [(set_attr "type" "alu")
8182 (set_attr "length_immediate" "0")
8183 (set_attr "mode" "QI")])
8184
8185 (define_insn "*andqi_ext_1"
8186 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8187 (const_int 8)
8188 (const_int 8))
8189 (and:SI
8190 (zero_extract:SI
8191 (match_operand 1 "ext_register_operand" "0")
8192 (const_int 8)
8193 (const_int 8))
8194 (zero_extend:SI
8195 (match_operand:QI 2 "general_operand" "Qm"))))
8196 (clobber (reg:CC FLAGS_REG))]
8197 "!TARGET_64BIT"
8198 "and{b}\t{%2, %h0|%h0, %2}"
8199 [(set_attr "type" "alu")
8200 (set_attr "length_immediate" "0")
8201 (set_attr "mode" "QI")])
8202
8203 (define_insn "*andqi_ext_2"
8204 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8205 (const_int 8)
8206 (const_int 8))
8207 (and:SI
8208 (zero_extract:SI
8209 (match_operand 1 "ext_register_operand" "%0")
8210 (const_int 8)
8211 (const_int 8))
8212 (zero_extract:SI
8213 (match_operand 2 "ext_register_operand" "Q")
8214 (const_int 8)
8215 (const_int 8))))
8216 (clobber (reg:CC FLAGS_REG))]
8217 ""
8218 "and{b}\t{%h2, %h0|%h0, %h2}"
8219 [(set_attr "type" "alu")
8220 (set_attr "length_immediate" "0")
8221 (set_attr "mode" "QI")])
8222
8223 ;; Convert wide AND instructions with immediate operand to shorter QImode
8224 ;; equivalents when possible.
8225 ;; Don't do the splitting with memory operands, since it introduces risk
8226 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8227 ;; for size, but that can (should?) be handled by generic code instead.
8228 (define_split
8229 [(set (match_operand 0 "register_operand")
8230 (and (match_operand 1 "register_operand")
8231 (match_operand 2 "const_int_operand")))
8232 (clobber (reg:CC FLAGS_REG))]
8233 "reload_completed
8234 && QI_REG_P (operands[0])
8235 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8236 && !(~INTVAL (operands[2]) & ~(255 << 8))
8237 && GET_MODE (operands[0]) != QImode"
8238 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8239 (and:SI (zero_extract:SI (match_dup 1)
8240 (const_int 8) (const_int 8))
8241 (match_dup 2)))
8242 (clobber (reg:CC FLAGS_REG))])]
8243 {
8244 operands[0] = gen_lowpart (SImode, operands[0]);
8245 operands[1] = gen_lowpart (SImode, operands[1]);
8246 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8247 })
8248
8249 ;; Since AND can be encoded with sign extended immediate, this is only
8250 ;; profitable when 7th bit is not set.
8251 (define_split
8252 [(set (match_operand 0 "register_operand")
8253 (and (match_operand 1 "general_operand")
8254 (match_operand 2 "const_int_operand")))
8255 (clobber (reg:CC FLAGS_REG))]
8256 "reload_completed
8257 && ANY_QI_REG_P (operands[0])
8258 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8259 && !(~INTVAL (operands[2]) & ~255)
8260 && !(INTVAL (operands[2]) & 128)
8261 && GET_MODE (operands[0]) != QImode"
8262 [(parallel [(set (strict_low_part (match_dup 0))
8263 (and:QI (match_dup 1)
8264 (match_dup 2)))
8265 (clobber (reg:CC FLAGS_REG))])]
8266 {
8267 operands[0] = gen_lowpart (QImode, operands[0]);
8268 operands[1] = gen_lowpart (QImode, operands[1]);
8269 operands[2] = gen_lowpart (QImode, operands[2]);
8270 })
8271 \f
8272 ;; Logical inclusive and exclusive OR instructions
8273
8274 ;; %%% This used to optimize known byte-wide and operations to memory.
8275 ;; If this is considered useful, it should be done with splitters.
8276
8277 (define_expand "<code><mode>3"
8278 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8279 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8280 (match_operand:SWIM 2 "<general_operand>")))]
8281 ""
8282 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8283
8284 (define_insn "*<code><mode>_1"
8285 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8286 (any_or:SWI248
8287 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8288 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8289 (clobber (reg:CC FLAGS_REG))]
8290 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8291 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8292 [(set_attr "type" "alu")
8293 (set_attr "mode" "<MODE>")])
8294
8295 ;; %%% Potential partial reg stall on alternative 2. What to do?
8296 (define_insn "*<code>qi_1"
8297 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8298 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8299 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8300 (clobber (reg:CC FLAGS_REG))]
8301 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8302 "@
8303 <logic>{b}\t{%2, %0|%0, %2}
8304 <logic>{b}\t{%2, %0|%0, %2}
8305 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8306 [(set_attr "type" "alu")
8307 (set_attr "mode" "QI,QI,SI")])
8308
8309 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8310 (define_insn "*<code>si_1_zext"
8311 [(set (match_operand:DI 0 "register_operand" "=r")
8312 (zero_extend:DI
8313 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8314 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8315 (clobber (reg:CC FLAGS_REG))]
8316 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8317 "<logic>{l}\t{%2, %k0|%k0, %2}"
8318 [(set_attr "type" "alu")
8319 (set_attr "mode" "SI")])
8320
8321 (define_insn "*<code>si_1_zext_imm"
8322 [(set (match_operand:DI 0 "register_operand" "=r")
8323 (any_or:DI
8324 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8325 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8326 (clobber (reg:CC FLAGS_REG))]
8327 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8328 "<logic>{l}\t{%2, %k0|%k0, %2}"
8329 [(set_attr "type" "alu")
8330 (set_attr "mode" "SI")])
8331
8332 (define_insn "*<code>qi_1_slp"
8333 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8334 (any_or:QI (match_dup 0)
8335 (match_operand:QI 1 "general_operand" "qmn,qn")))
8336 (clobber (reg:CC FLAGS_REG))]
8337 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8338 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8339 "<logic>{b}\t{%1, %0|%0, %1}"
8340 [(set_attr "type" "alu1")
8341 (set_attr "mode" "QI")])
8342
8343 (define_insn "*<code><mode>_2"
8344 [(set (reg FLAGS_REG)
8345 (compare (any_or:SWI
8346 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8347 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8348 (const_int 0)))
8349 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8350 (any_or:SWI (match_dup 1) (match_dup 2)))]
8351 "ix86_match_ccmode (insn, CCNOmode)
8352 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8353 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8354 [(set_attr "type" "alu")
8355 (set_attr "mode" "<MODE>")])
8356
8357 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8358 ;; ??? Special case for immediate operand is missing - it is tricky.
8359 (define_insn "*<code>si_2_zext"
8360 [(set (reg FLAGS_REG)
8361 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8362 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8363 (const_int 0)))
8364 (set (match_operand:DI 0 "register_operand" "=r")
8365 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8366 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8367 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8368 "<logic>{l}\t{%2, %k0|%k0, %2}"
8369 [(set_attr "type" "alu")
8370 (set_attr "mode" "SI")])
8371
8372 (define_insn "*<code>si_2_zext_imm"
8373 [(set (reg FLAGS_REG)
8374 (compare (any_or:SI
8375 (match_operand:SI 1 "nonimmediate_operand" "%0")
8376 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8377 (const_int 0)))
8378 (set (match_operand:DI 0 "register_operand" "=r")
8379 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8380 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8381 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8382 "<logic>{l}\t{%2, %k0|%k0, %2}"
8383 [(set_attr "type" "alu")
8384 (set_attr "mode" "SI")])
8385
8386 (define_insn "*<code>qi_2_slp"
8387 [(set (reg FLAGS_REG)
8388 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8389 (match_operand:QI 1 "general_operand" "qmn,qn"))
8390 (const_int 0)))
8391 (set (strict_low_part (match_dup 0))
8392 (any_or:QI (match_dup 0) (match_dup 1)))]
8393 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8394 && ix86_match_ccmode (insn, CCNOmode)
8395 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8396 "<logic>{b}\t{%1, %0|%0, %1}"
8397 [(set_attr "type" "alu1")
8398 (set_attr "mode" "QI")])
8399
8400 (define_insn "*<code><mode>_3"
8401 [(set (reg FLAGS_REG)
8402 (compare (any_or:SWI
8403 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8404 (match_operand:SWI 2 "<general_operand>" "<g>"))
8405 (const_int 0)))
8406 (clobber (match_scratch:SWI 0 "=<r>"))]
8407 "ix86_match_ccmode (insn, CCNOmode)
8408 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8409 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8410 [(set_attr "type" "alu")
8411 (set_attr "mode" "<MODE>")])
8412
8413 (define_insn "*<code>qi_ext_0"
8414 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8415 (const_int 8)
8416 (const_int 8))
8417 (any_or:SI
8418 (zero_extract:SI
8419 (match_operand 1 "ext_register_operand" "0")
8420 (const_int 8)
8421 (const_int 8))
8422 (match_operand 2 "const_int_operand" "n")))
8423 (clobber (reg:CC FLAGS_REG))]
8424 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8425 "<logic>{b}\t{%2, %h0|%h0, %2}"
8426 [(set_attr "type" "alu")
8427 (set_attr "length_immediate" "1")
8428 (set_attr "modrm" "1")
8429 (set_attr "mode" "QI")])
8430
8431 (define_insn "*<code>qi_ext_1_rex64"
8432 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8433 (const_int 8)
8434 (const_int 8))
8435 (any_or:SI
8436 (zero_extract:SI
8437 (match_operand 1 "ext_register_operand" "0")
8438 (const_int 8)
8439 (const_int 8))
8440 (zero_extend:SI
8441 (match_operand 2 "ext_register_operand" "Q"))))
8442 (clobber (reg:CC FLAGS_REG))]
8443 "TARGET_64BIT
8444 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8445 "<logic>{b}\t{%2, %h0|%h0, %2}"
8446 [(set_attr "type" "alu")
8447 (set_attr "length_immediate" "0")
8448 (set_attr "mode" "QI")])
8449
8450 (define_insn "*<code>qi_ext_1"
8451 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8452 (const_int 8)
8453 (const_int 8))
8454 (any_or:SI
8455 (zero_extract:SI
8456 (match_operand 1 "ext_register_operand" "0")
8457 (const_int 8)
8458 (const_int 8))
8459 (zero_extend:SI
8460 (match_operand:QI 2 "general_operand" "Qm"))))
8461 (clobber (reg:CC FLAGS_REG))]
8462 "!TARGET_64BIT
8463 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8464 "<logic>{b}\t{%2, %h0|%h0, %2}"
8465 [(set_attr "type" "alu")
8466 (set_attr "length_immediate" "0")
8467 (set_attr "mode" "QI")])
8468
8469 (define_insn "*<code>qi_ext_2"
8470 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8471 (const_int 8)
8472 (const_int 8))
8473 (any_or:SI
8474 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8475 (const_int 8)
8476 (const_int 8))
8477 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8478 (const_int 8)
8479 (const_int 8))))
8480 (clobber (reg:CC FLAGS_REG))]
8481 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8482 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8483 [(set_attr "type" "alu")
8484 (set_attr "length_immediate" "0")
8485 (set_attr "mode" "QI")])
8486
8487 (define_split
8488 [(set (match_operand 0 "register_operand")
8489 (any_or (match_operand 1 "register_operand")
8490 (match_operand 2 "const_int_operand")))
8491 (clobber (reg:CC FLAGS_REG))]
8492 "reload_completed
8493 && QI_REG_P (operands[0])
8494 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8495 && !(INTVAL (operands[2]) & ~(255 << 8))
8496 && GET_MODE (operands[0]) != QImode"
8497 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8498 (any_or:SI (zero_extract:SI (match_dup 1)
8499 (const_int 8) (const_int 8))
8500 (match_dup 2)))
8501 (clobber (reg:CC FLAGS_REG))])]
8502 {
8503 operands[0] = gen_lowpart (SImode, operands[0]);
8504 operands[1] = gen_lowpart (SImode, operands[1]);
8505 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8506 })
8507
8508 ;; Since OR can be encoded with sign extended immediate, this is only
8509 ;; profitable when 7th bit is set.
8510 (define_split
8511 [(set (match_operand 0 "register_operand")
8512 (any_or (match_operand 1 "general_operand")
8513 (match_operand 2 "const_int_operand")))
8514 (clobber (reg:CC FLAGS_REG))]
8515 "reload_completed
8516 && ANY_QI_REG_P (operands[0])
8517 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8518 && !(INTVAL (operands[2]) & ~255)
8519 && (INTVAL (operands[2]) & 128)
8520 && GET_MODE (operands[0]) != QImode"
8521 [(parallel [(set (strict_low_part (match_dup 0))
8522 (any_or:QI (match_dup 1)
8523 (match_dup 2)))
8524 (clobber (reg:CC FLAGS_REG))])]
8525 {
8526 operands[0] = gen_lowpart (QImode, operands[0]);
8527 operands[1] = gen_lowpart (QImode, operands[1]);
8528 operands[2] = gen_lowpart (QImode, operands[2]);
8529 })
8530
8531 (define_expand "xorqi_cc_ext_1"
8532 [(parallel [
8533 (set (reg:CCNO FLAGS_REG)
8534 (compare:CCNO
8535 (xor:SI
8536 (zero_extract:SI
8537 (match_operand 1 "ext_register_operand")
8538 (const_int 8)
8539 (const_int 8))
8540 (match_operand:QI 2 "general_operand"))
8541 (const_int 0)))
8542 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8543 (const_int 8)
8544 (const_int 8))
8545 (xor:SI
8546 (zero_extract:SI
8547 (match_dup 1)
8548 (const_int 8)
8549 (const_int 8))
8550 (match_dup 2)))])])
8551
8552 (define_insn "*xorqi_cc_ext_1_rex64"
8553 [(set (reg FLAGS_REG)
8554 (compare
8555 (xor:SI
8556 (zero_extract:SI
8557 (match_operand 1 "ext_register_operand" "0")
8558 (const_int 8)
8559 (const_int 8))
8560 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8561 (const_int 0)))
8562 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8563 (const_int 8)
8564 (const_int 8))
8565 (xor:SI
8566 (zero_extract:SI
8567 (match_dup 1)
8568 (const_int 8)
8569 (const_int 8))
8570 (match_dup 2)))]
8571 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8572 "xor{b}\t{%2, %h0|%h0, %2}"
8573 [(set_attr "type" "alu")
8574 (set_attr "modrm" "1")
8575 (set_attr "mode" "QI")])
8576
8577 (define_insn "*xorqi_cc_ext_1"
8578 [(set (reg FLAGS_REG)
8579 (compare
8580 (xor:SI
8581 (zero_extract:SI
8582 (match_operand 1 "ext_register_operand" "0")
8583 (const_int 8)
8584 (const_int 8))
8585 (match_operand:QI 2 "general_operand" "qmn"))
8586 (const_int 0)))
8587 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8588 (const_int 8)
8589 (const_int 8))
8590 (xor:SI
8591 (zero_extract:SI
8592 (match_dup 1)
8593 (const_int 8)
8594 (const_int 8))
8595 (match_dup 2)))]
8596 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8597 "xor{b}\t{%2, %h0|%h0, %2}"
8598 [(set_attr "type" "alu")
8599 (set_attr "modrm" "1")
8600 (set_attr "mode" "QI")])
8601 \f
8602 ;; Negation instructions
8603
8604 (define_expand "neg<mode>2"
8605 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8606 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8607 ""
8608 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8609
8610 (define_insn_and_split "*neg<dwi>2_doubleword"
8611 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8612 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8613 (clobber (reg:CC FLAGS_REG))]
8614 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8615 "#"
8616 "reload_completed"
8617 [(parallel
8618 [(set (reg:CCZ FLAGS_REG)
8619 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8620 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8621 (parallel
8622 [(set (match_dup 2)
8623 (plus:DWIH (match_dup 3)
8624 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8625 (const_int 0))))
8626 (clobber (reg:CC FLAGS_REG))])
8627 (parallel
8628 [(set (match_dup 2)
8629 (neg:DWIH (match_dup 2)))
8630 (clobber (reg:CC FLAGS_REG))])]
8631 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8632
8633 (define_insn "*neg<mode>2_1"
8634 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8635 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8636 (clobber (reg:CC FLAGS_REG))]
8637 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8638 "neg{<imodesuffix>}\t%0"
8639 [(set_attr "type" "negnot")
8640 (set_attr "mode" "<MODE>")])
8641
8642 ;; Combine is quite creative about this pattern.
8643 (define_insn "*negsi2_1_zext"
8644 [(set (match_operand:DI 0 "register_operand" "=r")
8645 (lshiftrt:DI
8646 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8647 (const_int 32)))
8648 (const_int 32)))
8649 (clobber (reg:CC FLAGS_REG))]
8650 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8651 "neg{l}\t%k0"
8652 [(set_attr "type" "negnot")
8653 (set_attr "mode" "SI")])
8654
8655 ;; The problem with neg is that it does not perform (compare x 0),
8656 ;; it really performs (compare 0 x), which leaves us with the zero
8657 ;; flag being the only useful item.
8658
8659 (define_insn "*neg<mode>2_cmpz"
8660 [(set (reg:CCZ FLAGS_REG)
8661 (compare:CCZ
8662 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8663 (const_int 0)))
8664 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8665 (neg:SWI (match_dup 1)))]
8666 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8667 "neg{<imodesuffix>}\t%0"
8668 [(set_attr "type" "negnot")
8669 (set_attr "mode" "<MODE>")])
8670
8671 (define_insn "*negsi2_cmpz_zext"
8672 [(set (reg:CCZ FLAGS_REG)
8673 (compare:CCZ
8674 (lshiftrt:DI
8675 (neg:DI (ashift:DI
8676 (match_operand:DI 1 "register_operand" "0")
8677 (const_int 32)))
8678 (const_int 32))
8679 (const_int 0)))
8680 (set (match_operand:DI 0 "register_operand" "=r")
8681 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8682 (const_int 32)))
8683 (const_int 32)))]
8684 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8685 "neg{l}\t%k0"
8686 [(set_attr "type" "negnot")
8687 (set_attr "mode" "SI")])
8688
8689 ;; Changing of sign for FP values is doable using integer unit too.
8690
8691 (define_expand "<code><mode>2"
8692 [(set (match_operand:X87MODEF 0 "register_operand")
8693 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8694 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8695 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8696
8697 (define_insn "*absneg<mode>2_mixed"
8698 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8699 (match_operator:MODEF 3 "absneg_operator"
8700 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8701 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8702 (clobber (reg:CC FLAGS_REG))]
8703 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8704 "#")
8705
8706 (define_insn "*absneg<mode>2_sse"
8707 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8708 (match_operator:MODEF 3 "absneg_operator"
8709 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8710 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8711 (clobber (reg:CC FLAGS_REG))]
8712 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8713 "#")
8714
8715 (define_insn "*absneg<mode>2_i387"
8716 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8717 (match_operator:X87MODEF 3 "absneg_operator"
8718 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8719 (use (match_operand 2))
8720 (clobber (reg:CC FLAGS_REG))]
8721 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8722 "#")
8723
8724 (define_expand "<code>tf2"
8725 [(set (match_operand:TF 0 "register_operand")
8726 (absneg:TF (match_operand:TF 1 "register_operand")))]
8727 "TARGET_SSE"
8728 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8729
8730 (define_insn "*absnegtf2_sse"
8731 [(set (match_operand:TF 0 "register_operand" "=x,x")
8732 (match_operator:TF 3 "absneg_operator"
8733 [(match_operand:TF 1 "register_operand" "0,x")]))
8734 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8735 (clobber (reg:CC FLAGS_REG))]
8736 "TARGET_SSE"
8737 "#")
8738
8739 ;; Splitters for fp abs and neg.
8740
8741 (define_split
8742 [(set (match_operand 0 "fp_register_operand")
8743 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8744 (use (match_operand 2))
8745 (clobber (reg:CC FLAGS_REG))]
8746 "reload_completed"
8747 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8748
8749 (define_split
8750 [(set (match_operand 0 "register_operand")
8751 (match_operator 3 "absneg_operator"
8752 [(match_operand 1 "register_operand")]))
8753 (use (match_operand 2 "nonimmediate_operand"))
8754 (clobber (reg:CC FLAGS_REG))]
8755 "reload_completed && SSE_REG_P (operands[0])"
8756 [(set (match_dup 0) (match_dup 3))]
8757 {
8758 enum machine_mode mode = GET_MODE (operands[0]);
8759 enum machine_mode vmode = GET_MODE (operands[2]);
8760 rtx tmp;
8761
8762 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8763 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8764 if (operands_match_p (operands[0], operands[2]))
8765 {
8766 tmp = operands[1];
8767 operands[1] = operands[2];
8768 operands[2] = tmp;
8769 }
8770 if (GET_CODE (operands[3]) == ABS)
8771 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8772 else
8773 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8774 operands[3] = tmp;
8775 })
8776
8777 (define_split
8778 [(set (match_operand:SF 0 "register_operand")
8779 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8780 (use (match_operand:V4SF 2))
8781 (clobber (reg:CC FLAGS_REG))]
8782 "reload_completed"
8783 [(parallel [(set (match_dup 0) (match_dup 1))
8784 (clobber (reg:CC FLAGS_REG))])]
8785 {
8786 rtx tmp;
8787 operands[0] = gen_lowpart (SImode, operands[0]);
8788 if (GET_CODE (operands[1]) == ABS)
8789 {
8790 tmp = gen_int_mode (0x7fffffff, SImode);
8791 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8792 }
8793 else
8794 {
8795 tmp = gen_int_mode (0x80000000, SImode);
8796 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8797 }
8798 operands[1] = tmp;
8799 })
8800
8801 (define_split
8802 [(set (match_operand:DF 0 "register_operand")
8803 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8804 (use (match_operand 2))
8805 (clobber (reg:CC FLAGS_REG))]
8806 "reload_completed"
8807 [(parallel [(set (match_dup 0) (match_dup 1))
8808 (clobber (reg:CC FLAGS_REG))])]
8809 {
8810 rtx tmp;
8811 if (TARGET_64BIT)
8812 {
8813 tmp = gen_lowpart (DImode, operands[0]);
8814 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8815 operands[0] = tmp;
8816
8817 if (GET_CODE (operands[1]) == ABS)
8818 tmp = const0_rtx;
8819 else
8820 tmp = gen_rtx_NOT (DImode, tmp);
8821 }
8822 else
8823 {
8824 operands[0] = gen_highpart (SImode, operands[0]);
8825 if (GET_CODE (operands[1]) == ABS)
8826 {
8827 tmp = gen_int_mode (0x7fffffff, SImode);
8828 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8829 }
8830 else
8831 {
8832 tmp = gen_int_mode (0x80000000, SImode);
8833 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8834 }
8835 }
8836 operands[1] = tmp;
8837 })
8838
8839 (define_split
8840 [(set (match_operand:XF 0 "register_operand")
8841 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8842 (use (match_operand 2))
8843 (clobber (reg:CC FLAGS_REG))]
8844 "reload_completed"
8845 [(parallel [(set (match_dup 0) (match_dup 1))
8846 (clobber (reg:CC FLAGS_REG))])]
8847 {
8848 rtx tmp;
8849 operands[0] = gen_rtx_REG (SImode,
8850 true_regnum (operands[0])
8851 + (TARGET_64BIT ? 1 : 2));
8852 if (GET_CODE (operands[1]) == ABS)
8853 {
8854 tmp = GEN_INT (0x7fff);
8855 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8856 }
8857 else
8858 {
8859 tmp = GEN_INT (0x8000);
8860 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8861 }
8862 operands[1] = tmp;
8863 })
8864
8865 ;; Conditionalize these after reload. If they match before reload, we
8866 ;; lose the clobber and ability to use integer instructions.
8867
8868 (define_insn "*<code><mode>2_1"
8869 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8870 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8871 "TARGET_80387
8872 && (reload_completed
8873 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8874 "f<absneg_mnemonic>"
8875 [(set_attr "type" "fsgn")
8876 (set_attr "mode" "<MODE>")])
8877
8878 (define_insn "*<code>extendsfdf2"
8879 [(set (match_operand:DF 0 "register_operand" "=f")
8880 (absneg:DF (float_extend:DF
8881 (match_operand:SF 1 "register_operand" "0"))))]
8882 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8883 "f<absneg_mnemonic>"
8884 [(set_attr "type" "fsgn")
8885 (set_attr "mode" "DF")])
8886
8887 (define_insn "*<code>extendsfxf2"
8888 [(set (match_operand:XF 0 "register_operand" "=f")
8889 (absneg:XF (float_extend:XF
8890 (match_operand:SF 1 "register_operand" "0"))))]
8891 "TARGET_80387"
8892 "f<absneg_mnemonic>"
8893 [(set_attr "type" "fsgn")
8894 (set_attr "mode" "XF")])
8895
8896 (define_insn "*<code>extenddfxf2"
8897 [(set (match_operand:XF 0 "register_operand" "=f")
8898 (absneg:XF (float_extend:XF
8899 (match_operand:DF 1 "register_operand" "0"))))]
8900 "TARGET_80387"
8901 "f<absneg_mnemonic>"
8902 [(set_attr "type" "fsgn")
8903 (set_attr "mode" "XF")])
8904
8905 ;; Copysign instructions
8906
8907 (define_mode_iterator CSGNMODE [SF DF TF])
8908 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8909
8910 (define_expand "copysign<mode>3"
8911 [(match_operand:CSGNMODE 0 "register_operand")
8912 (match_operand:CSGNMODE 1 "nonmemory_operand")
8913 (match_operand:CSGNMODE 2 "register_operand")]
8914 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8915 || (TARGET_SSE && (<MODE>mode == TFmode))"
8916 "ix86_expand_copysign (operands); DONE;")
8917
8918 (define_insn_and_split "copysign<mode>3_const"
8919 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8920 (unspec:CSGNMODE
8921 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8922 (match_operand:CSGNMODE 2 "register_operand" "0")
8923 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8924 UNSPEC_COPYSIGN))]
8925 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8926 || (TARGET_SSE && (<MODE>mode == TFmode))"
8927 "#"
8928 "&& reload_completed"
8929 [(const_int 0)]
8930 "ix86_split_copysign_const (operands); DONE;")
8931
8932 (define_insn "copysign<mode>3_var"
8933 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8934 (unspec:CSGNMODE
8935 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8936 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8937 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8938 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8939 UNSPEC_COPYSIGN))
8940 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8941 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8942 || (TARGET_SSE && (<MODE>mode == TFmode))"
8943 "#")
8944
8945 (define_split
8946 [(set (match_operand:CSGNMODE 0 "register_operand")
8947 (unspec:CSGNMODE
8948 [(match_operand:CSGNMODE 2 "register_operand")
8949 (match_operand:CSGNMODE 3 "register_operand")
8950 (match_operand:<CSGNVMODE> 4)
8951 (match_operand:<CSGNVMODE> 5)]
8952 UNSPEC_COPYSIGN))
8953 (clobber (match_scratch:<CSGNVMODE> 1))]
8954 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8955 || (TARGET_SSE && (<MODE>mode == TFmode)))
8956 && reload_completed"
8957 [(const_int 0)]
8958 "ix86_split_copysign_var (operands); DONE;")
8959 \f
8960 ;; One complement instructions
8961
8962 (define_expand "one_cmpl<mode>2"
8963 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8964 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8965 ""
8966 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8967
8968 (define_insn "*one_cmpl<mode>2_1"
8969 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8970 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8971 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8972 "not{<imodesuffix>}\t%0"
8973 [(set_attr "type" "negnot")
8974 (set_attr "mode" "<MODE>")])
8975
8976 ;; %%% Potential partial reg stall on alternative 1. What to do?
8977 (define_insn "*one_cmplqi2_1"
8978 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8979 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8980 "ix86_unary_operator_ok (NOT, QImode, operands)"
8981 "@
8982 not{b}\t%0
8983 not{l}\t%k0"
8984 [(set_attr "type" "negnot")
8985 (set_attr "mode" "QI,SI")])
8986
8987 ;; ??? Currently never generated - xor is used instead.
8988 (define_insn "*one_cmplsi2_1_zext"
8989 [(set (match_operand:DI 0 "register_operand" "=r")
8990 (zero_extend:DI
8991 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8992 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8993 "not{l}\t%k0"
8994 [(set_attr "type" "negnot")
8995 (set_attr "mode" "SI")])
8996
8997 (define_insn "*one_cmpl<mode>2_2"
8998 [(set (reg FLAGS_REG)
8999 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9000 (const_int 0)))
9001 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9002 (not:SWI (match_dup 1)))]
9003 "ix86_match_ccmode (insn, CCNOmode)
9004 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9005 "#"
9006 [(set_attr "type" "alu1")
9007 (set_attr "mode" "<MODE>")])
9008
9009 (define_split
9010 [(set (match_operand 0 "flags_reg_operand")
9011 (match_operator 2 "compare_operator"
9012 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9013 (const_int 0)]))
9014 (set (match_operand:SWI 1 "nonimmediate_operand")
9015 (not:SWI (match_dup 3)))]
9016 "ix86_match_ccmode (insn, CCNOmode)"
9017 [(parallel [(set (match_dup 0)
9018 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9019 (const_int 0)]))
9020 (set (match_dup 1)
9021 (xor:SWI (match_dup 3) (const_int -1)))])])
9022
9023 ;; ??? Currently never generated - xor is used instead.
9024 (define_insn "*one_cmplsi2_2_zext"
9025 [(set (reg FLAGS_REG)
9026 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9027 (const_int 0)))
9028 (set (match_operand:DI 0 "register_operand" "=r")
9029 (zero_extend:DI (not:SI (match_dup 1))))]
9030 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9031 && ix86_unary_operator_ok (NOT, SImode, operands)"
9032 "#"
9033 [(set_attr "type" "alu1")
9034 (set_attr "mode" "SI")])
9035
9036 (define_split
9037 [(set (match_operand 0 "flags_reg_operand")
9038 (match_operator 2 "compare_operator"
9039 [(not:SI (match_operand:SI 3 "register_operand"))
9040 (const_int 0)]))
9041 (set (match_operand:DI 1 "register_operand")
9042 (zero_extend:DI (not:SI (match_dup 3))))]
9043 "ix86_match_ccmode (insn, CCNOmode)"
9044 [(parallel [(set (match_dup 0)
9045 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9046 (const_int 0)]))
9047 (set (match_dup 1)
9048 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9049 \f
9050 ;; Shift instructions
9051
9052 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9053 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9054 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9055 ;; from the assembler input.
9056 ;;
9057 ;; This instruction shifts the target reg/mem as usual, but instead of
9058 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9059 ;; is a left shift double, bits are taken from the high order bits of
9060 ;; reg, else if the insn is a shift right double, bits are taken from the
9061 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9062 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9063 ;;
9064 ;; Since sh[lr]d does not change the `reg' operand, that is done
9065 ;; separately, making all shifts emit pairs of shift double and normal
9066 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9067 ;; support a 63 bit shift, each shift where the count is in a reg expands
9068 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9069 ;;
9070 ;; If the shift count is a constant, we need never emit more than one
9071 ;; shift pair, instead using moves and sign extension for counts greater
9072 ;; than 31.
9073
9074 (define_expand "ashl<mode>3"
9075 [(set (match_operand:SDWIM 0 "<shift_operand>")
9076 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9077 (match_operand:QI 2 "nonmemory_operand")))]
9078 ""
9079 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9080
9081 (define_insn "*ashl<mode>3_doubleword"
9082 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9083 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9084 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9085 (clobber (reg:CC FLAGS_REG))]
9086 ""
9087 "#"
9088 [(set_attr "type" "multi")])
9089
9090 (define_split
9091 [(set (match_operand:DWI 0 "register_operand")
9092 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9093 (match_operand:QI 2 "nonmemory_operand")))
9094 (clobber (reg:CC FLAGS_REG))]
9095 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9096 [(const_int 0)]
9097 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9098
9099 ;; By default we don't ask for a scratch register, because when DWImode
9100 ;; values are manipulated, registers are already at a premium. But if
9101 ;; we have one handy, we won't turn it away.
9102
9103 (define_peephole2
9104 [(match_scratch:DWIH 3 "r")
9105 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9106 (ashift:<DWI>
9107 (match_operand:<DWI> 1 "nonmemory_operand")
9108 (match_operand:QI 2 "nonmemory_operand")))
9109 (clobber (reg:CC FLAGS_REG))])
9110 (match_dup 3)]
9111 "TARGET_CMOVE"
9112 [(const_int 0)]
9113 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9114
9115 (define_insn "x86_64_shld"
9116 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9117 (ior:DI (ashift:DI (match_dup 0)
9118 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9119 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9120 (minus:QI (const_int 64) (match_dup 2)))))
9121 (clobber (reg:CC FLAGS_REG))]
9122 "TARGET_64BIT"
9123 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9124 [(set_attr "type" "ishift")
9125 (set_attr "prefix_0f" "1")
9126 (set_attr "mode" "DI")
9127 (set_attr "athlon_decode" "vector")
9128 (set_attr "amdfam10_decode" "vector")
9129 (set_attr "bdver1_decode" "vector")])
9130
9131 (define_insn "x86_shld"
9132 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9133 (ior:SI (ashift:SI (match_dup 0)
9134 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9135 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9136 (minus:QI (const_int 32) (match_dup 2)))))
9137 (clobber (reg:CC FLAGS_REG))]
9138 ""
9139 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9140 [(set_attr "type" "ishift")
9141 (set_attr "prefix_0f" "1")
9142 (set_attr "mode" "SI")
9143 (set_attr "pent_pair" "np")
9144 (set_attr "athlon_decode" "vector")
9145 (set_attr "amdfam10_decode" "vector")
9146 (set_attr "bdver1_decode" "vector")])
9147
9148 (define_expand "x86_shift<mode>_adj_1"
9149 [(set (reg:CCZ FLAGS_REG)
9150 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9151 (match_dup 4))
9152 (const_int 0)))
9153 (set (match_operand:SWI48 0 "register_operand")
9154 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9155 (match_operand:SWI48 1 "register_operand")
9156 (match_dup 0)))
9157 (set (match_dup 1)
9158 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9159 (match_operand:SWI48 3 "register_operand")
9160 (match_dup 1)))]
9161 "TARGET_CMOVE"
9162 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9163
9164 (define_expand "x86_shift<mode>_adj_2"
9165 [(use (match_operand:SWI48 0 "register_operand"))
9166 (use (match_operand:SWI48 1 "register_operand"))
9167 (use (match_operand:QI 2 "register_operand"))]
9168 ""
9169 {
9170 rtx label = gen_label_rtx ();
9171 rtx tmp;
9172
9173 emit_insn (gen_testqi_ccz_1 (operands[2],
9174 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9175
9176 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9177 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9178 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9179 gen_rtx_LABEL_REF (VOIDmode, label),
9180 pc_rtx);
9181 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9182 JUMP_LABEL (tmp) = label;
9183
9184 emit_move_insn (operands[0], operands[1]);
9185 ix86_expand_clear (operands[1]);
9186
9187 emit_label (label);
9188 LABEL_NUSES (label) = 1;
9189
9190 DONE;
9191 })
9192
9193 ;; Avoid useless masking of count operand.
9194 (define_insn_and_split "*ashl<mode>3_mask"
9195 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9196 (ashift:SWI48
9197 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9198 (subreg:QI
9199 (and:SI
9200 (match_operand:SI 2 "nonimmediate_operand" "c")
9201 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9202 (clobber (reg:CC FLAGS_REG))]
9203 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9204 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9205 == GET_MODE_BITSIZE (<MODE>mode)-1"
9206 "#"
9207 "&& 1"
9208 [(parallel [(set (match_dup 0)
9209 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9210 (clobber (reg:CC FLAGS_REG))])]
9211 {
9212 if (can_create_pseudo_p ())
9213 operands [2] = force_reg (SImode, operands[2]);
9214
9215 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9216 }
9217 [(set_attr "type" "ishift")
9218 (set_attr "mode" "<MODE>")])
9219
9220 (define_insn "*bmi2_ashl<mode>3_1"
9221 [(set (match_operand:SWI48 0 "register_operand" "=r")
9222 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9223 (match_operand:SWI48 2 "register_operand" "r")))]
9224 "TARGET_BMI2"
9225 "shlx\t{%2, %1, %0|%0, %1, %2}"
9226 [(set_attr "type" "ishiftx")
9227 (set_attr "mode" "<MODE>")])
9228
9229 (define_insn "*ashl<mode>3_1"
9230 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9231 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9232 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9233 (clobber (reg:CC FLAGS_REG))]
9234 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9235 {
9236 switch (get_attr_type (insn))
9237 {
9238 case TYPE_LEA:
9239 case TYPE_ISHIFTX:
9240 return "#";
9241
9242 case TYPE_ALU:
9243 gcc_assert (operands[2] == const1_rtx);
9244 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9245 return "add{<imodesuffix>}\t%0, %0";
9246
9247 default:
9248 if (operands[2] == const1_rtx
9249 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9250 return "sal{<imodesuffix>}\t%0";
9251 else
9252 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9253 }
9254 }
9255 [(set_attr "isa" "*,*,bmi2")
9256 (set (attr "type")
9257 (cond [(eq_attr "alternative" "1")
9258 (const_string "lea")
9259 (eq_attr "alternative" "2")
9260 (const_string "ishiftx")
9261 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9262 (match_operand 0 "register_operand"))
9263 (match_operand 2 "const1_operand"))
9264 (const_string "alu")
9265 ]
9266 (const_string "ishift")))
9267 (set (attr "length_immediate")
9268 (if_then_else
9269 (ior (eq_attr "type" "alu")
9270 (and (eq_attr "type" "ishift")
9271 (and (match_operand 2 "const1_operand")
9272 (ior (match_test "TARGET_SHIFT1")
9273 (match_test "optimize_function_for_size_p (cfun)")))))
9274 (const_string "0")
9275 (const_string "*")))
9276 (set_attr "mode" "<MODE>")])
9277
9278 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9279 (define_split
9280 [(set (match_operand:SWI48 0 "register_operand")
9281 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9282 (match_operand:QI 2 "register_operand")))
9283 (clobber (reg:CC FLAGS_REG))]
9284 "TARGET_BMI2 && reload_completed"
9285 [(set (match_dup 0)
9286 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9287 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9288
9289 (define_insn "*bmi2_ashlsi3_1_zext"
9290 [(set (match_operand:DI 0 "register_operand" "=r")
9291 (zero_extend:DI
9292 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9293 (match_operand:SI 2 "register_operand" "r"))))]
9294 "TARGET_64BIT && TARGET_BMI2"
9295 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9296 [(set_attr "type" "ishiftx")
9297 (set_attr "mode" "SI")])
9298
9299 (define_insn "*ashlsi3_1_zext"
9300 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9301 (zero_extend:DI
9302 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9303 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9304 (clobber (reg:CC FLAGS_REG))]
9305 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9306 {
9307 switch (get_attr_type (insn))
9308 {
9309 case TYPE_LEA:
9310 case TYPE_ISHIFTX:
9311 return "#";
9312
9313 case TYPE_ALU:
9314 gcc_assert (operands[2] == const1_rtx);
9315 return "add{l}\t%k0, %k0";
9316
9317 default:
9318 if (operands[2] == const1_rtx
9319 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9320 return "sal{l}\t%k0";
9321 else
9322 return "sal{l}\t{%2, %k0|%k0, %2}";
9323 }
9324 }
9325 [(set_attr "isa" "*,*,bmi2")
9326 (set (attr "type")
9327 (cond [(eq_attr "alternative" "1")
9328 (const_string "lea")
9329 (eq_attr "alternative" "2")
9330 (const_string "ishiftx")
9331 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9332 (match_operand 2 "const1_operand"))
9333 (const_string "alu")
9334 ]
9335 (const_string "ishift")))
9336 (set (attr "length_immediate")
9337 (if_then_else
9338 (ior (eq_attr "type" "alu")
9339 (and (eq_attr "type" "ishift")
9340 (and (match_operand 2 "const1_operand")
9341 (ior (match_test "TARGET_SHIFT1")
9342 (match_test "optimize_function_for_size_p (cfun)")))))
9343 (const_string "0")
9344 (const_string "*")))
9345 (set_attr "mode" "SI")])
9346
9347 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9348 (define_split
9349 [(set (match_operand:DI 0 "register_operand")
9350 (zero_extend:DI
9351 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9352 (match_operand:QI 2 "register_operand"))))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9355 [(set (match_dup 0)
9356 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9357 "operands[2] = gen_lowpart (SImode, operands[2]);")
9358
9359 (define_insn "*ashlhi3_1"
9360 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9361 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9362 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9363 (clobber (reg:CC FLAGS_REG))]
9364 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9365 {
9366 switch (get_attr_type (insn))
9367 {
9368 case TYPE_LEA:
9369 return "#";
9370
9371 case TYPE_ALU:
9372 gcc_assert (operands[2] == const1_rtx);
9373 return "add{w}\t%0, %0";
9374
9375 default:
9376 if (operands[2] == const1_rtx
9377 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9378 return "sal{w}\t%0";
9379 else
9380 return "sal{w}\t{%2, %0|%0, %2}";
9381 }
9382 }
9383 [(set (attr "type")
9384 (cond [(eq_attr "alternative" "1")
9385 (const_string "lea")
9386 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9387 (match_operand 0 "register_operand"))
9388 (match_operand 2 "const1_operand"))
9389 (const_string "alu")
9390 ]
9391 (const_string "ishift")))
9392 (set (attr "length_immediate")
9393 (if_then_else
9394 (ior (eq_attr "type" "alu")
9395 (and (eq_attr "type" "ishift")
9396 (and (match_operand 2 "const1_operand")
9397 (ior (match_test "TARGET_SHIFT1")
9398 (match_test "optimize_function_for_size_p (cfun)")))))
9399 (const_string "0")
9400 (const_string "*")))
9401 (set_attr "mode" "HI,SI")])
9402
9403 ;; %%% Potential partial reg stall on alternative 1. What to do?
9404 (define_insn "*ashlqi3_1"
9405 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9406 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9407 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9408 (clobber (reg:CC FLAGS_REG))]
9409 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9410 {
9411 switch (get_attr_type (insn))
9412 {
9413 case TYPE_LEA:
9414 return "#";
9415
9416 case TYPE_ALU:
9417 gcc_assert (operands[2] == const1_rtx);
9418 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9419 return "add{l}\t%k0, %k0";
9420 else
9421 return "add{b}\t%0, %0";
9422
9423 default:
9424 if (operands[2] == const1_rtx
9425 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9426 {
9427 if (get_attr_mode (insn) == MODE_SI)
9428 return "sal{l}\t%k0";
9429 else
9430 return "sal{b}\t%0";
9431 }
9432 else
9433 {
9434 if (get_attr_mode (insn) == MODE_SI)
9435 return "sal{l}\t{%2, %k0|%k0, %2}";
9436 else
9437 return "sal{b}\t{%2, %0|%0, %2}";
9438 }
9439 }
9440 }
9441 [(set (attr "type")
9442 (cond [(eq_attr "alternative" "2")
9443 (const_string "lea")
9444 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9445 (match_operand 0 "register_operand"))
9446 (match_operand 2 "const1_operand"))
9447 (const_string "alu")
9448 ]
9449 (const_string "ishift")))
9450 (set (attr "length_immediate")
9451 (if_then_else
9452 (ior (eq_attr "type" "alu")
9453 (and (eq_attr "type" "ishift")
9454 (and (match_operand 2 "const1_operand")
9455 (ior (match_test "TARGET_SHIFT1")
9456 (match_test "optimize_function_for_size_p (cfun)")))))
9457 (const_string "0")
9458 (const_string "*")))
9459 (set_attr "mode" "QI,SI,SI")])
9460
9461 (define_insn "*ashlqi3_1_slp"
9462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9463 (ashift:QI (match_dup 0)
9464 (match_operand:QI 1 "nonmemory_operand" "cI")))
9465 (clobber (reg:CC FLAGS_REG))]
9466 "(optimize_function_for_size_p (cfun)
9467 || !TARGET_PARTIAL_FLAG_REG_STALL
9468 || (operands[1] == const1_rtx
9469 && (TARGET_SHIFT1
9470 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9471 {
9472 switch (get_attr_type (insn))
9473 {
9474 case TYPE_ALU:
9475 gcc_assert (operands[1] == const1_rtx);
9476 return "add{b}\t%0, %0";
9477
9478 default:
9479 if (operands[1] == const1_rtx
9480 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9481 return "sal{b}\t%0";
9482 else
9483 return "sal{b}\t{%1, %0|%0, %1}";
9484 }
9485 }
9486 [(set (attr "type")
9487 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9488 (match_operand 0 "register_operand"))
9489 (match_operand 1 "const1_operand"))
9490 (const_string "alu")
9491 ]
9492 (const_string "ishift1")))
9493 (set (attr "length_immediate")
9494 (if_then_else
9495 (ior (eq_attr "type" "alu")
9496 (and (eq_attr "type" "ishift1")
9497 (and (match_operand 1 "const1_operand")
9498 (ior (match_test "TARGET_SHIFT1")
9499 (match_test "optimize_function_for_size_p (cfun)")))))
9500 (const_string "0")
9501 (const_string "*")))
9502 (set_attr "mode" "QI")])
9503
9504 ;; Convert ashift to the lea pattern to avoid flags dependency.
9505 (define_split
9506 [(set (match_operand 0 "register_operand")
9507 (ashift (match_operand 1 "index_register_operand")
9508 (match_operand:QI 2 "const_int_operand")))
9509 (clobber (reg:CC FLAGS_REG))]
9510 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9511 && reload_completed
9512 && true_regnum (operands[0]) != true_regnum (operands[1])"
9513 [(const_int 0)]
9514 {
9515 enum machine_mode mode = GET_MODE (operands[0]);
9516 rtx pat;
9517
9518 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9519 {
9520 mode = SImode;
9521 operands[0] = gen_lowpart (mode, operands[0]);
9522 operands[1] = gen_lowpart (mode, operands[1]);
9523 }
9524
9525 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9526
9527 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9528
9529 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9530 DONE;
9531 })
9532
9533 ;; Convert ashift to the lea pattern to avoid flags dependency.
9534 (define_split
9535 [(set (match_operand:DI 0 "register_operand")
9536 (zero_extend:DI
9537 (ashift:SI (match_operand:SI 1 "index_register_operand")
9538 (match_operand:QI 2 "const_int_operand"))))
9539 (clobber (reg:CC FLAGS_REG))]
9540 "TARGET_64BIT && reload_completed
9541 && true_regnum (operands[0]) != true_regnum (operands[1])"
9542 [(set (match_dup 0)
9543 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9544 {
9545 operands[1] = gen_lowpart (DImode, operands[1]);
9546 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9547 })
9548
9549 ;; This pattern can't accept a variable shift count, since shifts by
9550 ;; zero don't affect the flags. We assume that shifts by constant
9551 ;; zero are optimized away.
9552 (define_insn "*ashl<mode>3_cmp"
9553 [(set (reg FLAGS_REG)
9554 (compare
9555 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9556 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9557 (const_int 0)))
9558 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9559 (ashift:SWI (match_dup 1) (match_dup 2)))]
9560 "(optimize_function_for_size_p (cfun)
9561 || !TARGET_PARTIAL_FLAG_REG_STALL
9562 || (operands[2] == const1_rtx
9563 && (TARGET_SHIFT1
9564 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9565 && ix86_match_ccmode (insn, CCGOCmode)
9566 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9567 {
9568 switch (get_attr_type (insn))
9569 {
9570 case TYPE_ALU:
9571 gcc_assert (operands[2] == const1_rtx);
9572 return "add{<imodesuffix>}\t%0, %0";
9573
9574 default:
9575 if (operands[2] == const1_rtx
9576 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9577 return "sal{<imodesuffix>}\t%0";
9578 else
9579 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9580 }
9581 }
9582 [(set (attr "type")
9583 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9584 (match_operand 0 "register_operand"))
9585 (match_operand 2 "const1_operand"))
9586 (const_string "alu")
9587 ]
9588 (const_string "ishift")))
9589 (set (attr "length_immediate")
9590 (if_then_else
9591 (ior (eq_attr "type" "alu")
9592 (and (eq_attr "type" "ishift")
9593 (and (match_operand 2 "const1_operand")
9594 (ior (match_test "TARGET_SHIFT1")
9595 (match_test "optimize_function_for_size_p (cfun)")))))
9596 (const_string "0")
9597 (const_string "*")))
9598 (set_attr "mode" "<MODE>")])
9599
9600 (define_insn "*ashlsi3_cmp_zext"
9601 [(set (reg FLAGS_REG)
9602 (compare
9603 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9604 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9605 (const_int 0)))
9606 (set (match_operand:DI 0 "register_operand" "=r")
9607 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9608 "TARGET_64BIT
9609 && (optimize_function_for_size_p (cfun)
9610 || !TARGET_PARTIAL_FLAG_REG_STALL
9611 || (operands[2] == const1_rtx
9612 && (TARGET_SHIFT1
9613 || TARGET_DOUBLE_WITH_ADD)))
9614 && ix86_match_ccmode (insn, CCGOCmode)
9615 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9616 {
9617 switch (get_attr_type (insn))
9618 {
9619 case TYPE_ALU:
9620 gcc_assert (operands[2] == const1_rtx);
9621 return "add{l}\t%k0, %k0";
9622
9623 default:
9624 if (operands[2] == const1_rtx
9625 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9626 return "sal{l}\t%k0";
9627 else
9628 return "sal{l}\t{%2, %k0|%k0, %2}";
9629 }
9630 }
9631 [(set (attr "type")
9632 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9633 (match_operand 2 "const1_operand"))
9634 (const_string "alu")
9635 ]
9636 (const_string "ishift")))
9637 (set (attr "length_immediate")
9638 (if_then_else
9639 (ior (eq_attr "type" "alu")
9640 (and (eq_attr "type" "ishift")
9641 (and (match_operand 2 "const1_operand")
9642 (ior (match_test "TARGET_SHIFT1")
9643 (match_test "optimize_function_for_size_p (cfun)")))))
9644 (const_string "0")
9645 (const_string "*")))
9646 (set_attr "mode" "SI")])
9647
9648 (define_insn "*ashl<mode>3_cconly"
9649 [(set (reg FLAGS_REG)
9650 (compare
9651 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9652 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9653 (const_int 0)))
9654 (clobber (match_scratch:SWI 0 "=<r>"))]
9655 "(optimize_function_for_size_p (cfun)
9656 || !TARGET_PARTIAL_FLAG_REG_STALL
9657 || (operands[2] == const1_rtx
9658 && (TARGET_SHIFT1
9659 || TARGET_DOUBLE_WITH_ADD)))
9660 && ix86_match_ccmode (insn, CCGOCmode)"
9661 {
9662 switch (get_attr_type (insn))
9663 {
9664 case TYPE_ALU:
9665 gcc_assert (operands[2] == const1_rtx);
9666 return "add{<imodesuffix>}\t%0, %0";
9667
9668 default:
9669 if (operands[2] == const1_rtx
9670 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9671 return "sal{<imodesuffix>}\t%0";
9672 else
9673 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9674 }
9675 }
9676 [(set (attr "type")
9677 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9678 (match_operand 0 "register_operand"))
9679 (match_operand 2 "const1_operand"))
9680 (const_string "alu")
9681 ]
9682 (const_string "ishift")))
9683 (set (attr "length_immediate")
9684 (if_then_else
9685 (ior (eq_attr "type" "alu")
9686 (and (eq_attr "type" "ishift")
9687 (and (match_operand 2 "const1_operand")
9688 (ior (match_test "TARGET_SHIFT1")
9689 (match_test "optimize_function_for_size_p (cfun)")))))
9690 (const_string "0")
9691 (const_string "*")))
9692 (set_attr "mode" "<MODE>")])
9693
9694 ;; See comment above `ashl<mode>3' about how this works.
9695
9696 (define_expand "<shift_insn><mode>3"
9697 [(set (match_operand:SDWIM 0 "<shift_operand>")
9698 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9699 (match_operand:QI 2 "nonmemory_operand")))]
9700 ""
9701 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9702
9703 ;; Avoid useless masking of count operand.
9704 (define_insn_and_split "*<shift_insn><mode>3_mask"
9705 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9706 (any_shiftrt:SWI48
9707 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9708 (subreg:QI
9709 (and:SI
9710 (match_operand:SI 2 "nonimmediate_operand" "c")
9711 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9712 (clobber (reg:CC FLAGS_REG))]
9713 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9714 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9715 == GET_MODE_BITSIZE (<MODE>mode)-1"
9716 "#"
9717 "&& 1"
9718 [(parallel [(set (match_dup 0)
9719 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9720 (clobber (reg:CC FLAGS_REG))])]
9721 {
9722 if (can_create_pseudo_p ())
9723 operands [2] = force_reg (SImode, operands[2]);
9724
9725 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9726 }
9727 [(set_attr "type" "ishift")
9728 (set_attr "mode" "<MODE>")])
9729
9730 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9731 [(set (match_operand:DWI 0 "register_operand" "=r")
9732 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9733 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9734 (clobber (reg:CC FLAGS_REG))]
9735 ""
9736 "#"
9737 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9738 [(const_int 0)]
9739 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9740 [(set_attr "type" "multi")])
9741
9742 ;; By default we don't ask for a scratch register, because when DWImode
9743 ;; values are manipulated, registers are already at a premium. But if
9744 ;; we have one handy, we won't turn it away.
9745
9746 (define_peephole2
9747 [(match_scratch:DWIH 3 "r")
9748 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9749 (any_shiftrt:<DWI>
9750 (match_operand:<DWI> 1 "register_operand")
9751 (match_operand:QI 2 "nonmemory_operand")))
9752 (clobber (reg:CC FLAGS_REG))])
9753 (match_dup 3)]
9754 "TARGET_CMOVE"
9755 [(const_int 0)]
9756 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9757
9758 (define_insn "x86_64_shrd"
9759 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9760 (ior:DI (ashiftrt:DI (match_dup 0)
9761 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9762 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9763 (minus:QI (const_int 64) (match_dup 2)))))
9764 (clobber (reg:CC FLAGS_REG))]
9765 "TARGET_64BIT"
9766 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9767 [(set_attr "type" "ishift")
9768 (set_attr "prefix_0f" "1")
9769 (set_attr "mode" "DI")
9770 (set_attr "athlon_decode" "vector")
9771 (set_attr "amdfam10_decode" "vector")
9772 (set_attr "bdver1_decode" "vector")])
9773
9774 (define_insn "x86_shrd"
9775 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9776 (ior:SI (ashiftrt:SI (match_dup 0)
9777 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9778 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9779 (minus:QI (const_int 32) (match_dup 2)))))
9780 (clobber (reg:CC FLAGS_REG))]
9781 ""
9782 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9783 [(set_attr "type" "ishift")
9784 (set_attr "prefix_0f" "1")
9785 (set_attr "mode" "SI")
9786 (set_attr "pent_pair" "np")
9787 (set_attr "athlon_decode" "vector")
9788 (set_attr "amdfam10_decode" "vector")
9789 (set_attr "bdver1_decode" "vector")])
9790
9791 (define_insn "ashrdi3_cvt"
9792 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9793 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9794 (match_operand:QI 2 "const_int_operand")))
9795 (clobber (reg:CC FLAGS_REG))]
9796 "TARGET_64BIT && INTVAL (operands[2]) == 63
9797 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9798 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9799 "@
9800 {cqto|cqo}
9801 sar{q}\t{%2, %0|%0, %2}"
9802 [(set_attr "type" "imovx,ishift")
9803 (set_attr "prefix_0f" "0,*")
9804 (set_attr "length_immediate" "0,*")
9805 (set_attr "modrm" "0,1")
9806 (set_attr "mode" "DI")])
9807
9808 (define_insn "ashrsi3_cvt"
9809 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9810 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9811 (match_operand:QI 2 "const_int_operand")))
9812 (clobber (reg:CC FLAGS_REG))]
9813 "INTVAL (operands[2]) == 31
9814 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9815 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9816 "@
9817 {cltd|cdq}
9818 sar{l}\t{%2, %0|%0, %2}"
9819 [(set_attr "type" "imovx,ishift")
9820 (set_attr "prefix_0f" "0,*")
9821 (set_attr "length_immediate" "0,*")
9822 (set_attr "modrm" "0,1")
9823 (set_attr "mode" "SI")])
9824
9825 (define_insn "*ashrsi3_cvt_zext"
9826 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9827 (zero_extend:DI
9828 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9829 (match_operand:QI 2 "const_int_operand"))))
9830 (clobber (reg:CC FLAGS_REG))]
9831 "TARGET_64BIT && INTVAL (operands[2]) == 31
9832 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9833 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9834 "@
9835 {cltd|cdq}
9836 sar{l}\t{%2, %k0|%k0, %2}"
9837 [(set_attr "type" "imovx,ishift")
9838 (set_attr "prefix_0f" "0,*")
9839 (set_attr "length_immediate" "0,*")
9840 (set_attr "modrm" "0,1")
9841 (set_attr "mode" "SI")])
9842
9843 (define_expand "x86_shift<mode>_adj_3"
9844 [(use (match_operand:SWI48 0 "register_operand"))
9845 (use (match_operand:SWI48 1 "register_operand"))
9846 (use (match_operand:QI 2 "register_operand"))]
9847 ""
9848 {
9849 rtx label = gen_label_rtx ();
9850 rtx tmp;
9851
9852 emit_insn (gen_testqi_ccz_1 (operands[2],
9853 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9854
9855 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9856 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9857 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9858 gen_rtx_LABEL_REF (VOIDmode, label),
9859 pc_rtx);
9860 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9861 JUMP_LABEL (tmp) = label;
9862
9863 emit_move_insn (operands[0], operands[1]);
9864 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9865 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9866 emit_label (label);
9867 LABEL_NUSES (label) = 1;
9868
9869 DONE;
9870 })
9871
9872 (define_insn "*bmi2_<shift_insn><mode>3_1"
9873 [(set (match_operand:SWI48 0 "register_operand" "=r")
9874 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9875 (match_operand:SWI48 2 "register_operand" "r")))]
9876 "TARGET_BMI2"
9877 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9878 [(set_attr "type" "ishiftx")
9879 (set_attr "mode" "<MODE>")])
9880
9881 (define_insn "*<shift_insn><mode>3_1"
9882 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9883 (any_shiftrt:SWI48
9884 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9885 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9886 (clobber (reg:CC FLAGS_REG))]
9887 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9888 {
9889 switch (get_attr_type (insn))
9890 {
9891 case TYPE_ISHIFTX:
9892 return "#";
9893
9894 default:
9895 if (operands[2] == const1_rtx
9896 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9897 return "<shift>{<imodesuffix>}\t%0";
9898 else
9899 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9900 }
9901 }
9902 [(set_attr "isa" "*,bmi2")
9903 (set_attr "type" "ishift,ishiftx")
9904 (set (attr "length_immediate")
9905 (if_then_else
9906 (and (match_operand 2 "const1_operand")
9907 (ior (match_test "TARGET_SHIFT1")
9908 (match_test "optimize_function_for_size_p (cfun)")))
9909 (const_string "0")
9910 (const_string "*")))
9911 (set_attr "mode" "<MODE>")])
9912
9913 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9914 (define_split
9915 [(set (match_operand:SWI48 0 "register_operand")
9916 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9917 (match_operand:QI 2 "register_operand")))
9918 (clobber (reg:CC FLAGS_REG))]
9919 "TARGET_BMI2 && reload_completed"
9920 [(set (match_dup 0)
9921 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9922 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9923
9924 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9925 [(set (match_operand:DI 0 "register_operand" "=r")
9926 (zero_extend:DI
9927 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9928 (match_operand:SI 2 "register_operand" "r"))))]
9929 "TARGET_64BIT && TARGET_BMI2"
9930 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9931 [(set_attr "type" "ishiftx")
9932 (set_attr "mode" "SI")])
9933
9934 (define_insn "*<shift_insn>si3_1_zext"
9935 [(set (match_operand:DI 0 "register_operand" "=r,r")
9936 (zero_extend:DI
9937 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9938 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9939 (clobber (reg:CC FLAGS_REG))]
9940 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9941 {
9942 switch (get_attr_type (insn))
9943 {
9944 case TYPE_ISHIFTX:
9945 return "#";
9946
9947 default:
9948 if (operands[2] == const1_rtx
9949 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9950 return "<shift>{l}\t%k0";
9951 else
9952 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9953 }
9954 }
9955 [(set_attr "isa" "*,bmi2")
9956 (set_attr "type" "ishift,ishiftx")
9957 (set (attr "length_immediate")
9958 (if_then_else
9959 (and (match_operand 2 "const1_operand")
9960 (ior (match_test "TARGET_SHIFT1")
9961 (match_test "optimize_function_for_size_p (cfun)")))
9962 (const_string "0")
9963 (const_string "*")))
9964 (set_attr "mode" "SI")])
9965
9966 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9967 (define_split
9968 [(set (match_operand:DI 0 "register_operand")
9969 (zero_extend:DI
9970 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9971 (match_operand:QI 2 "register_operand"))))
9972 (clobber (reg:CC FLAGS_REG))]
9973 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9974 [(set (match_dup 0)
9975 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9976 "operands[2] = gen_lowpart (SImode, operands[2]);")
9977
9978 (define_insn "*<shift_insn><mode>3_1"
9979 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9980 (any_shiftrt:SWI12
9981 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9982 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9983 (clobber (reg:CC FLAGS_REG))]
9984 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9985 {
9986 if (operands[2] == const1_rtx
9987 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9988 return "<shift>{<imodesuffix>}\t%0";
9989 else
9990 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9991 }
9992 [(set_attr "type" "ishift")
9993 (set (attr "length_immediate")
9994 (if_then_else
9995 (and (match_operand 2 "const1_operand")
9996 (ior (match_test "TARGET_SHIFT1")
9997 (match_test "optimize_function_for_size_p (cfun)")))
9998 (const_string "0")
9999 (const_string "*")))
10000 (set_attr "mode" "<MODE>")])
10001
10002 (define_insn "*<shift_insn>qi3_1_slp"
10003 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10004 (any_shiftrt:QI (match_dup 0)
10005 (match_operand:QI 1 "nonmemory_operand" "cI")))
10006 (clobber (reg:CC FLAGS_REG))]
10007 "(optimize_function_for_size_p (cfun)
10008 || !TARGET_PARTIAL_REG_STALL
10009 || (operands[1] == const1_rtx
10010 && TARGET_SHIFT1))"
10011 {
10012 if (operands[1] == const1_rtx
10013 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10014 return "<shift>{b}\t%0";
10015 else
10016 return "<shift>{b}\t{%1, %0|%0, %1}";
10017 }
10018 [(set_attr "type" "ishift1")
10019 (set (attr "length_immediate")
10020 (if_then_else
10021 (and (match_operand 1 "const1_operand")
10022 (ior (match_test "TARGET_SHIFT1")
10023 (match_test "optimize_function_for_size_p (cfun)")))
10024 (const_string "0")
10025 (const_string "*")))
10026 (set_attr "mode" "QI")])
10027
10028 ;; This pattern can't accept a variable shift count, since shifts by
10029 ;; zero don't affect the flags. We assume that shifts by constant
10030 ;; zero are optimized away.
10031 (define_insn "*<shift_insn><mode>3_cmp"
10032 [(set (reg FLAGS_REG)
10033 (compare
10034 (any_shiftrt:SWI
10035 (match_operand:SWI 1 "nonimmediate_operand" "0")
10036 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10037 (const_int 0)))
10038 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10039 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10040 "(optimize_function_for_size_p (cfun)
10041 || !TARGET_PARTIAL_FLAG_REG_STALL
10042 || (operands[2] == const1_rtx
10043 && TARGET_SHIFT1))
10044 && ix86_match_ccmode (insn, CCGOCmode)
10045 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10046 {
10047 if (operands[2] == const1_rtx
10048 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10049 return "<shift>{<imodesuffix>}\t%0";
10050 else
10051 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10052 }
10053 [(set_attr "type" "ishift")
10054 (set (attr "length_immediate")
10055 (if_then_else
10056 (and (match_operand 2 "const1_operand")
10057 (ior (match_test "TARGET_SHIFT1")
10058 (match_test "optimize_function_for_size_p (cfun)")))
10059 (const_string "0")
10060 (const_string "*")))
10061 (set_attr "mode" "<MODE>")])
10062
10063 (define_insn "*<shift_insn>si3_cmp_zext"
10064 [(set (reg FLAGS_REG)
10065 (compare
10066 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10067 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10068 (const_int 0)))
10069 (set (match_operand:DI 0 "register_operand" "=r")
10070 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10071 "TARGET_64BIT
10072 && (optimize_function_for_size_p (cfun)
10073 || !TARGET_PARTIAL_FLAG_REG_STALL
10074 || (operands[2] == const1_rtx
10075 && TARGET_SHIFT1))
10076 && ix86_match_ccmode (insn, CCGOCmode)
10077 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10078 {
10079 if (operands[2] == const1_rtx
10080 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10081 return "<shift>{l}\t%k0";
10082 else
10083 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10084 }
10085 [(set_attr "type" "ishift")
10086 (set (attr "length_immediate")
10087 (if_then_else
10088 (and (match_operand 2 "const1_operand")
10089 (ior (match_test "TARGET_SHIFT1")
10090 (match_test "optimize_function_for_size_p (cfun)")))
10091 (const_string "0")
10092 (const_string "*")))
10093 (set_attr "mode" "SI")])
10094
10095 (define_insn "*<shift_insn><mode>3_cconly"
10096 [(set (reg FLAGS_REG)
10097 (compare
10098 (any_shiftrt:SWI
10099 (match_operand:SWI 1 "register_operand" "0")
10100 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10101 (const_int 0)))
10102 (clobber (match_scratch:SWI 0 "=<r>"))]
10103 "(optimize_function_for_size_p (cfun)
10104 || !TARGET_PARTIAL_FLAG_REG_STALL
10105 || (operands[2] == const1_rtx
10106 && TARGET_SHIFT1))
10107 && ix86_match_ccmode (insn, CCGOCmode)"
10108 {
10109 if (operands[2] == const1_rtx
10110 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10111 return "<shift>{<imodesuffix>}\t%0";
10112 else
10113 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10114 }
10115 [(set_attr "type" "ishift")
10116 (set (attr "length_immediate")
10117 (if_then_else
10118 (and (match_operand 2 "const1_operand")
10119 (ior (match_test "TARGET_SHIFT1")
10120 (match_test "optimize_function_for_size_p (cfun)")))
10121 (const_string "0")
10122 (const_string "*")))
10123 (set_attr "mode" "<MODE>")])
10124 \f
10125 ;; Rotate instructions
10126
10127 (define_expand "<rotate_insn>ti3"
10128 [(set (match_operand:TI 0 "register_operand")
10129 (any_rotate:TI (match_operand:TI 1 "register_operand")
10130 (match_operand:QI 2 "nonmemory_operand")))]
10131 "TARGET_64BIT"
10132 {
10133 if (const_1_to_63_operand (operands[2], VOIDmode))
10134 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10135 (operands[0], operands[1], operands[2]));
10136 else
10137 FAIL;
10138
10139 DONE;
10140 })
10141
10142 (define_expand "<rotate_insn>di3"
10143 [(set (match_operand:DI 0 "shiftdi_operand")
10144 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10145 (match_operand:QI 2 "nonmemory_operand")))]
10146 ""
10147 {
10148 if (TARGET_64BIT)
10149 ix86_expand_binary_operator (<CODE>, DImode, operands);
10150 else if (const_1_to_31_operand (operands[2], VOIDmode))
10151 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10152 (operands[0], operands[1], operands[2]));
10153 else
10154 FAIL;
10155
10156 DONE;
10157 })
10158
10159 (define_expand "<rotate_insn><mode>3"
10160 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10161 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10162 (match_operand:QI 2 "nonmemory_operand")))]
10163 ""
10164 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10165
10166 ;; Avoid useless masking of count operand.
10167 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10168 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10169 (any_rotate:SWI48
10170 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10171 (subreg:QI
10172 (and:SI
10173 (match_operand:SI 2 "nonimmediate_operand" "c")
10174 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10175 (clobber (reg:CC FLAGS_REG))]
10176 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10177 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10178 == GET_MODE_BITSIZE (<MODE>mode)-1"
10179 "#"
10180 "&& 1"
10181 [(parallel [(set (match_dup 0)
10182 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10183 (clobber (reg:CC FLAGS_REG))])]
10184 {
10185 if (can_create_pseudo_p ())
10186 operands [2] = force_reg (SImode, operands[2]);
10187
10188 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10189 }
10190 [(set_attr "type" "rotate")
10191 (set_attr "mode" "<MODE>")])
10192
10193 ;; Implement rotation using two double-precision
10194 ;; shift instructions and a scratch register.
10195
10196 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10197 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10198 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10199 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10200 (clobber (reg:CC FLAGS_REG))
10201 (clobber (match_scratch:DWIH 3 "=&r"))]
10202 ""
10203 "#"
10204 "reload_completed"
10205 [(set (match_dup 3) (match_dup 4))
10206 (parallel
10207 [(set (match_dup 4)
10208 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10209 (lshiftrt:DWIH (match_dup 5)
10210 (minus:QI (match_dup 6) (match_dup 2)))))
10211 (clobber (reg:CC FLAGS_REG))])
10212 (parallel
10213 [(set (match_dup 5)
10214 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10215 (lshiftrt:DWIH (match_dup 3)
10216 (minus:QI (match_dup 6) (match_dup 2)))))
10217 (clobber (reg:CC FLAGS_REG))])]
10218 {
10219 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10220
10221 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10222 })
10223
10224 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10225 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10226 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10227 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10228 (clobber (reg:CC FLAGS_REG))
10229 (clobber (match_scratch:DWIH 3 "=&r"))]
10230 ""
10231 "#"
10232 "reload_completed"
10233 [(set (match_dup 3) (match_dup 4))
10234 (parallel
10235 [(set (match_dup 4)
10236 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10237 (ashift:DWIH (match_dup 5)
10238 (minus:QI (match_dup 6) (match_dup 2)))))
10239 (clobber (reg:CC FLAGS_REG))])
10240 (parallel
10241 [(set (match_dup 5)
10242 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10243 (ashift:DWIH (match_dup 3)
10244 (minus:QI (match_dup 6) (match_dup 2)))))
10245 (clobber (reg:CC FLAGS_REG))])]
10246 {
10247 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10248
10249 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10250 })
10251
10252 (define_insn "*bmi2_rorx<mode>3_1"
10253 [(set (match_operand:SWI48 0 "register_operand" "=r")
10254 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10255 (match_operand:QI 2 "immediate_operand" "<S>")))]
10256 "TARGET_BMI2"
10257 "rorx\t{%2, %1, %0|%0, %1, %2}"
10258 [(set_attr "type" "rotatex")
10259 (set_attr "mode" "<MODE>")])
10260
10261 (define_insn "*<rotate_insn><mode>3_1"
10262 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10263 (any_rotate:SWI48
10264 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10265 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10266 (clobber (reg:CC FLAGS_REG))]
10267 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10268 {
10269 switch (get_attr_type (insn))
10270 {
10271 case TYPE_ROTATEX:
10272 return "#";
10273
10274 default:
10275 if (operands[2] == const1_rtx
10276 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10277 return "<rotate>{<imodesuffix>}\t%0";
10278 else
10279 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10280 }
10281 }
10282 [(set_attr "isa" "*,bmi2")
10283 (set_attr "type" "rotate,rotatex")
10284 (set (attr "length_immediate")
10285 (if_then_else
10286 (and (eq_attr "type" "rotate")
10287 (and (match_operand 2 "const1_operand")
10288 (ior (match_test "TARGET_SHIFT1")
10289 (match_test "optimize_function_for_size_p (cfun)"))))
10290 (const_string "0")
10291 (const_string "*")))
10292 (set_attr "mode" "<MODE>")])
10293
10294 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10295 (define_split
10296 [(set (match_operand:SWI48 0 "register_operand")
10297 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10298 (match_operand:QI 2 "immediate_operand")))
10299 (clobber (reg:CC FLAGS_REG))]
10300 "TARGET_BMI2 && reload_completed"
10301 [(set (match_dup 0)
10302 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10303 {
10304 operands[2]
10305 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10306 })
10307
10308 (define_split
10309 [(set (match_operand:SWI48 0 "register_operand")
10310 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10311 (match_operand:QI 2 "immediate_operand")))
10312 (clobber (reg:CC FLAGS_REG))]
10313 "TARGET_BMI2 && reload_completed"
10314 [(set (match_dup 0)
10315 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10316
10317 (define_insn "*bmi2_rorxsi3_1_zext"
10318 [(set (match_operand:DI 0 "register_operand" "=r")
10319 (zero_extend:DI
10320 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10321 (match_operand:QI 2 "immediate_operand" "I"))))]
10322 "TARGET_64BIT && TARGET_BMI2"
10323 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10324 [(set_attr "type" "rotatex")
10325 (set_attr "mode" "SI")])
10326
10327 (define_insn "*<rotate_insn>si3_1_zext"
10328 [(set (match_operand:DI 0 "register_operand" "=r,r")
10329 (zero_extend:DI
10330 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10331 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10332 (clobber (reg:CC FLAGS_REG))]
10333 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10334 {
10335 switch (get_attr_type (insn))
10336 {
10337 case TYPE_ROTATEX:
10338 return "#";
10339
10340 default:
10341 if (operands[2] == const1_rtx
10342 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10343 return "<rotate>{l}\t%k0";
10344 else
10345 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10346 }
10347 }
10348 [(set_attr "isa" "*,bmi2")
10349 (set_attr "type" "rotate,rotatex")
10350 (set (attr "length_immediate")
10351 (if_then_else
10352 (and (eq_attr "type" "rotate")
10353 (and (match_operand 2 "const1_operand")
10354 (ior (match_test "TARGET_SHIFT1")
10355 (match_test "optimize_function_for_size_p (cfun)"))))
10356 (const_string "0")
10357 (const_string "*")))
10358 (set_attr "mode" "SI")])
10359
10360 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10361 (define_split
10362 [(set (match_operand:DI 0 "register_operand")
10363 (zero_extend:DI
10364 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10365 (match_operand:QI 2 "immediate_operand"))))
10366 (clobber (reg:CC FLAGS_REG))]
10367 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10368 [(set (match_dup 0)
10369 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10370 {
10371 operands[2]
10372 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10373 })
10374
10375 (define_split
10376 [(set (match_operand:DI 0 "register_operand")
10377 (zero_extend:DI
10378 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10379 (match_operand:QI 2 "immediate_operand"))))
10380 (clobber (reg:CC FLAGS_REG))]
10381 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10382 [(set (match_dup 0)
10383 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10384
10385 (define_insn "*<rotate_insn><mode>3_1"
10386 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10387 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10388 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10389 (clobber (reg:CC FLAGS_REG))]
10390 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10391 {
10392 if (operands[2] == const1_rtx
10393 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10394 return "<rotate>{<imodesuffix>}\t%0";
10395 else
10396 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10397 }
10398 [(set_attr "type" "rotate")
10399 (set (attr "length_immediate")
10400 (if_then_else
10401 (and (match_operand 2 "const1_operand")
10402 (ior (match_test "TARGET_SHIFT1")
10403 (match_test "optimize_function_for_size_p (cfun)")))
10404 (const_string "0")
10405 (const_string "*")))
10406 (set_attr "mode" "<MODE>")])
10407
10408 (define_insn "*<rotate_insn>qi3_1_slp"
10409 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10410 (any_rotate:QI (match_dup 0)
10411 (match_operand:QI 1 "nonmemory_operand" "cI")))
10412 (clobber (reg:CC FLAGS_REG))]
10413 "(optimize_function_for_size_p (cfun)
10414 || !TARGET_PARTIAL_REG_STALL
10415 || (operands[1] == const1_rtx
10416 && TARGET_SHIFT1))"
10417 {
10418 if (operands[1] == const1_rtx
10419 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10420 return "<rotate>{b}\t%0";
10421 else
10422 return "<rotate>{b}\t{%1, %0|%0, %1}";
10423 }
10424 [(set_attr "type" "rotate1")
10425 (set (attr "length_immediate")
10426 (if_then_else
10427 (and (match_operand 1 "const1_operand")
10428 (ior (match_test "TARGET_SHIFT1")
10429 (match_test "optimize_function_for_size_p (cfun)")))
10430 (const_string "0")
10431 (const_string "*")))
10432 (set_attr "mode" "QI")])
10433
10434 (define_split
10435 [(set (match_operand:HI 0 "register_operand")
10436 (any_rotate:HI (match_dup 0) (const_int 8)))
10437 (clobber (reg:CC FLAGS_REG))]
10438 "reload_completed
10439 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10440 [(parallel [(set (strict_low_part (match_dup 0))
10441 (bswap:HI (match_dup 0)))
10442 (clobber (reg:CC FLAGS_REG))])])
10443 \f
10444 ;; Bit set / bit test instructions
10445
10446 (define_expand "extv"
10447 [(set (match_operand:SI 0 "register_operand")
10448 (sign_extract:SI (match_operand:SI 1 "register_operand")
10449 (match_operand:SI 2 "const8_operand")
10450 (match_operand:SI 3 "const8_operand")))]
10451 ""
10452 {
10453 /* Handle extractions from %ah et al. */
10454 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10455 FAIL;
10456
10457 /* From mips.md: extract_bit_field doesn't verify that our source
10458 matches the predicate, so check it again here. */
10459 if (! ext_register_operand (operands[1], VOIDmode))
10460 FAIL;
10461 })
10462
10463 (define_expand "extzv"
10464 [(set (match_operand:SI 0 "register_operand")
10465 (zero_extract:SI (match_operand 1 "ext_register_operand")
10466 (match_operand:SI 2 "const8_operand")
10467 (match_operand:SI 3 "const8_operand")))]
10468 ""
10469 {
10470 /* Handle extractions from %ah et al. */
10471 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10472 FAIL;
10473
10474 /* From mips.md: extract_bit_field doesn't verify that our source
10475 matches the predicate, so check it again here. */
10476 if (! ext_register_operand (operands[1], VOIDmode))
10477 FAIL;
10478 })
10479
10480 (define_expand "insv"
10481 [(set (zero_extract (match_operand 0 "register_operand")
10482 (match_operand 1 "const_int_operand")
10483 (match_operand 2 "const_int_operand"))
10484 (match_operand 3 "register_operand"))]
10485 ""
10486 {
10487 rtx (*gen_mov_insv_1) (rtx, rtx);
10488
10489 if (ix86_expand_pinsr (operands))
10490 DONE;
10491
10492 /* Handle insertions to %ah et al. */
10493 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10494 FAIL;
10495
10496 /* From mips.md: insert_bit_field doesn't verify that our source
10497 matches the predicate, so check it again here. */
10498 if (! ext_register_operand (operands[0], VOIDmode))
10499 FAIL;
10500
10501 gen_mov_insv_1 = (TARGET_64BIT
10502 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10503
10504 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10505 DONE;
10506 })
10507
10508 ;; %%% bts, btr, btc, bt.
10509 ;; In general these instructions are *slow* when applied to memory,
10510 ;; since they enforce atomic operation. When applied to registers,
10511 ;; it depends on the cpu implementation. They're never faster than
10512 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10513 ;; no point. But in 64-bit, we can't hold the relevant immediates
10514 ;; within the instruction itself, so operating on bits in the high
10515 ;; 32-bits of a register becomes easier.
10516 ;;
10517 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10518 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10519 ;; negdf respectively, so they can never be disabled entirely.
10520
10521 (define_insn "*btsq"
10522 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10523 (const_int 1)
10524 (match_operand:DI 1 "const_0_to_63_operand"))
10525 (const_int 1))
10526 (clobber (reg:CC FLAGS_REG))]
10527 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10528 "bts{q}\t{%1, %0|%0, %1}"
10529 [(set_attr "type" "alu1")
10530 (set_attr "prefix_0f" "1")
10531 (set_attr "mode" "DI")])
10532
10533 (define_insn "*btrq"
10534 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10535 (const_int 1)
10536 (match_operand:DI 1 "const_0_to_63_operand"))
10537 (const_int 0))
10538 (clobber (reg:CC FLAGS_REG))]
10539 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10540 "btr{q}\t{%1, %0|%0, %1}"
10541 [(set_attr "type" "alu1")
10542 (set_attr "prefix_0f" "1")
10543 (set_attr "mode" "DI")])
10544
10545 (define_insn "*btcq"
10546 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10547 (const_int 1)
10548 (match_operand:DI 1 "const_0_to_63_operand"))
10549 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10550 (clobber (reg:CC FLAGS_REG))]
10551 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10552 "btc{q}\t{%1, %0|%0, %1}"
10553 [(set_attr "type" "alu1")
10554 (set_attr "prefix_0f" "1")
10555 (set_attr "mode" "DI")])
10556
10557 ;; Allow Nocona to avoid these instructions if a register is available.
10558
10559 (define_peephole2
10560 [(match_scratch:DI 2 "r")
10561 (parallel [(set (zero_extract:DI
10562 (match_operand:DI 0 "register_operand")
10563 (const_int 1)
10564 (match_operand:DI 1 "const_0_to_63_operand"))
10565 (const_int 1))
10566 (clobber (reg:CC FLAGS_REG))])]
10567 "TARGET_64BIT && !TARGET_USE_BT"
10568 [(const_int 0)]
10569 {
10570 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10571 rtx op1;
10572
10573 if (HOST_BITS_PER_WIDE_INT >= 64)
10574 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10575 else if (i < HOST_BITS_PER_WIDE_INT)
10576 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10577 else
10578 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10579
10580 op1 = immed_double_const (lo, hi, DImode);
10581 if (i >= 31)
10582 {
10583 emit_move_insn (operands[2], op1);
10584 op1 = operands[2];
10585 }
10586
10587 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10588 DONE;
10589 })
10590
10591 (define_peephole2
10592 [(match_scratch:DI 2 "r")
10593 (parallel [(set (zero_extract:DI
10594 (match_operand:DI 0 "register_operand")
10595 (const_int 1)
10596 (match_operand:DI 1 "const_0_to_63_operand"))
10597 (const_int 0))
10598 (clobber (reg:CC FLAGS_REG))])]
10599 "TARGET_64BIT && !TARGET_USE_BT"
10600 [(const_int 0)]
10601 {
10602 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10603 rtx op1;
10604
10605 if (HOST_BITS_PER_WIDE_INT >= 64)
10606 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10607 else if (i < HOST_BITS_PER_WIDE_INT)
10608 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10609 else
10610 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10611
10612 op1 = immed_double_const (~lo, ~hi, DImode);
10613 if (i >= 32)
10614 {
10615 emit_move_insn (operands[2], op1);
10616 op1 = operands[2];
10617 }
10618
10619 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10620 DONE;
10621 })
10622
10623 (define_peephole2
10624 [(match_scratch:DI 2 "r")
10625 (parallel [(set (zero_extract:DI
10626 (match_operand:DI 0 "register_operand")
10627 (const_int 1)
10628 (match_operand:DI 1 "const_0_to_63_operand"))
10629 (not:DI (zero_extract:DI
10630 (match_dup 0) (const_int 1) (match_dup 1))))
10631 (clobber (reg:CC FLAGS_REG))])]
10632 "TARGET_64BIT && !TARGET_USE_BT"
10633 [(const_int 0)]
10634 {
10635 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10636 rtx op1;
10637
10638 if (HOST_BITS_PER_WIDE_INT >= 64)
10639 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10640 else if (i < HOST_BITS_PER_WIDE_INT)
10641 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10642 else
10643 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10644
10645 op1 = immed_double_const (lo, hi, DImode);
10646 if (i >= 31)
10647 {
10648 emit_move_insn (operands[2], op1);
10649 op1 = operands[2];
10650 }
10651
10652 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10653 DONE;
10654 })
10655
10656 (define_insn "*bt<mode>"
10657 [(set (reg:CCC FLAGS_REG)
10658 (compare:CCC
10659 (zero_extract:SWI48
10660 (match_operand:SWI48 0 "register_operand" "r")
10661 (const_int 1)
10662 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10663 (const_int 0)))]
10664 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10665 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10666 [(set_attr "type" "alu1")
10667 (set_attr "prefix_0f" "1")
10668 (set_attr "mode" "<MODE>")])
10669 \f
10670 ;; Store-flag instructions.
10671
10672 ;; For all sCOND expanders, also expand the compare or test insn that
10673 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10674
10675 (define_insn_and_split "*setcc_di_1"
10676 [(set (match_operand:DI 0 "register_operand" "=q")
10677 (match_operator:DI 1 "ix86_comparison_operator"
10678 [(reg FLAGS_REG) (const_int 0)]))]
10679 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10680 "#"
10681 "&& reload_completed"
10682 [(set (match_dup 2) (match_dup 1))
10683 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10684 {
10685 PUT_MODE (operands[1], QImode);
10686 operands[2] = gen_lowpart (QImode, operands[0]);
10687 })
10688
10689 (define_insn_and_split "*setcc_si_1_and"
10690 [(set (match_operand:SI 0 "register_operand" "=q")
10691 (match_operator:SI 1 "ix86_comparison_operator"
10692 [(reg FLAGS_REG) (const_int 0)]))
10693 (clobber (reg:CC FLAGS_REG))]
10694 "!TARGET_PARTIAL_REG_STALL
10695 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10696 "#"
10697 "&& reload_completed"
10698 [(set (match_dup 2) (match_dup 1))
10699 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10700 (clobber (reg:CC FLAGS_REG))])]
10701 {
10702 PUT_MODE (operands[1], QImode);
10703 operands[2] = gen_lowpart (QImode, operands[0]);
10704 })
10705
10706 (define_insn_and_split "*setcc_si_1_movzbl"
10707 [(set (match_operand:SI 0 "register_operand" "=q")
10708 (match_operator:SI 1 "ix86_comparison_operator"
10709 [(reg FLAGS_REG) (const_int 0)]))]
10710 "!TARGET_PARTIAL_REG_STALL
10711 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10712 "#"
10713 "&& reload_completed"
10714 [(set (match_dup 2) (match_dup 1))
10715 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10716 {
10717 PUT_MODE (operands[1], QImode);
10718 operands[2] = gen_lowpart (QImode, operands[0]);
10719 })
10720
10721 (define_insn "*setcc_qi"
10722 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10723 (match_operator:QI 1 "ix86_comparison_operator"
10724 [(reg FLAGS_REG) (const_int 0)]))]
10725 ""
10726 "set%C1\t%0"
10727 [(set_attr "type" "setcc")
10728 (set_attr "mode" "QI")])
10729
10730 (define_insn "*setcc_qi_slp"
10731 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10732 (match_operator:QI 1 "ix86_comparison_operator"
10733 [(reg FLAGS_REG) (const_int 0)]))]
10734 ""
10735 "set%C1\t%0"
10736 [(set_attr "type" "setcc")
10737 (set_attr "mode" "QI")])
10738
10739 ;; In general it is not safe to assume too much about CCmode registers,
10740 ;; so simplify-rtx stops when it sees a second one. Under certain
10741 ;; conditions this is safe on x86, so help combine not create
10742 ;;
10743 ;; seta %al
10744 ;; testb %al, %al
10745 ;; sete %al
10746
10747 (define_split
10748 [(set (match_operand:QI 0 "nonimmediate_operand")
10749 (ne:QI (match_operator 1 "ix86_comparison_operator"
10750 [(reg FLAGS_REG) (const_int 0)])
10751 (const_int 0)))]
10752 ""
10753 [(set (match_dup 0) (match_dup 1))]
10754 "PUT_MODE (operands[1], QImode);")
10755
10756 (define_split
10757 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10758 (ne:QI (match_operator 1 "ix86_comparison_operator"
10759 [(reg FLAGS_REG) (const_int 0)])
10760 (const_int 0)))]
10761 ""
10762 [(set (match_dup 0) (match_dup 1))]
10763 "PUT_MODE (operands[1], QImode);")
10764
10765 (define_split
10766 [(set (match_operand:QI 0 "nonimmediate_operand")
10767 (eq:QI (match_operator 1 "ix86_comparison_operator"
10768 [(reg FLAGS_REG) (const_int 0)])
10769 (const_int 0)))]
10770 ""
10771 [(set (match_dup 0) (match_dup 1))]
10772 {
10773 rtx new_op1 = copy_rtx (operands[1]);
10774 operands[1] = new_op1;
10775 PUT_MODE (new_op1, QImode);
10776 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10777 GET_MODE (XEXP (new_op1, 0))));
10778
10779 /* Make sure that (a) the CCmode we have for the flags is strong
10780 enough for the reversed compare or (b) we have a valid FP compare. */
10781 if (! ix86_comparison_operator (new_op1, VOIDmode))
10782 FAIL;
10783 })
10784
10785 (define_split
10786 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10787 (eq:QI (match_operator 1 "ix86_comparison_operator"
10788 [(reg FLAGS_REG) (const_int 0)])
10789 (const_int 0)))]
10790 ""
10791 [(set (match_dup 0) (match_dup 1))]
10792 {
10793 rtx new_op1 = copy_rtx (operands[1]);
10794 operands[1] = new_op1;
10795 PUT_MODE (new_op1, QImode);
10796 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10797 GET_MODE (XEXP (new_op1, 0))));
10798
10799 /* Make sure that (a) the CCmode we have for the flags is strong
10800 enough for the reversed compare or (b) we have a valid FP compare. */
10801 if (! ix86_comparison_operator (new_op1, VOIDmode))
10802 FAIL;
10803 })
10804
10805 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10806 ;; subsequent logical operations are used to imitate conditional moves.
10807 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10808 ;; it directly.
10809
10810 (define_insn "setcc_<mode>_sse"
10811 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10812 (match_operator:MODEF 3 "sse_comparison_operator"
10813 [(match_operand:MODEF 1 "register_operand" "0,x")
10814 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10815 "SSE_FLOAT_MODE_P (<MODE>mode)"
10816 "@
10817 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10818 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10819 [(set_attr "isa" "noavx,avx")
10820 (set_attr "type" "ssecmp")
10821 (set_attr "length_immediate" "1")
10822 (set_attr "prefix" "orig,vex")
10823 (set_attr "mode" "<MODE>")])
10824 \f
10825 ;; Basic conditional jump instructions.
10826 ;; We ignore the overflow flag for signed branch instructions.
10827
10828 (define_insn "*jcc_1"
10829 [(set (pc)
10830 (if_then_else (match_operator 1 "ix86_comparison_operator"
10831 [(reg FLAGS_REG) (const_int 0)])
10832 (label_ref (match_operand 0))
10833 (pc)))]
10834 ""
10835 "%+j%C1\t%l0"
10836 [(set_attr "type" "ibr")
10837 (set_attr "modrm" "0")
10838 (set (attr "length")
10839 (if_then_else (and (ge (minus (match_dup 0) (pc))
10840 (const_int -126))
10841 (lt (minus (match_dup 0) (pc))
10842 (const_int 128)))
10843 (const_int 2)
10844 (const_int 6)))])
10845
10846 (define_insn "*jcc_2"
10847 [(set (pc)
10848 (if_then_else (match_operator 1 "ix86_comparison_operator"
10849 [(reg FLAGS_REG) (const_int 0)])
10850 (pc)
10851 (label_ref (match_operand 0))))]
10852 ""
10853 "%+j%c1\t%l0"
10854 [(set_attr "type" "ibr")
10855 (set_attr "modrm" "0")
10856 (set (attr "length")
10857 (if_then_else (and (ge (minus (match_dup 0) (pc))
10858 (const_int -126))
10859 (lt (minus (match_dup 0) (pc))
10860 (const_int 128)))
10861 (const_int 2)
10862 (const_int 6)))])
10863
10864 ;; In general it is not safe to assume too much about CCmode registers,
10865 ;; so simplify-rtx stops when it sees a second one. Under certain
10866 ;; conditions this is safe on x86, so help combine not create
10867 ;;
10868 ;; seta %al
10869 ;; testb %al, %al
10870 ;; je Lfoo
10871
10872 (define_split
10873 [(set (pc)
10874 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10875 [(reg FLAGS_REG) (const_int 0)])
10876 (const_int 0))
10877 (label_ref (match_operand 1))
10878 (pc)))]
10879 ""
10880 [(set (pc)
10881 (if_then_else (match_dup 0)
10882 (label_ref (match_dup 1))
10883 (pc)))]
10884 "PUT_MODE (operands[0], VOIDmode);")
10885
10886 (define_split
10887 [(set (pc)
10888 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10889 [(reg FLAGS_REG) (const_int 0)])
10890 (const_int 0))
10891 (label_ref (match_operand 1))
10892 (pc)))]
10893 ""
10894 [(set (pc)
10895 (if_then_else (match_dup 0)
10896 (label_ref (match_dup 1))
10897 (pc)))]
10898 {
10899 rtx new_op0 = copy_rtx (operands[0]);
10900 operands[0] = new_op0;
10901 PUT_MODE (new_op0, VOIDmode);
10902 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10903 GET_MODE (XEXP (new_op0, 0))));
10904
10905 /* Make sure that (a) the CCmode we have for the flags is strong
10906 enough for the reversed compare or (b) we have a valid FP compare. */
10907 if (! ix86_comparison_operator (new_op0, VOIDmode))
10908 FAIL;
10909 })
10910
10911 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10912 ;; pass generates from shift insn with QImode operand. Actually, the mode
10913 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10914 ;; appropriate modulo of the bit offset value.
10915
10916 (define_insn_and_split "*jcc_bt<mode>"
10917 [(set (pc)
10918 (if_then_else (match_operator 0 "bt_comparison_operator"
10919 [(zero_extract:SWI48
10920 (match_operand:SWI48 1 "register_operand" "r")
10921 (const_int 1)
10922 (zero_extend:SI
10923 (match_operand:QI 2 "register_operand" "r")))
10924 (const_int 0)])
10925 (label_ref (match_operand 3))
10926 (pc)))
10927 (clobber (reg:CC FLAGS_REG))]
10928 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10929 "#"
10930 "&& 1"
10931 [(set (reg:CCC FLAGS_REG)
10932 (compare:CCC
10933 (zero_extract:SWI48
10934 (match_dup 1)
10935 (const_int 1)
10936 (match_dup 2))
10937 (const_int 0)))
10938 (set (pc)
10939 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10940 (label_ref (match_dup 3))
10941 (pc)))]
10942 {
10943 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10944
10945 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10946 })
10947
10948 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10949 ;; also for DImode, this is what combine produces.
10950 (define_insn_and_split "*jcc_bt<mode>_mask"
10951 [(set (pc)
10952 (if_then_else (match_operator 0 "bt_comparison_operator"
10953 [(zero_extract:SWI48
10954 (match_operand:SWI48 1 "register_operand" "r")
10955 (const_int 1)
10956 (and:SI
10957 (match_operand:SI 2 "register_operand" "r")
10958 (match_operand:SI 3 "const_int_operand" "n")))])
10959 (label_ref (match_operand 4))
10960 (pc)))
10961 (clobber (reg:CC FLAGS_REG))]
10962 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10963 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10964 == GET_MODE_BITSIZE (<MODE>mode)-1"
10965 "#"
10966 "&& 1"
10967 [(set (reg:CCC FLAGS_REG)
10968 (compare:CCC
10969 (zero_extract:SWI48
10970 (match_dup 1)
10971 (const_int 1)
10972 (match_dup 2))
10973 (const_int 0)))
10974 (set (pc)
10975 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10976 (label_ref (match_dup 4))
10977 (pc)))]
10978 {
10979 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10980
10981 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10982 })
10983
10984 (define_insn_and_split "*jcc_btsi_1"
10985 [(set (pc)
10986 (if_then_else (match_operator 0 "bt_comparison_operator"
10987 [(and:SI
10988 (lshiftrt:SI
10989 (match_operand:SI 1 "register_operand" "r")
10990 (match_operand:QI 2 "register_operand" "r"))
10991 (const_int 1))
10992 (const_int 0)])
10993 (label_ref (match_operand 3))
10994 (pc)))
10995 (clobber (reg:CC FLAGS_REG))]
10996 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10997 "#"
10998 "&& 1"
10999 [(set (reg:CCC FLAGS_REG)
11000 (compare:CCC
11001 (zero_extract:SI
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 3))
11009 (pc)))]
11010 {
11011 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11012
11013 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11014 })
11015
11016 ;; avoid useless masking of bit offset operand
11017 (define_insn_and_split "*jcc_btsi_mask_1"
11018 [(set (pc)
11019 (if_then_else
11020 (match_operator 0 "bt_comparison_operator"
11021 [(and:SI
11022 (lshiftrt:SI
11023 (match_operand:SI 1 "register_operand" "r")
11024 (subreg:QI
11025 (and:SI
11026 (match_operand:SI 2 "register_operand" "r")
11027 (match_operand:SI 3 "const_int_operand" "n")) 0))
11028 (const_int 1))
11029 (const_int 0)])
11030 (label_ref (match_operand 4))
11031 (pc)))
11032 (clobber (reg:CC FLAGS_REG))]
11033 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11034 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11035 "#"
11036 "&& 1"
11037 [(set (reg:CCC FLAGS_REG)
11038 (compare:CCC
11039 (zero_extract:SI
11040 (match_dup 1)
11041 (const_int 1)
11042 (match_dup 2))
11043 (const_int 0)))
11044 (set (pc)
11045 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11046 (label_ref (match_dup 4))
11047 (pc)))]
11048 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11049
11050 ;; Define combination compare-and-branch fp compare instructions to help
11051 ;; combine.
11052
11053 (define_insn "*fp_jcc_1_387"
11054 [(set (pc)
11055 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11056 [(match_operand 1 "register_operand" "f")
11057 (match_operand 2 "nonimmediate_operand" "fm")])
11058 (label_ref (match_operand 3))
11059 (pc)))
11060 (clobber (reg:CCFP FPSR_REG))
11061 (clobber (reg:CCFP FLAGS_REG))
11062 (clobber (match_scratch:HI 4 "=a"))]
11063 "TARGET_80387
11064 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11065 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11066 && SELECT_CC_MODE (GET_CODE (operands[0]),
11067 operands[1], operands[2]) == CCFPmode
11068 && !TARGET_CMOVE"
11069 "#")
11070
11071 (define_insn "*fp_jcc_1r_387"
11072 [(set (pc)
11073 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11074 [(match_operand 1 "register_operand" "f")
11075 (match_operand 2 "nonimmediate_operand" "fm")])
11076 (pc)
11077 (label_ref (match_operand 3))))
11078 (clobber (reg:CCFP FPSR_REG))
11079 (clobber (reg:CCFP FLAGS_REG))
11080 (clobber (match_scratch:HI 4 "=a"))]
11081 "TARGET_80387
11082 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11083 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11084 && SELECT_CC_MODE (GET_CODE (operands[0]),
11085 operands[1], operands[2]) == CCFPmode
11086 && !TARGET_CMOVE"
11087 "#")
11088
11089 (define_insn "*fp_jcc_2_387"
11090 [(set (pc)
11091 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11092 [(match_operand 1 "register_operand" "f")
11093 (match_operand 2 "register_operand" "f")])
11094 (label_ref (match_operand 3))
11095 (pc)))
11096 (clobber (reg:CCFP FPSR_REG))
11097 (clobber (reg:CCFP FLAGS_REG))
11098 (clobber (match_scratch:HI 4 "=a"))]
11099 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11100 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11101 && !TARGET_CMOVE"
11102 "#")
11103
11104 (define_insn "*fp_jcc_2r_387"
11105 [(set (pc)
11106 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11107 [(match_operand 1 "register_operand" "f")
11108 (match_operand 2 "register_operand" "f")])
11109 (pc)
11110 (label_ref (match_operand 3))))
11111 (clobber (reg:CCFP FPSR_REG))
11112 (clobber (reg:CCFP FLAGS_REG))
11113 (clobber (match_scratch:HI 4 "=a"))]
11114 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11115 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11116 && !TARGET_CMOVE"
11117 "#")
11118
11119 (define_insn "*fp_jcc_3_387"
11120 [(set (pc)
11121 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11122 [(match_operand 1 "register_operand" "f")
11123 (match_operand 2 "const0_operand")])
11124 (label_ref (match_operand 3))
11125 (pc)))
11126 (clobber (reg:CCFP FPSR_REG))
11127 (clobber (reg:CCFP FLAGS_REG))
11128 (clobber (match_scratch:HI 4 "=a"))]
11129 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11130 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11131 && SELECT_CC_MODE (GET_CODE (operands[0]),
11132 operands[1], operands[2]) == CCFPmode
11133 && !TARGET_CMOVE"
11134 "#")
11135
11136 (define_split
11137 [(set (pc)
11138 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11139 [(match_operand 1 "register_operand")
11140 (match_operand 2 "nonimmediate_operand")])
11141 (match_operand 3)
11142 (match_operand 4)))
11143 (clobber (reg:CCFP FPSR_REG))
11144 (clobber (reg:CCFP FLAGS_REG))]
11145 "reload_completed"
11146 [(const_int 0)]
11147 {
11148 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11149 operands[3], operands[4], NULL_RTX, NULL_RTX);
11150 DONE;
11151 })
11152
11153 (define_split
11154 [(set (pc)
11155 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11156 [(match_operand 1 "register_operand")
11157 (match_operand 2 "general_operand")])
11158 (match_operand 3)
11159 (match_operand 4)))
11160 (clobber (reg:CCFP FPSR_REG))
11161 (clobber (reg:CCFP FLAGS_REG))
11162 (clobber (match_scratch:HI 5 "=a"))]
11163 "reload_completed"
11164 [(const_int 0)]
11165 {
11166 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11167 operands[3], operands[4], operands[5], NULL_RTX);
11168 DONE;
11169 })
11170
11171 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11172 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11173 ;; with a precedence over other operators and is always put in the first
11174 ;; place. Swap condition and operands to match ficom instruction.
11175
11176 (define_insn "*fp_jcc_4_<mode>_387"
11177 [(set (pc)
11178 (if_then_else
11179 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11180 [(match_operator 1 "float_operator"
11181 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11182 (match_operand 3 "register_operand" "f,f")])
11183 (label_ref (match_operand 4))
11184 (pc)))
11185 (clobber (reg:CCFP FPSR_REG))
11186 (clobber (reg:CCFP FLAGS_REG))
11187 (clobber (match_scratch:HI 5 "=a,a"))]
11188 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11189 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11190 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11191 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11192 && !TARGET_CMOVE"
11193 "#")
11194
11195 (define_split
11196 [(set (pc)
11197 (if_then_else
11198 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11199 [(match_operator 1 "float_operator"
11200 [(match_operand:SWI24 2 "memory_operand")])
11201 (match_operand 3 "register_operand")])
11202 (match_operand 4)
11203 (match_operand 5)))
11204 (clobber (reg:CCFP FPSR_REG))
11205 (clobber (reg:CCFP FLAGS_REG))
11206 (clobber (match_scratch:HI 6 "=a"))]
11207 "reload_completed"
11208 [(const_int 0)]
11209 {
11210 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11211
11212 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11213 operands[3], operands[7],
11214 operands[4], operands[5], operands[6], NULL_RTX);
11215 DONE;
11216 })
11217
11218 ;; %%% Kill this when reload knows how to do it.
11219 (define_split
11220 [(set (pc)
11221 (if_then_else
11222 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11223 [(match_operator 1 "float_operator"
11224 [(match_operand:SWI24 2 "register_operand")])
11225 (match_operand 3 "register_operand")])
11226 (match_operand 4)
11227 (match_operand 5)))
11228 (clobber (reg:CCFP FPSR_REG))
11229 (clobber (reg:CCFP FLAGS_REG))
11230 (clobber (match_scratch:HI 6 "=a"))]
11231 "reload_completed"
11232 [(const_int 0)]
11233 {
11234 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11235 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11236
11237 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11238 operands[3], operands[7],
11239 operands[4], operands[5], operands[6], operands[2]);
11240 DONE;
11241 })
11242 \f
11243 ;; Unconditional and other jump instructions
11244
11245 (define_insn "jump"
11246 [(set (pc)
11247 (label_ref (match_operand 0)))]
11248 ""
11249 "jmp\t%l0"
11250 [(set_attr "type" "ibr")
11251 (set (attr "length")
11252 (if_then_else (and (ge (minus (match_dup 0) (pc))
11253 (const_int -126))
11254 (lt (minus (match_dup 0) (pc))
11255 (const_int 128)))
11256 (const_int 2)
11257 (const_int 5)))
11258 (set_attr "modrm" "0")])
11259
11260 (define_expand "indirect_jump"
11261 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11262 ""
11263 {
11264 if (TARGET_X32)
11265 operands[0] = convert_memory_address (word_mode, operands[0]);
11266 })
11267
11268 (define_insn "*indirect_jump"
11269 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11270 ""
11271 "jmp\t%A0"
11272 [(set_attr "type" "ibr")
11273 (set_attr "length_immediate" "0")])
11274
11275 (define_expand "tablejump"
11276 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11277 (use (label_ref (match_operand 1)))])]
11278 ""
11279 {
11280 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11281 relative. Convert the relative address to an absolute address. */
11282 if (flag_pic)
11283 {
11284 rtx op0, op1;
11285 enum rtx_code code;
11286
11287 /* We can't use @GOTOFF for text labels on VxWorks;
11288 see gotoff_operand. */
11289 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11290 {
11291 code = PLUS;
11292 op0 = operands[0];
11293 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11294 }
11295 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11296 {
11297 code = PLUS;
11298 op0 = operands[0];
11299 op1 = pic_offset_table_rtx;
11300 }
11301 else
11302 {
11303 code = MINUS;
11304 op0 = pic_offset_table_rtx;
11305 op1 = operands[0];
11306 }
11307
11308 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11309 OPTAB_DIRECT);
11310 }
11311
11312 if (TARGET_X32)
11313 operands[0] = convert_memory_address (word_mode, operands[0]);
11314 })
11315
11316 (define_insn "*tablejump_1"
11317 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11318 (use (label_ref (match_operand 1)))]
11319 ""
11320 "jmp\t%A0"
11321 [(set_attr "type" "ibr")
11322 (set_attr "length_immediate" "0")])
11323 \f
11324 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11325
11326 (define_peephole2
11327 [(set (reg FLAGS_REG) (match_operand 0))
11328 (set (match_operand:QI 1 "register_operand")
11329 (match_operator:QI 2 "ix86_comparison_operator"
11330 [(reg FLAGS_REG) (const_int 0)]))
11331 (set (match_operand 3 "q_regs_operand")
11332 (zero_extend (match_dup 1)))]
11333 "(peep2_reg_dead_p (3, operands[1])
11334 || operands_match_p (operands[1], operands[3]))
11335 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11336 [(set (match_dup 4) (match_dup 0))
11337 (set (strict_low_part (match_dup 5))
11338 (match_dup 2))]
11339 {
11340 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11341 operands[5] = gen_lowpart (QImode, operands[3]);
11342 ix86_expand_clear (operands[3]);
11343 })
11344
11345 (define_peephole2
11346 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11347 (match_operand 4)])
11348 (set (match_operand:QI 1 "register_operand")
11349 (match_operator:QI 2 "ix86_comparison_operator"
11350 [(reg FLAGS_REG) (const_int 0)]))
11351 (set (match_operand 3 "q_regs_operand")
11352 (zero_extend (match_dup 1)))]
11353 "(peep2_reg_dead_p (3, operands[1])
11354 || operands_match_p (operands[1], operands[3]))
11355 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11356 [(parallel [(set (match_dup 5) (match_dup 0))
11357 (match_dup 4)])
11358 (set (strict_low_part (match_dup 6))
11359 (match_dup 2))]
11360 {
11361 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11362 operands[6] = gen_lowpart (QImode, operands[3]);
11363 ix86_expand_clear (operands[3]);
11364 })
11365
11366 ;; Similar, but match zero extend with andsi3.
11367
11368 (define_peephole2
11369 [(set (reg FLAGS_REG) (match_operand 0))
11370 (set (match_operand:QI 1 "register_operand")
11371 (match_operator:QI 2 "ix86_comparison_operator"
11372 [(reg FLAGS_REG) (const_int 0)]))
11373 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11374 (and:SI (match_dup 3) (const_int 255)))
11375 (clobber (reg:CC FLAGS_REG))])]
11376 "REGNO (operands[1]) == REGNO (operands[3])
11377 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11378 [(set (match_dup 4) (match_dup 0))
11379 (set (strict_low_part (match_dup 5))
11380 (match_dup 2))]
11381 {
11382 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11383 operands[5] = gen_lowpart (QImode, operands[3]);
11384 ix86_expand_clear (operands[3]);
11385 })
11386
11387 (define_peephole2
11388 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11389 (match_operand 4)])
11390 (set (match_operand:QI 1 "register_operand")
11391 (match_operator:QI 2 "ix86_comparison_operator"
11392 [(reg FLAGS_REG) (const_int 0)]))
11393 (parallel [(set (match_operand 3 "q_regs_operand")
11394 (zero_extend (match_dup 1)))
11395 (clobber (reg:CC FLAGS_REG))])]
11396 "(peep2_reg_dead_p (3, operands[1])
11397 || operands_match_p (operands[1], operands[3]))
11398 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11399 [(parallel [(set (match_dup 5) (match_dup 0))
11400 (match_dup 4)])
11401 (set (strict_low_part (match_dup 6))
11402 (match_dup 2))]
11403 {
11404 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11405 operands[6] = gen_lowpart (QImode, operands[3]);
11406 ix86_expand_clear (operands[3]);
11407 })
11408 \f
11409 ;; Call instructions.
11410
11411 ;; The predicates normally associated with named expanders are not properly
11412 ;; checked for calls. This is a bug in the generic code, but it isn't that
11413 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11414
11415 ;; P6 processors will jump to the address after the decrement when %esp
11416 ;; is used as a call operand, so they will execute return address as a code.
11417 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11418
11419 ;; Register constraint for call instruction.
11420 (define_mode_attr c [(SI "l") (DI "r")])
11421
11422 ;; Call subroutine returning no value.
11423
11424 (define_expand "call"
11425 [(call (match_operand:QI 0)
11426 (match_operand 1))
11427 (use (match_operand 2))]
11428 ""
11429 {
11430 ix86_expand_call (NULL, operands[0], operands[1],
11431 operands[2], NULL, false);
11432 DONE;
11433 })
11434
11435 (define_expand "sibcall"
11436 [(call (match_operand:QI 0)
11437 (match_operand 1))
11438 (use (match_operand 2))]
11439 ""
11440 {
11441 ix86_expand_call (NULL, operands[0], operands[1],
11442 operands[2], NULL, true);
11443 DONE;
11444 })
11445
11446 (define_insn_and_split "*call_vzeroupper"
11447 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11448 (match_operand 1))
11449 (unspec [(match_operand 2 "const_int_operand")]
11450 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11451 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11452 "#"
11453 "&& reload_completed"
11454 [(const_int 0)]
11455 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11456 [(set_attr "type" "call")])
11457
11458 (define_insn "*call"
11459 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11460 (match_operand 1))]
11461 "!SIBLING_CALL_P (insn)"
11462 "* return ix86_output_call_insn (insn, operands[0]);"
11463 [(set_attr "type" "call")])
11464
11465 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11466 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11467 (match_operand 1))
11468 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11469 (clobber (reg:TI XMM6_REG))
11470 (clobber (reg:TI XMM7_REG))
11471 (clobber (reg:TI XMM8_REG))
11472 (clobber (reg:TI XMM9_REG))
11473 (clobber (reg:TI XMM10_REG))
11474 (clobber (reg:TI XMM11_REG))
11475 (clobber (reg:TI XMM12_REG))
11476 (clobber (reg:TI XMM13_REG))
11477 (clobber (reg:TI XMM14_REG))
11478 (clobber (reg:TI XMM15_REG))
11479 (clobber (reg:DI SI_REG))
11480 (clobber (reg:DI DI_REG))
11481 (unspec [(match_operand 2 "const_int_operand")]
11482 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11483 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11484 "#"
11485 "&& reload_completed"
11486 [(const_int 0)]
11487 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11488 [(set_attr "type" "call")])
11489
11490 (define_insn "*call_rex64_ms_sysv"
11491 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11492 (match_operand 1))
11493 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11494 (clobber (reg:TI XMM6_REG))
11495 (clobber (reg:TI XMM7_REG))
11496 (clobber (reg:TI XMM8_REG))
11497 (clobber (reg:TI XMM9_REG))
11498 (clobber (reg:TI XMM10_REG))
11499 (clobber (reg:TI XMM11_REG))
11500 (clobber (reg:TI XMM12_REG))
11501 (clobber (reg:TI XMM13_REG))
11502 (clobber (reg:TI XMM14_REG))
11503 (clobber (reg:TI XMM15_REG))
11504 (clobber (reg:DI SI_REG))
11505 (clobber (reg:DI DI_REG))]
11506 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11507 "* return ix86_output_call_insn (insn, operands[0]);"
11508 [(set_attr "type" "call")])
11509
11510 (define_insn_and_split "*sibcall_vzeroupper"
11511 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11512 (match_operand 1))
11513 (unspec [(match_operand 2 "const_int_operand")]
11514 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11515 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11516 "#"
11517 "&& reload_completed"
11518 [(const_int 0)]
11519 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11520 [(set_attr "type" "call")])
11521
11522 (define_insn "*sibcall"
11523 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11524 (match_operand 1))]
11525 "SIBLING_CALL_P (insn)"
11526 "* return ix86_output_call_insn (insn, operands[0]);"
11527 [(set_attr "type" "call")])
11528
11529 (define_expand "call_pop"
11530 [(parallel [(call (match_operand:QI 0)
11531 (match_operand:SI 1))
11532 (set (reg:SI SP_REG)
11533 (plus:SI (reg:SI SP_REG)
11534 (match_operand:SI 3)))])]
11535 "!TARGET_64BIT"
11536 {
11537 ix86_expand_call (NULL, operands[0], operands[1],
11538 operands[2], operands[3], false);
11539 DONE;
11540 })
11541
11542 (define_insn_and_split "*call_pop_vzeroupper"
11543 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11544 (match_operand 1))
11545 (set (reg:SI SP_REG)
11546 (plus:SI (reg:SI SP_REG)
11547 (match_operand:SI 2 "immediate_operand" "i")))
11548 (unspec [(match_operand 3 "const_int_operand")]
11549 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11550 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11551 "#"
11552 "&& reload_completed"
11553 [(const_int 0)]
11554 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11555 [(set_attr "type" "call")])
11556
11557 (define_insn "*call_pop"
11558 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11559 (match_operand 1))
11560 (set (reg:SI SP_REG)
11561 (plus:SI (reg:SI SP_REG)
11562 (match_operand:SI 2 "immediate_operand" "i")))]
11563 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11564 "* return ix86_output_call_insn (insn, operands[0]);"
11565 [(set_attr "type" "call")])
11566
11567 (define_insn_and_split "*sibcall_pop_vzeroupper"
11568 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11569 (match_operand 1))
11570 (set (reg:SI SP_REG)
11571 (plus:SI (reg:SI SP_REG)
11572 (match_operand:SI 2 "immediate_operand" "i")))
11573 (unspec [(match_operand 3 "const_int_operand")]
11574 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11575 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11576 "#"
11577 "&& reload_completed"
11578 [(const_int 0)]
11579 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11580 [(set_attr "type" "call")])
11581
11582 (define_insn "*sibcall_pop"
11583 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11584 (match_operand 1))
11585 (set (reg:SI SP_REG)
11586 (plus:SI (reg:SI SP_REG)
11587 (match_operand:SI 2 "immediate_operand" "i")))]
11588 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11589 "* return ix86_output_call_insn (insn, operands[0]);"
11590 [(set_attr "type" "call")])
11591
11592 ;; Call subroutine, returning value in operand 0
11593
11594 (define_expand "call_value"
11595 [(set (match_operand 0)
11596 (call (match_operand:QI 1)
11597 (match_operand 2)))
11598 (use (match_operand 3))]
11599 ""
11600 {
11601 ix86_expand_call (operands[0], operands[1], operands[2],
11602 operands[3], NULL, false);
11603 DONE;
11604 })
11605
11606 (define_expand "sibcall_value"
11607 [(set (match_operand 0)
11608 (call (match_operand:QI 1)
11609 (match_operand 2)))
11610 (use (match_operand 3))]
11611 ""
11612 {
11613 ix86_expand_call (operands[0], operands[1], operands[2],
11614 operands[3], NULL, true);
11615 DONE;
11616 })
11617
11618 (define_insn_and_split "*call_value_vzeroupper"
11619 [(set (match_operand 0)
11620 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11621 (match_operand 2)))
11622 (unspec [(match_operand 3 "const_int_operand")]
11623 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11624 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11625 "#"
11626 "&& reload_completed"
11627 [(const_int 0)]
11628 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11629 [(set_attr "type" "callv")])
11630
11631 (define_insn "*call_value"
11632 [(set (match_operand 0)
11633 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11634 (match_operand 2)))]
11635 "!SIBLING_CALL_P (insn)"
11636 "* return ix86_output_call_insn (insn, operands[1]);"
11637 [(set_attr "type" "callv")])
11638
11639 (define_insn_and_split "*sibcall_value_vzeroupper"
11640 [(set (match_operand 0)
11641 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11642 (match_operand 2)))
11643 (unspec [(match_operand 3 "const_int_operand")]
11644 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11645 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11646 "#"
11647 "&& reload_completed"
11648 [(const_int 0)]
11649 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11650 [(set_attr "type" "callv")])
11651
11652 (define_insn "*sibcall_value"
11653 [(set (match_operand 0)
11654 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11655 (match_operand 2)))]
11656 "SIBLING_CALL_P (insn)"
11657 "* return ix86_output_call_insn (insn, operands[1]);"
11658 [(set_attr "type" "callv")])
11659
11660 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11661 [(set (match_operand 0)
11662 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11663 (match_operand 2)))
11664 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11665 (clobber (reg:TI XMM6_REG))
11666 (clobber (reg:TI XMM7_REG))
11667 (clobber (reg:TI XMM8_REG))
11668 (clobber (reg:TI XMM9_REG))
11669 (clobber (reg:TI XMM10_REG))
11670 (clobber (reg:TI XMM11_REG))
11671 (clobber (reg:TI XMM12_REG))
11672 (clobber (reg:TI XMM13_REG))
11673 (clobber (reg:TI XMM14_REG))
11674 (clobber (reg:TI XMM15_REG))
11675 (clobber (reg:DI SI_REG))
11676 (clobber (reg:DI DI_REG))
11677 (unspec [(match_operand 3 "const_int_operand")]
11678 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11679 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11680 "#"
11681 "&& reload_completed"
11682 [(const_int 0)]
11683 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11684 [(set_attr "type" "callv")])
11685
11686 (define_insn "*call_value_rex64_ms_sysv"
11687 [(set (match_operand 0)
11688 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11689 (match_operand 2)))
11690 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11691 (clobber (reg:TI XMM6_REG))
11692 (clobber (reg:TI XMM7_REG))
11693 (clobber (reg:TI XMM8_REG))
11694 (clobber (reg:TI XMM9_REG))
11695 (clobber (reg:TI XMM10_REG))
11696 (clobber (reg:TI XMM11_REG))
11697 (clobber (reg:TI XMM12_REG))
11698 (clobber (reg:TI XMM13_REG))
11699 (clobber (reg:TI XMM14_REG))
11700 (clobber (reg:TI XMM15_REG))
11701 (clobber (reg:DI SI_REG))
11702 (clobber (reg:DI DI_REG))]
11703 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11704 "* return ix86_output_call_insn (insn, operands[1]);"
11705 [(set_attr "type" "callv")])
11706
11707 (define_expand "call_value_pop"
11708 [(parallel [(set (match_operand 0)
11709 (call (match_operand:QI 1)
11710 (match_operand:SI 2)))
11711 (set (reg:SI SP_REG)
11712 (plus:SI (reg:SI SP_REG)
11713 (match_operand:SI 4)))])]
11714 "!TARGET_64BIT"
11715 {
11716 ix86_expand_call (operands[0], operands[1], operands[2],
11717 operands[3], operands[4], false);
11718 DONE;
11719 })
11720
11721 (define_insn_and_split "*call_value_pop_vzeroupper"
11722 [(set (match_operand 0)
11723 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11724 (match_operand 2)))
11725 (set (reg:SI SP_REG)
11726 (plus:SI (reg:SI SP_REG)
11727 (match_operand:SI 3 "immediate_operand" "i")))
11728 (unspec [(match_operand 4 "const_int_operand")]
11729 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11730 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11731 "#"
11732 "&& reload_completed"
11733 [(const_int 0)]
11734 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11735 [(set_attr "type" "callv")])
11736
11737 (define_insn "*call_value_pop"
11738 [(set (match_operand 0)
11739 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11740 (match_operand 2)))
11741 (set (reg:SI SP_REG)
11742 (plus:SI (reg:SI SP_REG)
11743 (match_operand:SI 3 "immediate_operand" "i")))]
11744 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11745 "* return ix86_output_call_insn (insn, operands[1]);"
11746 [(set_attr "type" "callv")])
11747
11748 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11749 [(set (match_operand 0)
11750 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11751 (match_operand 2)))
11752 (set (reg:SI SP_REG)
11753 (plus:SI (reg:SI SP_REG)
11754 (match_operand:SI 3 "immediate_operand" "i")))
11755 (unspec [(match_operand 4 "const_int_operand")]
11756 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11757 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11758 "#"
11759 "&& reload_completed"
11760 [(const_int 0)]
11761 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11762 [(set_attr "type" "callv")])
11763
11764 (define_insn "*sibcall_value_pop"
11765 [(set (match_operand 0)
11766 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11767 (match_operand 2)))
11768 (set (reg:SI SP_REG)
11769 (plus:SI (reg:SI SP_REG)
11770 (match_operand:SI 3 "immediate_operand" "i")))]
11771 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11772 "* return ix86_output_call_insn (insn, operands[1]);"
11773 [(set_attr "type" "callv")])
11774
11775 ;; Call subroutine returning any type.
11776
11777 (define_expand "untyped_call"
11778 [(parallel [(call (match_operand 0)
11779 (const_int 0))
11780 (match_operand 1)
11781 (match_operand 2)])]
11782 ""
11783 {
11784 int i;
11785
11786 /* In order to give reg-stack an easier job in validating two
11787 coprocessor registers as containing a possible return value,
11788 simply pretend the untyped call returns a complex long double
11789 value.
11790
11791 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11792 and should have the default ABI. */
11793
11794 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11795 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11796 operands[0], const0_rtx,
11797 GEN_INT ((TARGET_64BIT
11798 ? (ix86_abi == SYSV_ABI
11799 ? X86_64_SSE_REGPARM_MAX
11800 : X86_64_MS_SSE_REGPARM_MAX)
11801 : X86_32_SSE_REGPARM_MAX)
11802 - 1),
11803 NULL, false);
11804
11805 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11806 {
11807 rtx set = XVECEXP (operands[2], 0, i);
11808 emit_move_insn (SET_DEST (set), SET_SRC (set));
11809 }
11810
11811 /* The optimizer does not know that the call sets the function value
11812 registers we stored in the result block. We avoid problems by
11813 claiming that all hard registers are used and clobbered at this
11814 point. */
11815 emit_insn (gen_blockage ());
11816
11817 DONE;
11818 })
11819 \f
11820 ;; Prologue and epilogue instructions
11821
11822 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11823 ;; all of memory. This blocks insns from being moved across this point.
11824
11825 (define_insn "blockage"
11826 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11827 ""
11828 ""
11829 [(set_attr "length" "0")])
11830
11831 ;; Do not schedule instructions accessing memory across this point.
11832
11833 (define_expand "memory_blockage"
11834 [(set (match_dup 0)
11835 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11836 ""
11837 {
11838 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11839 MEM_VOLATILE_P (operands[0]) = 1;
11840 })
11841
11842 (define_insn "*memory_blockage"
11843 [(set (match_operand:BLK 0)
11844 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11845 ""
11846 ""
11847 [(set_attr "length" "0")])
11848
11849 ;; As USE insns aren't meaningful after reload, this is used instead
11850 ;; to prevent deleting instructions setting registers for PIC code
11851 (define_insn "prologue_use"
11852 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11853 ""
11854 ""
11855 [(set_attr "length" "0")])
11856
11857 ;; Insn emitted into the body of a function to return from a function.
11858 ;; This is only done if the function's epilogue is known to be simple.
11859 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11860
11861 (define_expand "return"
11862 [(simple_return)]
11863 "ix86_can_use_return_insn_p ()"
11864 {
11865 ix86_maybe_emit_epilogue_vzeroupper ();
11866 if (crtl->args.pops_args)
11867 {
11868 rtx popc = GEN_INT (crtl->args.pops_args);
11869 emit_jump_insn (gen_simple_return_pop_internal (popc));
11870 DONE;
11871 }
11872 })
11873
11874 ;; We need to disable this for TARGET_SEH, as otherwise
11875 ;; shrink-wrapped prologue gets enabled too. This might exceed
11876 ;; the maximum size of prologue in unwind information.
11877
11878 (define_expand "simple_return"
11879 [(simple_return)]
11880 "!TARGET_SEH"
11881 {
11882 ix86_maybe_emit_epilogue_vzeroupper ();
11883 if (crtl->args.pops_args)
11884 {
11885 rtx popc = GEN_INT (crtl->args.pops_args);
11886 emit_jump_insn (gen_simple_return_pop_internal (popc));
11887 DONE;
11888 }
11889 })
11890
11891 (define_insn "simple_return_internal"
11892 [(simple_return)]
11893 "reload_completed"
11894 "ret"
11895 [(set_attr "length" "1")
11896 (set_attr "atom_unit" "jeu")
11897 (set_attr "length_immediate" "0")
11898 (set_attr "modrm" "0")])
11899
11900 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11901 ;; instruction Athlon and K8 have.
11902
11903 (define_insn "simple_return_internal_long"
11904 [(simple_return)
11905 (unspec [(const_int 0)] UNSPEC_REP)]
11906 "reload_completed"
11907 "rep%; ret"
11908 [(set_attr "length" "2")
11909 (set_attr "atom_unit" "jeu")
11910 (set_attr "length_immediate" "0")
11911 (set_attr "prefix_rep" "1")
11912 (set_attr "modrm" "0")])
11913
11914 (define_insn "simple_return_pop_internal"
11915 [(simple_return)
11916 (use (match_operand:SI 0 "const_int_operand"))]
11917 "reload_completed"
11918 "ret\t%0"
11919 [(set_attr "length" "3")
11920 (set_attr "atom_unit" "jeu")
11921 (set_attr "length_immediate" "2")
11922 (set_attr "modrm" "0")])
11923
11924 (define_insn "simple_return_indirect_internal"
11925 [(simple_return)
11926 (use (match_operand:SI 0 "register_operand" "r"))]
11927 "reload_completed"
11928 "jmp\t%A0"
11929 [(set_attr "type" "ibr")
11930 (set_attr "length_immediate" "0")])
11931
11932 (define_insn "nop"
11933 [(const_int 0)]
11934 ""
11935 "nop"
11936 [(set_attr "length" "1")
11937 (set_attr "length_immediate" "0")
11938 (set_attr "modrm" "0")])
11939
11940 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11941 (define_insn "nops"
11942 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11943 UNSPECV_NOPS)]
11944 "reload_completed"
11945 {
11946 int num = INTVAL (operands[0]);
11947
11948 gcc_assert (IN_RANGE (num, 1, 8));
11949
11950 while (num--)
11951 fputs ("\tnop\n", asm_out_file);
11952
11953 return "";
11954 }
11955 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11956 (set_attr "length_immediate" "0")
11957 (set_attr "modrm" "0")])
11958
11959 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11960 ;; branch prediction penalty for the third jump in a 16-byte
11961 ;; block on K8.
11962
11963 (define_insn "pad"
11964 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11965 ""
11966 {
11967 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11968 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11969 #else
11970 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11971 The align insn is used to avoid 3 jump instructions in the row to improve
11972 branch prediction and the benefits hardly outweigh the cost of extra 8
11973 nops on the average inserted by full alignment pseudo operation. */
11974 #endif
11975 return "";
11976 }
11977 [(set_attr "length" "16")])
11978
11979 (define_expand "prologue"
11980 [(const_int 0)]
11981 ""
11982 "ix86_expand_prologue (); DONE;")
11983
11984 (define_insn "set_got"
11985 [(set (match_operand:SI 0 "register_operand" "=r")
11986 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11987 (clobber (reg:CC FLAGS_REG))]
11988 "!TARGET_64BIT"
11989 "* return output_set_got (operands[0], NULL_RTX);"
11990 [(set_attr "type" "multi")
11991 (set_attr "length" "12")])
11992
11993 (define_insn "set_got_labelled"
11994 [(set (match_operand:SI 0 "register_operand" "=r")
11995 (unspec:SI [(label_ref (match_operand 1))]
11996 UNSPEC_SET_GOT))
11997 (clobber (reg:CC FLAGS_REG))]
11998 "!TARGET_64BIT"
11999 "* return output_set_got (operands[0], operands[1]);"
12000 [(set_attr "type" "multi")
12001 (set_attr "length" "12")])
12002
12003 (define_insn "set_got_rex64"
12004 [(set (match_operand:DI 0 "register_operand" "=r")
12005 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12006 "TARGET_64BIT"
12007 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12008 [(set_attr "type" "lea")
12009 (set_attr "length_address" "4")
12010 (set_attr "mode" "DI")])
12011
12012 (define_insn "set_rip_rex64"
12013 [(set (match_operand:DI 0 "register_operand" "=r")
12014 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12015 "TARGET_64BIT"
12016 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12017 [(set_attr "type" "lea")
12018 (set_attr "length_address" "4")
12019 (set_attr "mode" "DI")])
12020
12021 (define_insn "set_got_offset_rex64"
12022 [(set (match_operand:DI 0 "register_operand" "=r")
12023 (unspec:DI
12024 [(label_ref (match_operand 1))]
12025 UNSPEC_SET_GOT_OFFSET))]
12026 "TARGET_LP64"
12027 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12028 [(set_attr "type" "imov")
12029 (set_attr "length_immediate" "0")
12030 (set_attr "length_address" "8")
12031 (set_attr "mode" "DI")])
12032
12033 (define_expand "epilogue"
12034 [(const_int 0)]
12035 ""
12036 "ix86_expand_epilogue (1); DONE;")
12037
12038 (define_expand "sibcall_epilogue"
12039 [(const_int 0)]
12040 ""
12041 "ix86_expand_epilogue (0); DONE;")
12042
12043 (define_expand "eh_return"
12044 [(use (match_operand 0 "register_operand"))]
12045 ""
12046 {
12047 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12048
12049 /* Tricky bit: we write the address of the handler to which we will
12050 be returning into someone else's stack frame, one word below the
12051 stack address we wish to restore. */
12052 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12053 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12054 tmp = gen_rtx_MEM (Pmode, tmp);
12055 emit_move_insn (tmp, ra);
12056
12057 emit_jump_insn (gen_eh_return_internal ());
12058 emit_barrier ();
12059 DONE;
12060 })
12061
12062 (define_insn_and_split "eh_return_internal"
12063 [(eh_return)]
12064 ""
12065 "#"
12066 "epilogue_completed"
12067 [(const_int 0)]
12068 "ix86_expand_epilogue (2); DONE;")
12069
12070 (define_insn "leave"
12071 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12072 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12073 (clobber (mem:BLK (scratch)))]
12074 "!TARGET_64BIT"
12075 "leave"
12076 [(set_attr "type" "leave")])
12077
12078 (define_insn "leave_rex64"
12079 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12080 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12081 (clobber (mem:BLK (scratch)))]
12082 "TARGET_64BIT"
12083 "leave"
12084 [(set_attr "type" "leave")])
12085 \f
12086 ;; Handle -fsplit-stack.
12087
12088 (define_expand "split_stack_prologue"
12089 [(const_int 0)]
12090 ""
12091 {
12092 ix86_expand_split_stack_prologue ();
12093 DONE;
12094 })
12095
12096 ;; In order to support the call/return predictor, we use a return
12097 ;; instruction which the middle-end doesn't see.
12098 (define_insn "split_stack_return"
12099 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12100 UNSPECV_SPLIT_STACK_RETURN)]
12101 ""
12102 {
12103 if (operands[0] == const0_rtx)
12104 return "ret";
12105 else
12106 return "ret\t%0";
12107 }
12108 [(set_attr "atom_unit" "jeu")
12109 (set_attr "modrm" "0")
12110 (set (attr "length")
12111 (if_then_else (match_operand:SI 0 "const0_operand")
12112 (const_int 1)
12113 (const_int 3)))
12114 (set (attr "length_immediate")
12115 (if_then_else (match_operand:SI 0 "const0_operand")
12116 (const_int 0)
12117 (const_int 2)))])
12118
12119 ;; If there are operand 0 bytes available on the stack, jump to
12120 ;; operand 1.
12121
12122 (define_expand "split_stack_space_check"
12123 [(set (pc) (if_then_else
12124 (ltu (minus (reg SP_REG)
12125 (match_operand 0 "register_operand"))
12126 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12127 (label_ref (match_operand 1))
12128 (pc)))]
12129 ""
12130 {
12131 rtx reg, size, limit;
12132
12133 reg = gen_reg_rtx (Pmode);
12134 size = force_reg (Pmode, operands[0]);
12135 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12136 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12137 UNSPEC_STACK_CHECK);
12138 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12139 ix86_expand_branch (GEU, reg, limit, operands[1]);
12140
12141 DONE;
12142 })
12143 \f
12144 ;; Bit manipulation instructions.
12145
12146 (define_expand "ffs<mode>2"
12147 [(set (match_dup 2) (const_int -1))
12148 (parallel [(set (match_dup 3) (match_dup 4))
12149 (set (match_operand:SWI48 0 "register_operand")
12150 (ctz:SWI48
12151 (match_operand:SWI48 1 "nonimmediate_operand")))])
12152 (set (match_dup 0) (if_then_else:SWI48
12153 (eq (match_dup 3) (const_int 0))
12154 (match_dup 2)
12155 (match_dup 0)))
12156 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12157 (clobber (reg:CC FLAGS_REG))])]
12158 ""
12159 {
12160 enum machine_mode flags_mode;
12161
12162 if (<MODE>mode == SImode && !TARGET_CMOVE)
12163 {
12164 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12165 DONE;
12166 }
12167
12168 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12169
12170 operands[2] = gen_reg_rtx (<MODE>mode);
12171 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12172 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12173 })
12174
12175 (define_insn_and_split "ffssi2_no_cmove"
12176 [(set (match_operand:SI 0 "register_operand" "=r")
12177 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12178 (clobber (match_scratch:SI 2 "=&q"))
12179 (clobber (reg:CC FLAGS_REG))]
12180 "!TARGET_CMOVE"
12181 "#"
12182 "&& reload_completed"
12183 [(parallel [(set (match_dup 4) (match_dup 5))
12184 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12185 (set (strict_low_part (match_dup 3))
12186 (eq:QI (match_dup 4) (const_int 0)))
12187 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12188 (clobber (reg:CC FLAGS_REG))])
12189 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12190 (clobber (reg:CC FLAGS_REG))])
12191 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12192 (clobber (reg:CC FLAGS_REG))])]
12193 {
12194 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12195
12196 operands[3] = gen_lowpart (QImode, operands[2]);
12197 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12198 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12199
12200 ix86_expand_clear (operands[2]);
12201 })
12202
12203 (define_insn "*tzcnt<mode>_1"
12204 [(set (reg:CCC FLAGS_REG)
12205 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12206 (const_int 0)))
12207 (set (match_operand:SWI48 0 "register_operand" "=r")
12208 (ctz:SWI48 (match_dup 1)))]
12209 "TARGET_BMI"
12210 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12211 [(set_attr "type" "alu1")
12212 (set_attr "prefix_0f" "1")
12213 (set_attr "prefix_rep" "1")
12214 (set_attr "mode" "<MODE>")])
12215
12216 (define_insn "*bsf<mode>_1"
12217 [(set (reg:CCZ FLAGS_REG)
12218 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12219 (const_int 0)))
12220 (set (match_operand:SWI48 0 "register_operand" "=r")
12221 (ctz:SWI48 (match_dup 1)))]
12222 ""
12223 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12224 [(set_attr "type" "alu1")
12225 (set_attr "prefix_0f" "1")
12226 (set_attr "mode" "<MODE>")])
12227
12228 (define_insn "ctz<mode>2"
12229 [(set (match_operand:SWI248 0 "register_operand" "=r")
12230 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12231 (clobber (reg:CC FLAGS_REG))]
12232 ""
12233 {
12234 if (TARGET_BMI)
12235 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12236 else if (optimize_function_for_size_p (cfun))
12237 ;
12238 else if (TARGET_GENERIC)
12239 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12240 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12241
12242 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12243 }
12244 [(set_attr "type" "alu1")
12245 (set_attr "prefix_0f" "1")
12246 (set (attr "prefix_rep")
12247 (if_then_else
12248 (ior (match_test "TARGET_BMI")
12249 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12250 (match_test "TARGET_GENERIC")))
12251 (const_string "1")
12252 (const_string "0")))
12253 (set_attr "mode" "<MODE>")])
12254
12255 (define_expand "clz<mode>2"
12256 [(parallel
12257 [(set (match_operand:SWI248 0 "register_operand")
12258 (minus:SWI248
12259 (match_dup 2)
12260 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12261 (clobber (reg:CC FLAGS_REG))])
12262 (parallel
12263 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12264 (clobber (reg:CC FLAGS_REG))])]
12265 ""
12266 {
12267 if (TARGET_LZCNT)
12268 {
12269 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12270 DONE;
12271 }
12272 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12273 })
12274
12275 (define_insn "clz<mode>2_lzcnt"
12276 [(set (match_operand:SWI248 0 "register_operand" "=r")
12277 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12278 (clobber (reg:CC FLAGS_REG))]
12279 "TARGET_LZCNT"
12280 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12281 [(set_attr "prefix_rep" "1")
12282 (set_attr "type" "bitmanip")
12283 (set_attr "mode" "<MODE>")])
12284
12285 ;; BMI instructions.
12286 (define_insn "*bmi_andn_<mode>"
12287 [(set (match_operand:SWI48 0 "register_operand" "=r")
12288 (and:SWI48
12289 (not:SWI48
12290 (match_operand:SWI48 1 "register_operand" "r"))
12291 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12292 (clobber (reg:CC FLAGS_REG))]
12293 "TARGET_BMI"
12294 "andn\t{%2, %1, %0|%0, %1, %2}"
12295 [(set_attr "type" "bitmanip")
12296 (set_attr "mode" "<MODE>")])
12297
12298 (define_insn "bmi_bextr_<mode>"
12299 [(set (match_operand:SWI48 0 "register_operand" "=r")
12300 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12301 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12302 UNSPEC_BEXTR))
12303 (clobber (reg:CC FLAGS_REG))]
12304 "TARGET_BMI"
12305 "bextr\t{%2, %1, %0|%0, %1, %2}"
12306 [(set_attr "type" "bitmanip")
12307 (set_attr "mode" "<MODE>")])
12308
12309 (define_insn "*bmi_blsi_<mode>"
12310 [(set (match_operand:SWI48 0 "register_operand" "=r")
12311 (and:SWI48
12312 (neg:SWI48
12313 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12314 (match_dup 1)))
12315 (clobber (reg:CC FLAGS_REG))]
12316 "TARGET_BMI"
12317 "blsi\t{%1, %0|%0, %1}"
12318 [(set_attr "type" "bitmanip")
12319 (set_attr "mode" "<MODE>")])
12320
12321 (define_insn "*bmi_blsmsk_<mode>"
12322 [(set (match_operand:SWI48 0 "register_operand" "=r")
12323 (xor:SWI48
12324 (plus:SWI48
12325 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12326 (const_int -1))
12327 (match_dup 1)))
12328 (clobber (reg:CC FLAGS_REG))]
12329 "TARGET_BMI"
12330 "blsmsk\t{%1, %0|%0, %1}"
12331 [(set_attr "type" "bitmanip")
12332 (set_attr "mode" "<MODE>")])
12333
12334 (define_insn "*bmi_blsr_<mode>"
12335 [(set (match_operand:SWI48 0 "register_operand" "=r")
12336 (and:SWI48
12337 (plus:SWI48
12338 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12339 (const_int -1))
12340 (match_dup 1)))
12341 (clobber (reg:CC FLAGS_REG))]
12342 "TARGET_BMI"
12343 "blsr\t{%1, %0|%0, %1}"
12344 [(set_attr "type" "bitmanip")
12345 (set_attr "mode" "<MODE>")])
12346
12347 ;; BMI2 instructions.
12348 (define_insn "bmi2_bzhi_<mode>3"
12349 [(set (match_operand:SWI48 0 "register_operand" "=r")
12350 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12351 (lshiftrt:SWI48 (const_int -1)
12352 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12353 (clobber (reg:CC FLAGS_REG))]
12354 "TARGET_BMI2"
12355 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12356 [(set_attr "type" "bitmanip")
12357 (set_attr "prefix" "vex")
12358 (set_attr "mode" "<MODE>")])
12359
12360 (define_insn "bmi2_pdep_<mode>3"
12361 [(set (match_operand:SWI48 0 "register_operand" "=r")
12362 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12363 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12364 UNSPEC_PDEP))]
12365 "TARGET_BMI2"
12366 "pdep\t{%2, %1, %0|%0, %1, %2}"
12367 [(set_attr "type" "bitmanip")
12368 (set_attr "prefix" "vex")
12369 (set_attr "mode" "<MODE>")])
12370
12371 (define_insn "bmi2_pext_<mode>3"
12372 [(set (match_operand:SWI48 0 "register_operand" "=r")
12373 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12374 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12375 UNSPEC_PEXT))]
12376 "TARGET_BMI2"
12377 "pext\t{%2, %1, %0|%0, %1, %2}"
12378 [(set_attr "type" "bitmanip")
12379 (set_attr "prefix" "vex")
12380 (set_attr "mode" "<MODE>")])
12381
12382 ;; TBM instructions.
12383 (define_insn "tbm_bextri_<mode>"
12384 [(set (match_operand:SWI48 0 "register_operand" "=r")
12385 (zero_extract:SWI48
12386 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12387 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12388 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12389 (clobber (reg:CC FLAGS_REG))]
12390 "TARGET_TBM"
12391 {
12392 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12393 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12394 }
12395 [(set_attr "type" "bitmanip")
12396 (set_attr "mode" "<MODE>")])
12397
12398 (define_insn "*tbm_blcfill_<mode>"
12399 [(set (match_operand:SWI48 0 "register_operand" "=r")
12400 (and:SWI48
12401 (plus:SWI48
12402 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12403 (const_int 1))
12404 (match_dup 1)))
12405 (clobber (reg:CC FLAGS_REG))]
12406 "TARGET_TBM"
12407 "blcfill\t{%1, %0|%0, %1}"
12408 [(set_attr "type" "bitmanip")
12409 (set_attr "mode" "<MODE>")])
12410
12411 (define_insn "*tbm_blci_<mode>"
12412 [(set (match_operand:SWI48 0 "register_operand" "=r")
12413 (ior:SWI48
12414 (not:SWI48
12415 (plus:SWI48
12416 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12417 (const_int 1)))
12418 (match_dup 1)))
12419 (clobber (reg:CC FLAGS_REG))]
12420 "TARGET_TBM"
12421 "blci\t{%1, %0|%0, %1}"
12422 [(set_attr "type" "bitmanip")
12423 (set_attr "mode" "<MODE>")])
12424
12425 (define_insn "*tbm_blcic_<mode>"
12426 [(set (match_operand:SWI48 0 "register_operand" "=r")
12427 (and:SWI48
12428 (plus:SWI48
12429 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12430 (const_int 1))
12431 (not:SWI48
12432 (match_dup 1))))
12433 (clobber (reg:CC FLAGS_REG))]
12434 "TARGET_TBM"
12435 "blcic\t{%1, %0|%0, %1}"
12436 [(set_attr "type" "bitmanip")
12437 (set_attr "mode" "<MODE>")])
12438
12439 (define_insn "*tbm_blcmsk_<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_TBM"
12448 "blcmsk\t{%1, %0|%0, %1}"
12449 [(set_attr "type" "bitmanip")
12450 (set_attr "mode" "<MODE>")])
12451
12452 (define_insn "*tbm_blcs_<mode>"
12453 [(set (match_operand:SWI48 0 "register_operand" "=r")
12454 (ior:SWI48
12455 (plus:SWI48
12456 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12457 (const_int 1))
12458 (match_dup 1)))
12459 (clobber (reg:CC FLAGS_REG))]
12460 "TARGET_TBM"
12461 "blcs\t{%1, %0|%0, %1}"
12462 [(set_attr "type" "bitmanip")
12463 (set_attr "mode" "<MODE>")])
12464
12465 (define_insn "*tbm_blsfill_<mode>"
12466 [(set (match_operand:SWI48 0 "register_operand" "=r")
12467 (ior:SWI48
12468 (plus:SWI48
12469 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12470 (const_int -1))
12471 (match_dup 1)))
12472 (clobber (reg:CC FLAGS_REG))]
12473 "TARGET_TBM"
12474 "blsfill\t{%1, %0|%0, %1}"
12475 [(set_attr "type" "bitmanip")
12476 (set_attr "mode" "<MODE>")])
12477
12478 (define_insn "*tbm_blsic_<mode>"
12479 [(set (match_operand:SWI48 0 "register_operand" "=r")
12480 (ior:SWI48
12481 (plus:SWI48
12482 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12483 (const_int -1))
12484 (not:SWI48
12485 (match_dup 1))))
12486 (clobber (reg:CC FLAGS_REG))]
12487 "TARGET_TBM"
12488 "blsic\t{%1, %0|%0, %1}"
12489 [(set_attr "type" "bitmanip")
12490 (set_attr "mode" "<MODE>")])
12491
12492 (define_insn "*tbm_t1mskc_<mode>"
12493 [(set (match_operand:SWI48 0 "register_operand" "=r")
12494 (ior:SWI48
12495 (plus:SWI48
12496 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12497 (const_int 1))
12498 (not:SWI48
12499 (match_dup 1))))
12500 (clobber (reg:CC FLAGS_REG))]
12501 "TARGET_TBM"
12502 "t1mskc\t{%1, %0|%0, %1}"
12503 [(set_attr "type" "bitmanip")
12504 (set_attr "mode" "<MODE>")])
12505
12506 (define_insn "*tbm_tzmsk_<mode>"
12507 [(set (match_operand:SWI48 0 "register_operand" "=r")
12508 (and:SWI48
12509 (plus:SWI48
12510 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12511 (const_int -1))
12512 (not:SWI48
12513 (match_dup 1))))
12514 (clobber (reg:CC FLAGS_REG))]
12515 "TARGET_TBM"
12516 "tzmsk\t{%1, %0|%0, %1}"
12517 [(set_attr "type" "bitmanip")
12518 (set_attr "mode" "<MODE>")])
12519
12520 (define_insn "bsr_rex64"
12521 [(set (match_operand:DI 0 "register_operand" "=r")
12522 (minus:DI (const_int 63)
12523 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12524 (clobber (reg:CC FLAGS_REG))]
12525 "TARGET_64BIT"
12526 "bsr{q}\t{%1, %0|%0, %1}"
12527 [(set_attr "type" "alu1")
12528 (set_attr "prefix_0f" "1")
12529 (set_attr "mode" "DI")])
12530
12531 (define_insn "bsr"
12532 [(set (match_operand:SI 0 "register_operand" "=r")
12533 (minus:SI (const_int 31)
12534 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12535 (clobber (reg:CC FLAGS_REG))]
12536 ""
12537 "bsr{l}\t{%1, %0|%0, %1}"
12538 [(set_attr "type" "alu1")
12539 (set_attr "prefix_0f" "1")
12540 (set_attr "mode" "SI")])
12541
12542 (define_insn "*bsrhi"
12543 [(set (match_operand:HI 0 "register_operand" "=r")
12544 (minus:HI (const_int 15)
12545 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12546 (clobber (reg:CC FLAGS_REG))]
12547 ""
12548 "bsr{w}\t{%1, %0|%0, %1}"
12549 [(set_attr "type" "alu1")
12550 (set_attr "prefix_0f" "1")
12551 (set_attr "mode" "HI")])
12552
12553 (define_insn "popcount<mode>2"
12554 [(set (match_operand:SWI248 0 "register_operand" "=r")
12555 (popcount:SWI248
12556 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12557 (clobber (reg:CC FLAGS_REG))]
12558 "TARGET_POPCNT"
12559 {
12560 #if TARGET_MACHO
12561 return "popcnt\t{%1, %0|%0, %1}";
12562 #else
12563 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12564 #endif
12565 }
12566 [(set_attr "prefix_rep" "1")
12567 (set_attr "type" "bitmanip")
12568 (set_attr "mode" "<MODE>")])
12569
12570 (define_insn "*popcount<mode>2_cmp"
12571 [(set (reg FLAGS_REG)
12572 (compare
12573 (popcount:SWI248
12574 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12575 (const_int 0)))
12576 (set (match_operand:SWI248 0 "register_operand" "=r")
12577 (popcount:SWI248 (match_dup 1)))]
12578 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12579 {
12580 #if TARGET_MACHO
12581 return "popcnt\t{%1, %0|%0, %1}";
12582 #else
12583 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12584 #endif
12585 }
12586 [(set_attr "prefix_rep" "1")
12587 (set_attr "type" "bitmanip")
12588 (set_attr "mode" "<MODE>")])
12589
12590 (define_insn "*popcountsi2_cmp_zext"
12591 [(set (reg FLAGS_REG)
12592 (compare
12593 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12594 (const_int 0)))
12595 (set (match_operand:DI 0 "register_operand" "=r")
12596 (zero_extend:DI(popcount:SI (match_dup 1))))]
12597 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12598 {
12599 #if TARGET_MACHO
12600 return "popcnt\t{%1, %0|%0, %1}";
12601 #else
12602 return "popcnt{l}\t{%1, %0|%0, %1}";
12603 #endif
12604 }
12605 [(set_attr "prefix_rep" "1")
12606 (set_attr "type" "bitmanip")
12607 (set_attr "mode" "SI")])
12608
12609 (define_expand "bswapdi2"
12610 [(set (match_operand:DI 0 "register_operand")
12611 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12612 ""
12613 {
12614 if (TARGET_64BIT && !TARGET_MOVBE)
12615 operands[1] = force_reg (DImode, operands[1]);
12616 })
12617
12618 (define_insn_and_split "*bswapdi2_doubleword"
12619 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12620 (bswap:DI
12621 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12622 "!TARGET_64BIT
12623 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12624 "#"
12625 "&& reload_completed"
12626 [(set (match_dup 2)
12627 (bswap:SI (match_dup 1)))
12628 (set (match_dup 0)
12629 (bswap:SI (match_dup 3)))]
12630 {
12631 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12632
12633 if (REG_P (operands[0]) && REG_P (operands[1]))
12634 {
12635 emit_insn (gen_swapsi (operands[0], operands[2]));
12636 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12637 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12638 DONE;
12639 }
12640
12641 if (!TARGET_MOVBE)
12642 {
12643 if (MEM_P (operands[0]))
12644 {
12645 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12646 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12647
12648 emit_move_insn (operands[0], operands[3]);
12649 emit_move_insn (operands[2], operands[1]);
12650 }
12651 if (MEM_P (operands[1]))
12652 {
12653 emit_move_insn (operands[2], operands[1]);
12654 emit_move_insn (operands[0], operands[3]);
12655
12656 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12657 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12658 }
12659 DONE;
12660 }
12661 })
12662
12663 (define_expand "bswapsi2"
12664 [(set (match_operand:SI 0 "register_operand")
12665 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12666 ""
12667 {
12668 if (TARGET_MOVBE)
12669 ;
12670 else if (TARGET_BSWAP)
12671 operands[1] = force_reg (SImode, operands[1]);
12672 else
12673 {
12674 rtx x = operands[0];
12675
12676 emit_move_insn (x, operands[1]);
12677 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12678 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12679 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12680 DONE;
12681 }
12682 })
12683
12684 (define_insn "*bswap<mode>2_movbe"
12685 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12686 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12687 "TARGET_MOVBE
12688 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12689 "@
12690 bswap\t%0
12691 movbe\t{%1, %0|%0, %1}
12692 movbe\t{%1, %0|%0, %1}"
12693 [(set_attr "type" "bitmanip,imov,imov")
12694 (set_attr "modrm" "0,1,1")
12695 (set_attr "prefix_0f" "*,1,1")
12696 (set_attr "prefix_extra" "*,1,1")
12697 (set_attr "mode" "<MODE>")])
12698
12699 (define_insn "*bswap<mode>2"
12700 [(set (match_operand:SWI48 0 "register_operand" "=r")
12701 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12702 "TARGET_BSWAP"
12703 "bswap\t%0"
12704 [(set_attr "type" "bitmanip")
12705 (set_attr "modrm" "0")
12706 (set_attr "mode" "<MODE>")])
12707
12708 (define_insn "*bswaphi_lowpart_1"
12709 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12710 (bswap:HI (match_dup 0)))
12711 (clobber (reg:CC FLAGS_REG))]
12712 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12713 "@
12714 xchg{b}\t{%h0, %b0|%b0, %h0}
12715 rol{w}\t{$8, %0|%0, 8}"
12716 [(set_attr "length" "2,4")
12717 (set_attr "mode" "QI,HI")])
12718
12719 (define_insn "bswaphi_lowpart"
12720 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12721 (bswap:HI (match_dup 0)))
12722 (clobber (reg:CC FLAGS_REG))]
12723 ""
12724 "rol{w}\t{$8, %0|%0, 8}"
12725 [(set_attr "length" "4")
12726 (set_attr "mode" "HI")])
12727
12728 (define_expand "paritydi2"
12729 [(set (match_operand:DI 0 "register_operand")
12730 (parity:DI (match_operand:DI 1 "register_operand")))]
12731 "! TARGET_POPCNT"
12732 {
12733 rtx scratch = gen_reg_rtx (QImode);
12734 rtx cond;
12735
12736 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12737 NULL_RTX, operands[1]));
12738
12739 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12740 gen_rtx_REG (CCmode, FLAGS_REG),
12741 const0_rtx);
12742 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12743
12744 if (TARGET_64BIT)
12745 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12746 else
12747 {
12748 rtx tmp = gen_reg_rtx (SImode);
12749
12750 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12751 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12752 }
12753 DONE;
12754 })
12755
12756 (define_expand "paritysi2"
12757 [(set (match_operand:SI 0 "register_operand")
12758 (parity:SI (match_operand:SI 1 "register_operand")))]
12759 "! TARGET_POPCNT"
12760 {
12761 rtx scratch = gen_reg_rtx (QImode);
12762 rtx cond;
12763
12764 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12765
12766 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12767 gen_rtx_REG (CCmode, FLAGS_REG),
12768 const0_rtx);
12769 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12770
12771 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12772 DONE;
12773 })
12774
12775 (define_insn_and_split "paritydi2_cmp"
12776 [(set (reg:CC FLAGS_REG)
12777 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12778 UNSPEC_PARITY))
12779 (clobber (match_scratch:DI 0 "=r"))
12780 (clobber (match_scratch:SI 1 "=&r"))
12781 (clobber (match_scratch:HI 2 "=Q"))]
12782 "! TARGET_POPCNT"
12783 "#"
12784 "&& reload_completed"
12785 [(parallel
12786 [(set (match_dup 1)
12787 (xor:SI (match_dup 1) (match_dup 4)))
12788 (clobber (reg:CC FLAGS_REG))])
12789 (parallel
12790 [(set (reg:CC FLAGS_REG)
12791 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12792 (clobber (match_dup 1))
12793 (clobber (match_dup 2))])]
12794 {
12795 operands[4] = gen_lowpart (SImode, operands[3]);
12796
12797 if (TARGET_64BIT)
12798 {
12799 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12800 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12801 }
12802 else
12803 operands[1] = gen_highpart (SImode, operands[3]);
12804 })
12805
12806 (define_insn_and_split "paritysi2_cmp"
12807 [(set (reg:CC FLAGS_REG)
12808 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12809 UNSPEC_PARITY))
12810 (clobber (match_scratch:SI 0 "=r"))
12811 (clobber (match_scratch:HI 1 "=&Q"))]
12812 "! TARGET_POPCNT"
12813 "#"
12814 "&& reload_completed"
12815 [(parallel
12816 [(set (match_dup 1)
12817 (xor:HI (match_dup 1) (match_dup 3)))
12818 (clobber (reg:CC FLAGS_REG))])
12819 (parallel
12820 [(set (reg:CC FLAGS_REG)
12821 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12822 (clobber (match_dup 1))])]
12823 {
12824 operands[3] = gen_lowpart (HImode, operands[2]);
12825
12826 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12827 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12828 })
12829
12830 (define_insn "*parityhi2_cmp"
12831 [(set (reg:CC FLAGS_REG)
12832 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12833 UNSPEC_PARITY))
12834 (clobber (match_scratch:HI 0 "=Q"))]
12835 "! TARGET_POPCNT"
12836 "xor{b}\t{%h0, %b0|%b0, %h0}"
12837 [(set_attr "length" "2")
12838 (set_attr "mode" "HI")])
12839
12840 \f
12841 ;; Thread-local storage patterns for ELF.
12842 ;;
12843 ;; Note that these code sequences must appear exactly as shown
12844 ;; in order to allow linker relaxation.
12845
12846 (define_insn "*tls_global_dynamic_32_gnu"
12847 [(set (match_operand:SI 0 "register_operand" "=a")
12848 (unspec:SI
12849 [(match_operand:SI 1 "register_operand" "b")
12850 (match_operand 2 "tls_symbolic_operand")
12851 (match_operand 3 "constant_call_address_operand" "z")]
12852 UNSPEC_TLS_GD))
12853 (clobber (match_scratch:SI 4 "=d"))
12854 (clobber (match_scratch:SI 5 "=c"))
12855 (clobber (reg:CC FLAGS_REG))]
12856 "!TARGET_64BIT && TARGET_GNU_TLS"
12857 {
12858 output_asm_insn
12859 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12860 if (TARGET_SUN_TLS)
12861 #ifdef HAVE_AS_IX86_TLSGDPLT
12862 return "call\t%a2@tlsgdplt";
12863 #else
12864 return "call\t%p3@plt";
12865 #endif
12866 return "call\t%P3";
12867 }
12868 [(set_attr "type" "multi")
12869 (set_attr "length" "12")])
12870
12871 (define_expand "tls_global_dynamic_32"
12872 [(parallel
12873 [(set (match_operand:SI 0 "register_operand")
12874 (unspec:SI [(match_operand:SI 2 "register_operand")
12875 (match_operand 1 "tls_symbolic_operand")
12876 (match_operand 3 "constant_call_address_operand")]
12877 UNSPEC_TLS_GD))
12878 (clobber (match_scratch:SI 4))
12879 (clobber (match_scratch:SI 5))
12880 (clobber (reg:CC FLAGS_REG))])])
12881
12882 (define_insn "*tls_global_dynamic_64_<mode>"
12883 [(set (match_operand:P 0 "register_operand" "=a")
12884 (call:P
12885 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12886 (match_operand 3)))
12887 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12888 UNSPEC_TLS_GD)]
12889 "TARGET_64BIT"
12890 {
12891 if (!TARGET_X32)
12892 fputs (ASM_BYTE "0x66\n", asm_out_file);
12893 output_asm_insn
12894 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12895 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12896 fputs ("\trex64\n", asm_out_file);
12897 if (TARGET_SUN_TLS)
12898 return "call\t%p2@plt";
12899 return "call\t%P2";
12900 }
12901 [(set_attr "type" "multi")
12902 (set (attr "length")
12903 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12904
12905 (define_expand "tls_global_dynamic_64_<mode>"
12906 [(parallel
12907 [(set (match_operand:P 0 "register_operand")
12908 (call:P
12909 (mem:QI (match_operand 2 "constant_call_address_operand"))
12910 (const_int 0)))
12911 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12912 UNSPEC_TLS_GD)])]
12913 "TARGET_64BIT")
12914
12915 (define_insn "*tls_local_dynamic_base_32_gnu"
12916 [(set (match_operand:SI 0 "register_operand" "=a")
12917 (unspec:SI
12918 [(match_operand:SI 1 "register_operand" "b")
12919 (match_operand 2 "constant_call_address_operand" "z")]
12920 UNSPEC_TLS_LD_BASE))
12921 (clobber (match_scratch:SI 3 "=d"))
12922 (clobber (match_scratch:SI 4 "=c"))
12923 (clobber (reg:CC FLAGS_REG))]
12924 "!TARGET_64BIT && TARGET_GNU_TLS"
12925 {
12926 output_asm_insn
12927 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12928 if (TARGET_SUN_TLS)
12929 #ifdef HAVE_AS_IX86_TLSLDMPLT
12930 return "call\t%&@tlsldmplt";
12931 #else
12932 return "call\t%p2@plt";
12933 #endif
12934 return "call\t%P2";
12935 }
12936 [(set_attr "type" "multi")
12937 (set_attr "length" "11")])
12938
12939 (define_expand "tls_local_dynamic_base_32"
12940 [(parallel
12941 [(set (match_operand:SI 0 "register_operand")
12942 (unspec:SI
12943 [(match_operand:SI 1 "register_operand")
12944 (match_operand 2 "constant_call_address_operand")]
12945 UNSPEC_TLS_LD_BASE))
12946 (clobber (match_scratch:SI 3))
12947 (clobber (match_scratch:SI 4))
12948 (clobber (reg:CC FLAGS_REG))])])
12949
12950 (define_insn "*tls_local_dynamic_base_64_<mode>"
12951 [(set (match_operand:P 0 "register_operand" "=a")
12952 (call:P
12953 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12954 (match_operand 2)))
12955 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12956 "TARGET_64BIT"
12957 {
12958 output_asm_insn
12959 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12960 if (TARGET_SUN_TLS)
12961 return "call\t%p1@plt";
12962 return "call\t%P1";
12963 }
12964 [(set_attr "type" "multi")
12965 (set_attr "length" "12")])
12966
12967 (define_expand "tls_local_dynamic_base_64_<mode>"
12968 [(parallel
12969 [(set (match_operand:P 0 "register_operand")
12970 (call:P
12971 (mem:QI (match_operand 1 "constant_call_address_operand"))
12972 (const_int 0)))
12973 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12974 "TARGET_64BIT")
12975
12976 ;; Local dynamic of a single variable is a lose. Show combine how
12977 ;; to convert that back to global dynamic.
12978
12979 (define_insn_and_split "*tls_local_dynamic_32_once"
12980 [(set (match_operand:SI 0 "register_operand" "=a")
12981 (plus:SI
12982 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12983 (match_operand 2 "constant_call_address_operand" "z")]
12984 UNSPEC_TLS_LD_BASE)
12985 (const:SI (unspec:SI
12986 [(match_operand 3 "tls_symbolic_operand")]
12987 UNSPEC_DTPOFF))))
12988 (clobber (match_scratch:SI 4 "=d"))
12989 (clobber (match_scratch:SI 5 "=c"))
12990 (clobber (reg:CC FLAGS_REG))]
12991 ""
12992 "#"
12993 ""
12994 [(parallel
12995 [(set (match_dup 0)
12996 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12997 UNSPEC_TLS_GD))
12998 (clobber (match_dup 4))
12999 (clobber (match_dup 5))
13000 (clobber (reg:CC FLAGS_REG))])])
13001
13002 ;; Segment register for the thread base ptr load
13003 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13004
13005 ;; Load and add the thread base pointer from %<tp_seg>:0.
13006 (define_insn "*load_tp_x32"
13007 [(set (match_operand:SI 0 "register_operand" "=r")
13008 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13009 "TARGET_X32"
13010 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13011 [(set_attr "type" "imov")
13012 (set_attr "modrm" "0")
13013 (set_attr "length" "7")
13014 (set_attr "memory" "load")
13015 (set_attr "imm_disp" "false")])
13016
13017 (define_insn "*load_tp_x32_zext"
13018 [(set (match_operand:DI 0 "register_operand" "=r")
13019 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13020 "TARGET_X32"
13021 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13022 [(set_attr "type" "imov")
13023 (set_attr "modrm" "0")
13024 (set_attr "length" "7")
13025 (set_attr "memory" "load")
13026 (set_attr "imm_disp" "false")])
13027
13028 (define_insn "*load_tp_<mode>"
13029 [(set (match_operand:P 0 "register_operand" "=r")
13030 (unspec:P [(const_int 0)] UNSPEC_TP))]
13031 "!TARGET_X32"
13032 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13033 [(set_attr "type" "imov")
13034 (set_attr "modrm" "0")
13035 (set_attr "length" "7")
13036 (set_attr "memory" "load")
13037 (set_attr "imm_disp" "false")])
13038
13039 (define_insn "*add_tp_x32"
13040 [(set (match_operand:SI 0 "register_operand" "=r")
13041 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13042 (match_operand:SI 1 "register_operand" "0")))
13043 (clobber (reg:CC FLAGS_REG))]
13044 "TARGET_X32"
13045 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13046 [(set_attr "type" "alu")
13047 (set_attr "modrm" "0")
13048 (set_attr "length" "7")
13049 (set_attr "memory" "load")
13050 (set_attr "imm_disp" "false")])
13051
13052 (define_insn "*add_tp_x32_zext"
13053 [(set (match_operand:DI 0 "register_operand" "=r")
13054 (zero_extend:DI
13055 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13056 (match_operand:SI 1 "register_operand" "0"))))
13057 (clobber (reg:CC FLAGS_REG))]
13058 "TARGET_X32"
13059 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13060 [(set_attr "type" "alu")
13061 (set_attr "modrm" "0")
13062 (set_attr "length" "7")
13063 (set_attr "memory" "load")
13064 (set_attr "imm_disp" "false")])
13065
13066 (define_insn "*add_tp_<mode>"
13067 [(set (match_operand:P 0 "register_operand" "=r")
13068 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13069 (match_operand:P 1 "register_operand" "0")))
13070 (clobber (reg:CC FLAGS_REG))]
13071 "!TARGET_X32"
13072 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13073 [(set_attr "type" "alu")
13074 (set_attr "modrm" "0")
13075 (set_attr "length" "7")
13076 (set_attr "memory" "load")
13077 (set_attr "imm_disp" "false")])
13078
13079 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13080 ;; %rax as destination of the initial executable code sequence.
13081 (define_insn "tls_initial_exec_64_sun"
13082 [(set (match_operand:DI 0 "register_operand" "=a")
13083 (unspec:DI
13084 [(match_operand 1 "tls_symbolic_operand")]
13085 UNSPEC_TLS_IE_SUN))
13086 (clobber (reg:CC FLAGS_REG))]
13087 "TARGET_64BIT && TARGET_SUN_TLS"
13088 {
13089 output_asm_insn
13090 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13091 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13092 }
13093 [(set_attr "type" "multi")])
13094
13095 ;; GNU2 TLS patterns can be split.
13096
13097 (define_expand "tls_dynamic_gnu2_32"
13098 [(set (match_dup 3)
13099 (plus:SI (match_operand:SI 2 "register_operand")
13100 (const:SI
13101 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13102 UNSPEC_TLSDESC))))
13103 (parallel
13104 [(set (match_operand:SI 0 "register_operand")
13105 (unspec:SI [(match_dup 1) (match_dup 3)
13106 (match_dup 2) (reg:SI SP_REG)]
13107 UNSPEC_TLSDESC))
13108 (clobber (reg:CC FLAGS_REG))])]
13109 "!TARGET_64BIT && TARGET_GNU2_TLS"
13110 {
13111 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13112 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13113 })
13114
13115 (define_insn "*tls_dynamic_gnu2_lea_32"
13116 [(set (match_operand:SI 0 "register_operand" "=r")
13117 (plus:SI (match_operand:SI 1 "register_operand" "b")
13118 (const:SI
13119 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13120 UNSPEC_TLSDESC))))]
13121 "!TARGET_64BIT && TARGET_GNU2_TLS"
13122 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13123 [(set_attr "type" "lea")
13124 (set_attr "mode" "SI")
13125 (set_attr "length" "6")
13126 (set_attr "length_address" "4")])
13127
13128 (define_insn "*tls_dynamic_gnu2_call_32"
13129 [(set (match_operand:SI 0 "register_operand" "=a")
13130 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13131 (match_operand:SI 2 "register_operand" "0")
13132 ;; we have to make sure %ebx still points to the GOT
13133 (match_operand:SI 3 "register_operand" "b")
13134 (reg:SI SP_REG)]
13135 UNSPEC_TLSDESC))
13136 (clobber (reg:CC FLAGS_REG))]
13137 "!TARGET_64BIT && TARGET_GNU2_TLS"
13138 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13139 [(set_attr "type" "call")
13140 (set_attr "length" "2")
13141 (set_attr "length_address" "0")])
13142
13143 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13144 [(set (match_operand:SI 0 "register_operand" "=&a")
13145 (plus:SI
13146 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13147 (match_operand:SI 4)
13148 (match_operand:SI 2 "register_operand" "b")
13149 (reg:SI SP_REG)]
13150 UNSPEC_TLSDESC)
13151 (const:SI (unspec:SI
13152 [(match_operand 1 "tls_symbolic_operand")]
13153 UNSPEC_DTPOFF))))
13154 (clobber (reg:CC FLAGS_REG))]
13155 "!TARGET_64BIT && TARGET_GNU2_TLS"
13156 "#"
13157 ""
13158 [(set (match_dup 0) (match_dup 5))]
13159 {
13160 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13161 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13162 })
13163
13164 (define_expand "tls_dynamic_gnu2_64"
13165 [(set (match_dup 2)
13166 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13167 UNSPEC_TLSDESC))
13168 (parallel
13169 [(set (match_operand:DI 0 "register_operand")
13170 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13171 UNSPEC_TLSDESC))
13172 (clobber (reg:CC FLAGS_REG))])]
13173 "TARGET_64BIT && TARGET_GNU2_TLS"
13174 {
13175 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13176 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13177 })
13178
13179 (define_insn "*tls_dynamic_gnu2_lea_64"
13180 [(set (match_operand:DI 0 "register_operand" "=r")
13181 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13182 UNSPEC_TLSDESC))]
13183 "TARGET_64BIT && TARGET_GNU2_TLS"
13184 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13185 [(set_attr "type" "lea")
13186 (set_attr "mode" "DI")
13187 (set_attr "length" "7")
13188 (set_attr "length_address" "4")])
13189
13190 (define_insn "*tls_dynamic_gnu2_call_64"
13191 [(set (match_operand:DI 0 "register_operand" "=a")
13192 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13193 (match_operand:DI 2 "register_operand" "0")
13194 (reg:DI SP_REG)]
13195 UNSPEC_TLSDESC))
13196 (clobber (reg:CC FLAGS_REG))]
13197 "TARGET_64BIT && TARGET_GNU2_TLS"
13198 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13199 [(set_attr "type" "call")
13200 (set_attr "length" "2")
13201 (set_attr "length_address" "0")])
13202
13203 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13204 [(set (match_operand:DI 0 "register_operand" "=&a")
13205 (plus:DI
13206 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13207 (match_operand:DI 3)
13208 (reg:DI SP_REG)]
13209 UNSPEC_TLSDESC)
13210 (const:DI (unspec:DI
13211 [(match_operand 1 "tls_symbolic_operand")]
13212 UNSPEC_DTPOFF))))
13213 (clobber (reg:CC FLAGS_REG))]
13214 "TARGET_64BIT && TARGET_GNU2_TLS"
13215 "#"
13216 ""
13217 [(set (match_dup 0) (match_dup 4))]
13218 {
13219 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13220 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13221 })
13222 \f
13223 ;; These patterns match the binary 387 instructions for addM3, subM3,
13224 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13225 ;; SFmode. The first is the normal insn, the second the same insn but
13226 ;; with one operand a conversion, and the third the same insn but with
13227 ;; the other operand a conversion. The conversion may be SFmode or
13228 ;; SImode if the target mode DFmode, but only SImode if the target mode
13229 ;; is SFmode.
13230
13231 ;; Gcc is slightly more smart about handling normal two address instructions
13232 ;; so use special patterns for add and mull.
13233
13234 (define_insn "*fop_<mode>_comm_mixed"
13235 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13236 (match_operator:MODEF 3 "binary_fp_operator"
13237 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13238 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13239 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13240 && COMMUTATIVE_ARITH_P (operands[3])
13241 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13242 "* return output_387_binary_op (insn, operands);"
13243 [(set (attr "type")
13244 (if_then_else (eq_attr "alternative" "1,2")
13245 (if_then_else (match_operand:MODEF 3 "mult_operator")
13246 (const_string "ssemul")
13247 (const_string "sseadd"))
13248 (if_then_else (match_operand:MODEF 3 "mult_operator")
13249 (const_string "fmul")
13250 (const_string "fop"))))
13251 (set_attr "isa" "*,noavx,avx")
13252 (set_attr "prefix" "orig,orig,vex")
13253 (set_attr "mode" "<MODE>")])
13254
13255 (define_insn "*fop_<mode>_comm_sse"
13256 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13257 (match_operator:MODEF 3 "binary_fp_operator"
13258 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13259 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13260 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13261 && COMMUTATIVE_ARITH_P (operands[3])
13262 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13263 "* return output_387_binary_op (insn, operands);"
13264 [(set (attr "type")
13265 (if_then_else (match_operand:MODEF 3 "mult_operator")
13266 (const_string "ssemul")
13267 (const_string "sseadd")))
13268 (set_attr "isa" "noavx,avx")
13269 (set_attr "prefix" "orig,vex")
13270 (set_attr "mode" "<MODE>")])
13271
13272 (define_insn "*fop_<mode>_comm_i387"
13273 [(set (match_operand:MODEF 0 "register_operand" "=f")
13274 (match_operator:MODEF 3 "binary_fp_operator"
13275 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13276 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13277 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13278 && COMMUTATIVE_ARITH_P (operands[3])
13279 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13280 "* return output_387_binary_op (insn, operands);"
13281 [(set (attr "type")
13282 (if_then_else (match_operand:MODEF 3 "mult_operator")
13283 (const_string "fmul")
13284 (const_string "fop")))
13285 (set_attr "mode" "<MODE>")])
13286
13287 (define_insn "*fop_<mode>_1_mixed"
13288 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13289 (match_operator:MODEF 3 "binary_fp_operator"
13290 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13291 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13292 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13293 && !COMMUTATIVE_ARITH_P (operands[3])
13294 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13295 "* return output_387_binary_op (insn, operands);"
13296 [(set (attr "type")
13297 (cond [(and (eq_attr "alternative" "2,3")
13298 (match_operand:MODEF 3 "mult_operator"))
13299 (const_string "ssemul")
13300 (and (eq_attr "alternative" "2,3")
13301 (match_operand:MODEF 3 "div_operator"))
13302 (const_string "ssediv")
13303 (eq_attr "alternative" "2,3")
13304 (const_string "sseadd")
13305 (match_operand:MODEF 3 "mult_operator")
13306 (const_string "fmul")
13307 (match_operand:MODEF 3 "div_operator")
13308 (const_string "fdiv")
13309 ]
13310 (const_string "fop")))
13311 (set_attr "isa" "*,*,noavx,avx")
13312 (set_attr "prefix" "orig,orig,orig,vex")
13313 (set_attr "mode" "<MODE>")])
13314
13315 (define_insn "*rcpsf2_sse"
13316 [(set (match_operand:SF 0 "register_operand" "=x")
13317 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13318 UNSPEC_RCP))]
13319 "TARGET_SSE_MATH"
13320 "%vrcpss\t{%1, %d0|%d0, %1}"
13321 [(set_attr "type" "sse")
13322 (set_attr "atom_sse_attr" "rcp")
13323 (set_attr "prefix" "maybe_vex")
13324 (set_attr "mode" "SF")])
13325
13326 (define_insn "*fop_<mode>_1_sse"
13327 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13328 (match_operator:MODEF 3 "binary_fp_operator"
13329 [(match_operand:MODEF 1 "register_operand" "0,x")
13330 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13331 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13332 && !COMMUTATIVE_ARITH_P (operands[3])"
13333 "* return output_387_binary_op (insn, operands);"
13334 [(set (attr "type")
13335 (cond [(match_operand:MODEF 3 "mult_operator")
13336 (const_string "ssemul")
13337 (match_operand:MODEF 3 "div_operator")
13338 (const_string "ssediv")
13339 ]
13340 (const_string "sseadd")))
13341 (set_attr "isa" "noavx,avx")
13342 (set_attr "prefix" "orig,vex")
13343 (set_attr "mode" "<MODE>")])
13344
13345 ;; This pattern is not fully shadowed by the pattern above.
13346 (define_insn "*fop_<mode>_1_i387"
13347 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13348 (match_operator:MODEF 3 "binary_fp_operator"
13349 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13350 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13351 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13352 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13353 && !COMMUTATIVE_ARITH_P (operands[3])
13354 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13355 "* return output_387_binary_op (insn, operands);"
13356 [(set (attr "type")
13357 (cond [(match_operand:MODEF 3 "mult_operator")
13358 (const_string "fmul")
13359 (match_operand:MODEF 3 "div_operator")
13360 (const_string "fdiv")
13361 ]
13362 (const_string "fop")))
13363 (set_attr "mode" "<MODE>")])
13364
13365 ;; ??? Add SSE splitters for these!
13366 (define_insn "*fop_<MODEF:mode>_2_i387"
13367 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13368 (match_operator:MODEF 3 "binary_fp_operator"
13369 [(float:MODEF
13370 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13371 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13372 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13373 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13374 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13375 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13376 [(set (attr "type")
13377 (cond [(match_operand:MODEF 3 "mult_operator")
13378 (const_string "fmul")
13379 (match_operand:MODEF 3 "div_operator")
13380 (const_string "fdiv")
13381 ]
13382 (const_string "fop")))
13383 (set_attr "fp_int_src" "true")
13384 (set_attr "mode" "<SWI24:MODE>")])
13385
13386 (define_insn "*fop_<MODEF:mode>_3_i387"
13387 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13388 (match_operator:MODEF 3 "binary_fp_operator"
13389 [(match_operand:MODEF 1 "register_operand" "0,0")
13390 (float:MODEF
13391 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13392 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13393 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13394 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13395 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13396 [(set (attr "type")
13397 (cond [(match_operand:MODEF 3 "mult_operator")
13398 (const_string "fmul")
13399 (match_operand:MODEF 3 "div_operator")
13400 (const_string "fdiv")
13401 ]
13402 (const_string "fop")))
13403 (set_attr "fp_int_src" "true")
13404 (set_attr "mode" "<MODE>")])
13405
13406 (define_insn "*fop_df_4_i387"
13407 [(set (match_operand:DF 0 "register_operand" "=f,f")
13408 (match_operator:DF 3 "binary_fp_operator"
13409 [(float_extend:DF
13410 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13411 (match_operand:DF 2 "register_operand" "0,f")]))]
13412 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13413 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13414 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13415 "* return output_387_binary_op (insn, operands);"
13416 [(set (attr "type")
13417 (cond [(match_operand:DF 3 "mult_operator")
13418 (const_string "fmul")
13419 (match_operand:DF 3 "div_operator")
13420 (const_string "fdiv")
13421 ]
13422 (const_string "fop")))
13423 (set_attr "mode" "SF")])
13424
13425 (define_insn "*fop_df_5_i387"
13426 [(set (match_operand:DF 0 "register_operand" "=f,f")
13427 (match_operator:DF 3 "binary_fp_operator"
13428 [(match_operand:DF 1 "register_operand" "0,f")
13429 (float_extend:DF
13430 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13431 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13432 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13433 "* return output_387_binary_op (insn, operands);"
13434 [(set (attr "type")
13435 (cond [(match_operand:DF 3 "mult_operator")
13436 (const_string "fmul")
13437 (match_operand:DF 3 "div_operator")
13438 (const_string "fdiv")
13439 ]
13440 (const_string "fop")))
13441 (set_attr "mode" "SF")])
13442
13443 (define_insn "*fop_df_6_i387"
13444 [(set (match_operand:DF 0 "register_operand" "=f,f")
13445 (match_operator:DF 3 "binary_fp_operator"
13446 [(float_extend:DF
13447 (match_operand:SF 1 "register_operand" "0,f"))
13448 (float_extend:DF
13449 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13450 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13451 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13452 "* return output_387_binary_op (insn, operands);"
13453 [(set (attr "type")
13454 (cond [(match_operand:DF 3 "mult_operator")
13455 (const_string "fmul")
13456 (match_operand:DF 3 "div_operator")
13457 (const_string "fdiv")
13458 ]
13459 (const_string "fop")))
13460 (set_attr "mode" "SF")])
13461
13462 (define_insn "*fop_xf_comm_i387"
13463 [(set (match_operand:XF 0 "register_operand" "=f")
13464 (match_operator:XF 3 "binary_fp_operator"
13465 [(match_operand:XF 1 "register_operand" "%0")
13466 (match_operand:XF 2 "register_operand" "f")]))]
13467 "TARGET_80387
13468 && COMMUTATIVE_ARITH_P (operands[3])"
13469 "* return output_387_binary_op (insn, operands);"
13470 [(set (attr "type")
13471 (if_then_else (match_operand:XF 3 "mult_operator")
13472 (const_string "fmul")
13473 (const_string "fop")))
13474 (set_attr "mode" "XF")])
13475
13476 (define_insn "*fop_xf_1_i387"
13477 [(set (match_operand:XF 0 "register_operand" "=f,f")
13478 (match_operator:XF 3 "binary_fp_operator"
13479 [(match_operand:XF 1 "register_operand" "0,f")
13480 (match_operand:XF 2 "register_operand" "f,0")]))]
13481 "TARGET_80387
13482 && !COMMUTATIVE_ARITH_P (operands[3])"
13483 "* return output_387_binary_op (insn, operands);"
13484 [(set (attr "type")
13485 (cond [(match_operand:XF 3 "mult_operator")
13486 (const_string "fmul")
13487 (match_operand:XF 3 "div_operator")
13488 (const_string "fdiv")
13489 ]
13490 (const_string "fop")))
13491 (set_attr "mode" "XF")])
13492
13493 (define_insn "*fop_xf_2_i387"
13494 [(set (match_operand:XF 0 "register_operand" "=f,f")
13495 (match_operator:XF 3 "binary_fp_operator"
13496 [(float:XF
13497 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13498 (match_operand:XF 2 "register_operand" "0,0")]))]
13499 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13500 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13501 [(set (attr "type")
13502 (cond [(match_operand:XF 3 "mult_operator")
13503 (const_string "fmul")
13504 (match_operand:XF 3 "div_operator")
13505 (const_string "fdiv")
13506 ]
13507 (const_string "fop")))
13508 (set_attr "fp_int_src" "true")
13509 (set_attr "mode" "<MODE>")])
13510
13511 (define_insn "*fop_xf_3_i387"
13512 [(set (match_operand:XF 0 "register_operand" "=f,f")
13513 (match_operator:XF 3 "binary_fp_operator"
13514 [(match_operand:XF 1 "register_operand" "0,0")
13515 (float:XF
13516 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13517 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13518 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13519 [(set (attr "type")
13520 (cond [(match_operand:XF 3 "mult_operator")
13521 (const_string "fmul")
13522 (match_operand:XF 3 "div_operator")
13523 (const_string "fdiv")
13524 ]
13525 (const_string "fop")))
13526 (set_attr "fp_int_src" "true")
13527 (set_attr "mode" "<MODE>")])
13528
13529 (define_insn "*fop_xf_4_i387"
13530 [(set (match_operand:XF 0 "register_operand" "=f,f")
13531 (match_operator:XF 3 "binary_fp_operator"
13532 [(float_extend:XF
13533 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13534 (match_operand:XF 2 "register_operand" "0,f")]))]
13535 "TARGET_80387"
13536 "* return output_387_binary_op (insn, operands);"
13537 [(set (attr "type")
13538 (cond [(match_operand:XF 3 "mult_operator")
13539 (const_string "fmul")
13540 (match_operand:XF 3 "div_operator")
13541 (const_string "fdiv")
13542 ]
13543 (const_string "fop")))
13544 (set_attr "mode" "<MODE>")])
13545
13546 (define_insn "*fop_xf_5_i387"
13547 [(set (match_operand:XF 0 "register_operand" "=f,f")
13548 (match_operator:XF 3 "binary_fp_operator"
13549 [(match_operand:XF 1 "register_operand" "0,f")
13550 (float_extend:XF
13551 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13552 "TARGET_80387"
13553 "* return output_387_binary_op (insn, operands);"
13554 [(set (attr "type")
13555 (cond [(match_operand:XF 3 "mult_operator")
13556 (const_string "fmul")
13557 (match_operand:XF 3 "div_operator")
13558 (const_string "fdiv")
13559 ]
13560 (const_string "fop")))
13561 (set_attr "mode" "<MODE>")])
13562
13563 (define_insn "*fop_xf_6_i387"
13564 [(set (match_operand:XF 0 "register_operand" "=f,f")
13565 (match_operator:XF 3 "binary_fp_operator"
13566 [(float_extend:XF
13567 (match_operand:MODEF 1 "register_operand" "0,f"))
13568 (float_extend:XF
13569 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13570 "TARGET_80387"
13571 "* return output_387_binary_op (insn, operands);"
13572 [(set (attr "type")
13573 (cond [(match_operand:XF 3 "mult_operator")
13574 (const_string "fmul")
13575 (match_operand:XF 3 "div_operator")
13576 (const_string "fdiv")
13577 ]
13578 (const_string "fop")))
13579 (set_attr "mode" "<MODE>")])
13580
13581 (define_split
13582 [(set (match_operand 0 "register_operand")
13583 (match_operator 3 "binary_fp_operator"
13584 [(float (match_operand:SWI24 1 "register_operand"))
13585 (match_operand 2 "register_operand")]))]
13586 "reload_completed
13587 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13588 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13589 [(const_int 0)]
13590 {
13591 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13592 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13593 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13594 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13595 GET_MODE (operands[3]),
13596 operands[4],
13597 operands[2])));
13598 ix86_free_from_memory (GET_MODE (operands[1]));
13599 DONE;
13600 })
13601
13602 (define_split
13603 [(set (match_operand 0 "register_operand")
13604 (match_operator 3 "binary_fp_operator"
13605 [(match_operand 1 "register_operand")
13606 (float (match_operand:SWI24 2 "register_operand"))]))]
13607 "reload_completed
13608 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13609 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13610 [(const_int 0)]
13611 {
13612 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13613 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13614 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13615 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13616 GET_MODE (operands[3]),
13617 operands[1],
13618 operands[4])));
13619 ix86_free_from_memory (GET_MODE (operands[2]));
13620 DONE;
13621 })
13622 \f
13623 ;; FPU special functions.
13624
13625 ;; This pattern implements a no-op XFmode truncation for
13626 ;; all fancy i386 XFmode math functions.
13627
13628 (define_insn "truncxf<mode>2_i387_noop_unspec"
13629 [(set (match_operand:MODEF 0 "register_operand" "=f")
13630 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13631 UNSPEC_TRUNC_NOOP))]
13632 "TARGET_USE_FANCY_MATH_387"
13633 "* return output_387_reg_move (insn, operands);"
13634 [(set_attr "type" "fmov")
13635 (set_attr "mode" "<MODE>")])
13636
13637 (define_insn "sqrtxf2"
13638 [(set (match_operand:XF 0 "register_operand" "=f")
13639 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13640 "TARGET_USE_FANCY_MATH_387"
13641 "fsqrt"
13642 [(set_attr "type" "fpspc")
13643 (set_attr "mode" "XF")
13644 (set_attr "athlon_decode" "direct")
13645 (set_attr "amdfam10_decode" "direct")
13646 (set_attr "bdver1_decode" "direct")])
13647
13648 (define_insn "sqrt_extend<mode>xf2_i387"
13649 [(set (match_operand:XF 0 "register_operand" "=f")
13650 (sqrt:XF
13651 (float_extend:XF
13652 (match_operand:MODEF 1 "register_operand" "0"))))]
13653 "TARGET_USE_FANCY_MATH_387"
13654 "fsqrt"
13655 [(set_attr "type" "fpspc")
13656 (set_attr "mode" "XF")
13657 (set_attr "athlon_decode" "direct")
13658 (set_attr "amdfam10_decode" "direct")
13659 (set_attr "bdver1_decode" "direct")])
13660
13661 (define_insn "*rsqrtsf2_sse"
13662 [(set (match_operand:SF 0 "register_operand" "=x")
13663 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13664 UNSPEC_RSQRT))]
13665 "TARGET_SSE_MATH"
13666 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13667 [(set_attr "type" "sse")
13668 (set_attr "atom_sse_attr" "rcp")
13669 (set_attr "prefix" "maybe_vex")
13670 (set_attr "mode" "SF")])
13671
13672 (define_expand "rsqrtsf2"
13673 [(set (match_operand:SF 0 "register_operand")
13674 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13675 UNSPEC_RSQRT))]
13676 "TARGET_SSE_MATH"
13677 {
13678 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13679 DONE;
13680 })
13681
13682 (define_insn "*sqrt<mode>2_sse"
13683 [(set (match_operand:MODEF 0 "register_operand" "=x")
13684 (sqrt:MODEF
13685 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13686 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13687 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13688 [(set_attr "type" "sse")
13689 (set_attr "atom_sse_attr" "sqrt")
13690 (set_attr "prefix" "maybe_vex")
13691 (set_attr "mode" "<MODE>")
13692 (set_attr "athlon_decode" "*")
13693 (set_attr "amdfam10_decode" "*")
13694 (set_attr "bdver1_decode" "*")])
13695
13696 (define_expand "sqrt<mode>2"
13697 [(set (match_operand:MODEF 0 "register_operand")
13698 (sqrt:MODEF
13699 (match_operand:MODEF 1 "nonimmediate_operand")))]
13700 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13701 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13702 {
13703 if (<MODE>mode == SFmode
13704 && TARGET_SSE_MATH
13705 && TARGET_RECIP_SQRT
13706 && !optimize_function_for_size_p (cfun)
13707 && flag_finite_math_only && !flag_trapping_math
13708 && flag_unsafe_math_optimizations)
13709 {
13710 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13711 DONE;
13712 }
13713
13714 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13715 {
13716 rtx op0 = gen_reg_rtx (XFmode);
13717 rtx op1 = force_reg (<MODE>mode, operands[1]);
13718
13719 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13720 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13721 DONE;
13722 }
13723 })
13724
13725 (define_insn "fpremxf4_i387"
13726 [(set (match_operand:XF 0 "register_operand" "=f")
13727 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13728 (match_operand:XF 3 "register_operand" "1")]
13729 UNSPEC_FPREM_F))
13730 (set (match_operand:XF 1 "register_operand" "=u")
13731 (unspec:XF [(match_dup 2) (match_dup 3)]
13732 UNSPEC_FPREM_U))
13733 (set (reg:CCFP FPSR_REG)
13734 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13735 UNSPEC_C2_FLAG))]
13736 "TARGET_USE_FANCY_MATH_387"
13737 "fprem"
13738 [(set_attr "type" "fpspc")
13739 (set_attr "mode" "XF")])
13740
13741 (define_expand "fmodxf3"
13742 [(use (match_operand:XF 0 "register_operand"))
13743 (use (match_operand:XF 1 "general_operand"))
13744 (use (match_operand:XF 2 "general_operand"))]
13745 "TARGET_USE_FANCY_MATH_387"
13746 {
13747 rtx label = gen_label_rtx ();
13748
13749 rtx op1 = gen_reg_rtx (XFmode);
13750 rtx op2 = gen_reg_rtx (XFmode);
13751
13752 emit_move_insn (op2, operands[2]);
13753 emit_move_insn (op1, operands[1]);
13754
13755 emit_label (label);
13756 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13757 ix86_emit_fp_unordered_jump (label);
13758 LABEL_NUSES (label) = 1;
13759
13760 emit_move_insn (operands[0], op1);
13761 DONE;
13762 })
13763
13764 (define_expand "fmod<mode>3"
13765 [(use (match_operand:MODEF 0 "register_operand"))
13766 (use (match_operand:MODEF 1 "general_operand"))
13767 (use (match_operand:MODEF 2 "general_operand"))]
13768 "TARGET_USE_FANCY_MATH_387"
13769 {
13770 rtx (*gen_truncxf) (rtx, rtx);
13771
13772 rtx label = gen_label_rtx ();
13773
13774 rtx op1 = gen_reg_rtx (XFmode);
13775 rtx op2 = gen_reg_rtx (XFmode);
13776
13777 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13778 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13779
13780 emit_label (label);
13781 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13782 ix86_emit_fp_unordered_jump (label);
13783 LABEL_NUSES (label) = 1;
13784
13785 /* Truncate the result properly for strict SSE math. */
13786 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13787 && !TARGET_MIX_SSE_I387)
13788 gen_truncxf = gen_truncxf<mode>2;
13789 else
13790 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13791
13792 emit_insn (gen_truncxf (operands[0], op1));
13793 DONE;
13794 })
13795
13796 (define_insn "fprem1xf4_i387"
13797 [(set (match_operand:XF 0 "register_operand" "=f")
13798 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13799 (match_operand:XF 3 "register_operand" "1")]
13800 UNSPEC_FPREM1_F))
13801 (set (match_operand:XF 1 "register_operand" "=u")
13802 (unspec:XF [(match_dup 2) (match_dup 3)]
13803 UNSPEC_FPREM1_U))
13804 (set (reg:CCFP FPSR_REG)
13805 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13806 UNSPEC_C2_FLAG))]
13807 "TARGET_USE_FANCY_MATH_387"
13808 "fprem1"
13809 [(set_attr "type" "fpspc")
13810 (set_attr "mode" "XF")])
13811
13812 (define_expand "remainderxf3"
13813 [(use (match_operand:XF 0 "register_operand"))
13814 (use (match_operand:XF 1 "general_operand"))
13815 (use (match_operand:XF 2 "general_operand"))]
13816 "TARGET_USE_FANCY_MATH_387"
13817 {
13818 rtx label = gen_label_rtx ();
13819
13820 rtx op1 = gen_reg_rtx (XFmode);
13821 rtx op2 = gen_reg_rtx (XFmode);
13822
13823 emit_move_insn (op2, operands[2]);
13824 emit_move_insn (op1, operands[1]);
13825
13826 emit_label (label);
13827 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13828 ix86_emit_fp_unordered_jump (label);
13829 LABEL_NUSES (label) = 1;
13830
13831 emit_move_insn (operands[0], op1);
13832 DONE;
13833 })
13834
13835 (define_expand "remainder<mode>3"
13836 [(use (match_operand:MODEF 0 "register_operand"))
13837 (use (match_operand:MODEF 1 "general_operand"))
13838 (use (match_operand:MODEF 2 "general_operand"))]
13839 "TARGET_USE_FANCY_MATH_387"
13840 {
13841 rtx (*gen_truncxf) (rtx, rtx);
13842
13843 rtx label = gen_label_rtx ();
13844
13845 rtx op1 = gen_reg_rtx (XFmode);
13846 rtx op2 = gen_reg_rtx (XFmode);
13847
13848 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13849 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13850
13851 emit_label (label);
13852
13853 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13854 ix86_emit_fp_unordered_jump (label);
13855 LABEL_NUSES (label) = 1;
13856
13857 /* Truncate the result properly for strict SSE math. */
13858 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13859 && !TARGET_MIX_SSE_I387)
13860 gen_truncxf = gen_truncxf<mode>2;
13861 else
13862 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13863
13864 emit_insn (gen_truncxf (operands[0], op1));
13865 DONE;
13866 })
13867
13868 (define_int_iterator SINCOS
13869 [UNSPEC_SIN
13870 UNSPEC_COS])
13871
13872 (define_int_attr sincos
13873 [(UNSPEC_SIN "sin")
13874 (UNSPEC_COS "cos")])
13875
13876 (define_insn "*<sincos>xf2_i387"
13877 [(set (match_operand:XF 0 "register_operand" "=f")
13878 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13879 SINCOS))]
13880 "TARGET_USE_FANCY_MATH_387
13881 && flag_unsafe_math_optimizations"
13882 "f<sincos>"
13883 [(set_attr "type" "fpspc")
13884 (set_attr "mode" "XF")])
13885
13886 (define_insn "*<sincos>_extend<mode>xf2_i387"
13887 [(set (match_operand:XF 0 "register_operand" "=f")
13888 (unspec:XF [(float_extend:XF
13889 (match_operand:MODEF 1 "register_operand" "0"))]
13890 SINCOS))]
13891 "TARGET_USE_FANCY_MATH_387
13892 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13893 || TARGET_MIX_SSE_I387)
13894 && flag_unsafe_math_optimizations"
13895 "f<sincos>"
13896 [(set_attr "type" "fpspc")
13897 (set_attr "mode" "XF")])
13898
13899 ;; When sincos pattern is defined, sin and cos builtin functions will be
13900 ;; expanded to sincos pattern with one of its outputs left unused.
13901 ;; CSE pass will figure out if two sincos patterns can be combined,
13902 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13903 ;; depending on the unused output.
13904
13905 (define_insn "sincosxf3"
13906 [(set (match_operand:XF 0 "register_operand" "=f")
13907 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13908 UNSPEC_SINCOS_COS))
13909 (set (match_operand:XF 1 "register_operand" "=u")
13910 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13911 "TARGET_USE_FANCY_MATH_387
13912 && flag_unsafe_math_optimizations"
13913 "fsincos"
13914 [(set_attr "type" "fpspc")
13915 (set_attr "mode" "XF")])
13916
13917 (define_split
13918 [(set (match_operand:XF 0 "register_operand")
13919 (unspec:XF [(match_operand:XF 2 "register_operand")]
13920 UNSPEC_SINCOS_COS))
13921 (set (match_operand:XF 1 "register_operand")
13922 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13923 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13924 && can_create_pseudo_p ()"
13925 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13926
13927 (define_split
13928 [(set (match_operand:XF 0 "register_operand")
13929 (unspec:XF [(match_operand:XF 2 "register_operand")]
13930 UNSPEC_SINCOS_COS))
13931 (set (match_operand:XF 1 "register_operand")
13932 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13933 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13934 && can_create_pseudo_p ()"
13935 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13936
13937 (define_insn "sincos_extend<mode>xf3_i387"
13938 [(set (match_operand:XF 0 "register_operand" "=f")
13939 (unspec:XF [(float_extend:XF
13940 (match_operand:MODEF 2 "register_operand" "0"))]
13941 UNSPEC_SINCOS_COS))
13942 (set (match_operand:XF 1 "register_operand" "=u")
13943 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13944 "TARGET_USE_FANCY_MATH_387
13945 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13946 || TARGET_MIX_SSE_I387)
13947 && flag_unsafe_math_optimizations"
13948 "fsincos"
13949 [(set_attr "type" "fpspc")
13950 (set_attr "mode" "XF")])
13951
13952 (define_split
13953 [(set (match_operand:XF 0 "register_operand")
13954 (unspec:XF [(float_extend:XF
13955 (match_operand:MODEF 2 "register_operand"))]
13956 UNSPEC_SINCOS_COS))
13957 (set (match_operand:XF 1 "register_operand")
13958 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13959 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13960 && can_create_pseudo_p ()"
13961 [(set (match_dup 1)
13962 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13963
13964 (define_split
13965 [(set (match_operand:XF 0 "register_operand")
13966 (unspec:XF [(float_extend:XF
13967 (match_operand:MODEF 2 "register_operand"))]
13968 UNSPEC_SINCOS_COS))
13969 (set (match_operand:XF 1 "register_operand")
13970 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13971 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13972 && can_create_pseudo_p ()"
13973 [(set (match_dup 0)
13974 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13975
13976 (define_expand "sincos<mode>3"
13977 [(use (match_operand:MODEF 0 "register_operand"))
13978 (use (match_operand:MODEF 1 "register_operand"))
13979 (use (match_operand:MODEF 2 "register_operand"))]
13980 "TARGET_USE_FANCY_MATH_387
13981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13982 || TARGET_MIX_SSE_I387)
13983 && flag_unsafe_math_optimizations"
13984 {
13985 rtx op0 = gen_reg_rtx (XFmode);
13986 rtx op1 = gen_reg_rtx (XFmode);
13987
13988 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13989 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13990 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13991 DONE;
13992 })
13993
13994 (define_insn "fptanxf4_i387"
13995 [(set (match_operand:XF 0 "register_operand" "=f")
13996 (match_operand:XF 3 "const_double_operand" "F"))
13997 (set (match_operand:XF 1 "register_operand" "=u")
13998 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13999 UNSPEC_TAN))]
14000 "TARGET_USE_FANCY_MATH_387
14001 && flag_unsafe_math_optimizations
14002 && standard_80387_constant_p (operands[3]) == 2"
14003 "fptan"
14004 [(set_attr "type" "fpspc")
14005 (set_attr "mode" "XF")])
14006
14007 (define_insn "fptan_extend<mode>xf4_i387"
14008 [(set (match_operand:MODEF 0 "register_operand" "=f")
14009 (match_operand:MODEF 3 "const_double_operand" "F"))
14010 (set (match_operand:XF 1 "register_operand" "=u")
14011 (unspec:XF [(float_extend:XF
14012 (match_operand:MODEF 2 "register_operand" "0"))]
14013 UNSPEC_TAN))]
14014 "TARGET_USE_FANCY_MATH_387
14015 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14016 || TARGET_MIX_SSE_I387)
14017 && flag_unsafe_math_optimizations
14018 && standard_80387_constant_p (operands[3]) == 2"
14019 "fptan"
14020 [(set_attr "type" "fpspc")
14021 (set_attr "mode" "XF")])
14022
14023 (define_expand "tanxf2"
14024 [(use (match_operand:XF 0 "register_operand"))
14025 (use (match_operand:XF 1 "register_operand"))]
14026 "TARGET_USE_FANCY_MATH_387
14027 && flag_unsafe_math_optimizations"
14028 {
14029 rtx one = gen_reg_rtx (XFmode);
14030 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14031
14032 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14033 DONE;
14034 })
14035
14036 (define_expand "tan<mode>2"
14037 [(use (match_operand:MODEF 0 "register_operand"))
14038 (use (match_operand:MODEF 1 "register_operand"))]
14039 "TARGET_USE_FANCY_MATH_387
14040 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14041 || TARGET_MIX_SSE_I387)
14042 && flag_unsafe_math_optimizations"
14043 {
14044 rtx op0 = gen_reg_rtx (XFmode);
14045
14046 rtx one = gen_reg_rtx (<MODE>mode);
14047 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14048
14049 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14050 operands[1], op2));
14051 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14052 DONE;
14053 })
14054
14055 (define_insn "*fpatanxf3_i387"
14056 [(set (match_operand:XF 0 "register_operand" "=f")
14057 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14058 (match_operand:XF 2 "register_operand" "u")]
14059 UNSPEC_FPATAN))
14060 (clobber (match_scratch:XF 3 "=2"))]
14061 "TARGET_USE_FANCY_MATH_387
14062 && flag_unsafe_math_optimizations"
14063 "fpatan"
14064 [(set_attr "type" "fpspc")
14065 (set_attr "mode" "XF")])
14066
14067 (define_insn "fpatan_extend<mode>xf3_i387"
14068 [(set (match_operand:XF 0 "register_operand" "=f")
14069 (unspec:XF [(float_extend:XF
14070 (match_operand:MODEF 1 "register_operand" "0"))
14071 (float_extend:XF
14072 (match_operand:MODEF 2 "register_operand" "u"))]
14073 UNSPEC_FPATAN))
14074 (clobber (match_scratch:XF 3 "=2"))]
14075 "TARGET_USE_FANCY_MATH_387
14076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14077 || TARGET_MIX_SSE_I387)
14078 && flag_unsafe_math_optimizations"
14079 "fpatan"
14080 [(set_attr "type" "fpspc")
14081 (set_attr "mode" "XF")])
14082
14083 (define_expand "atan2xf3"
14084 [(parallel [(set (match_operand:XF 0 "register_operand")
14085 (unspec:XF [(match_operand:XF 2 "register_operand")
14086 (match_operand:XF 1 "register_operand")]
14087 UNSPEC_FPATAN))
14088 (clobber (match_scratch:XF 3))])]
14089 "TARGET_USE_FANCY_MATH_387
14090 && flag_unsafe_math_optimizations")
14091
14092 (define_expand "atan2<mode>3"
14093 [(use (match_operand:MODEF 0 "register_operand"))
14094 (use (match_operand:MODEF 1 "register_operand"))
14095 (use (match_operand:MODEF 2 "register_operand"))]
14096 "TARGET_USE_FANCY_MATH_387
14097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14098 || TARGET_MIX_SSE_I387)
14099 && flag_unsafe_math_optimizations"
14100 {
14101 rtx op0 = gen_reg_rtx (XFmode);
14102
14103 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14104 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14105 DONE;
14106 })
14107
14108 (define_expand "atanxf2"
14109 [(parallel [(set (match_operand:XF 0 "register_operand")
14110 (unspec:XF [(match_dup 2)
14111 (match_operand:XF 1 "register_operand")]
14112 UNSPEC_FPATAN))
14113 (clobber (match_scratch:XF 3))])]
14114 "TARGET_USE_FANCY_MATH_387
14115 && flag_unsafe_math_optimizations"
14116 {
14117 operands[2] = gen_reg_rtx (XFmode);
14118 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14119 })
14120
14121 (define_expand "atan<mode>2"
14122 [(use (match_operand:MODEF 0 "register_operand"))
14123 (use (match_operand:MODEF 1 "register_operand"))]
14124 "TARGET_USE_FANCY_MATH_387
14125 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14126 || TARGET_MIX_SSE_I387)
14127 && flag_unsafe_math_optimizations"
14128 {
14129 rtx op0 = gen_reg_rtx (XFmode);
14130
14131 rtx op2 = gen_reg_rtx (<MODE>mode);
14132 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14133
14134 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14135 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14136 DONE;
14137 })
14138
14139 (define_expand "asinxf2"
14140 [(set (match_dup 2)
14141 (mult:XF (match_operand:XF 1 "register_operand")
14142 (match_dup 1)))
14143 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14144 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14145 (parallel [(set (match_operand:XF 0 "register_operand")
14146 (unspec:XF [(match_dup 5) (match_dup 1)]
14147 UNSPEC_FPATAN))
14148 (clobber (match_scratch:XF 6))])]
14149 "TARGET_USE_FANCY_MATH_387
14150 && flag_unsafe_math_optimizations"
14151 {
14152 int i;
14153
14154 if (optimize_insn_for_size_p ())
14155 FAIL;
14156
14157 for (i = 2; i < 6; i++)
14158 operands[i] = gen_reg_rtx (XFmode);
14159
14160 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14161 })
14162
14163 (define_expand "asin<mode>2"
14164 [(use (match_operand:MODEF 0 "register_operand"))
14165 (use (match_operand:MODEF 1 "general_operand"))]
14166 "TARGET_USE_FANCY_MATH_387
14167 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14168 || TARGET_MIX_SSE_I387)
14169 && flag_unsafe_math_optimizations"
14170 {
14171 rtx op0 = gen_reg_rtx (XFmode);
14172 rtx op1 = gen_reg_rtx (XFmode);
14173
14174 if (optimize_insn_for_size_p ())
14175 FAIL;
14176
14177 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14178 emit_insn (gen_asinxf2 (op0, op1));
14179 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14180 DONE;
14181 })
14182
14183 (define_expand "acosxf2"
14184 [(set (match_dup 2)
14185 (mult:XF (match_operand:XF 1 "register_operand")
14186 (match_dup 1)))
14187 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14188 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14189 (parallel [(set (match_operand:XF 0 "register_operand")
14190 (unspec:XF [(match_dup 1) (match_dup 5)]
14191 UNSPEC_FPATAN))
14192 (clobber (match_scratch:XF 6))])]
14193 "TARGET_USE_FANCY_MATH_387
14194 && flag_unsafe_math_optimizations"
14195 {
14196 int i;
14197
14198 if (optimize_insn_for_size_p ())
14199 FAIL;
14200
14201 for (i = 2; i < 6; i++)
14202 operands[i] = gen_reg_rtx (XFmode);
14203
14204 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14205 })
14206
14207 (define_expand "acos<mode>2"
14208 [(use (match_operand:MODEF 0 "register_operand"))
14209 (use (match_operand:MODEF 1 "general_operand"))]
14210 "TARGET_USE_FANCY_MATH_387
14211 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14212 || TARGET_MIX_SSE_I387)
14213 && flag_unsafe_math_optimizations"
14214 {
14215 rtx op0 = gen_reg_rtx (XFmode);
14216 rtx op1 = gen_reg_rtx (XFmode);
14217
14218 if (optimize_insn_for_size_p ())
14219 FAIL;
14220
14221 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14222 emit_insn (gen_acosxf2 (op0, op1));
14223 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14224 DONE;
14225 })
14226
14227 (define_insn "fyl2xxf3_i387"
14228 [(set (match_operand:XF 0 "register_operand" "=f")
14229 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14230 (match_operand:XF 2 "register_operand" "u")]
14231 UNSPEC_FYL2X))
14232 (clobber (match_scratch:XF 3 "=2"))]
14233 "TARGET_USE_FANCY_MATH_387
14234 && flag_unsafe_math_optimizations"
14235 "fyl2x"
14236 [(set_attr "type" "fpspc")
14237 (set_attr "mode" "XF")])
14238
14239 (define_insn "fyl2x_extend<mode>xf3_i387"
14240 [(set (match_operand:XF 0 "register_operand" "=f")
14241 (unspec:XF [(float_extend:XF
14242 (match_operand:MODEF 1 "register_operand" "0"))
14243 (match_operand:XF 2 "register_operand" "u")]
14244 UNSPEC_FYL2X))
14245 (clobber (match_scratch:XF 3 "=2"))]
14246 "TARGET_USE_FANCY_MATH_387
14247 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14248 || TARGET_MIX_SSE_I387)
14249 && flag_unsafe_math_optimizations"
14250 "fyl2x"
14251 [(set_attr "type" "fpspc")
14252 (set_attr "mode" "XF")])
14253
14254 (define_expand "logxf2"
14255 [(parallel [(set (match_operand:XF 0 "register_operand")
14256 (unspec:XF [(match_operand:XF 1 "register_operand")
14257 (match_dup 2)] UNSPEC_FYL2X))
14258 (clobber (match_scratch:XF 3))])]
14259 "TARGET_USE_FANCY_MATH_387
14260 && flag_unsafe_math_optimizations"
14261 {
14262 operands[2] = gen_reg_rtx (XFmode);
14263 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14264 })
14265
14266 (define_expand "log<mode>2"
14267 [(use (match_operand:MODEF 0 "register_operand"))
14268 (use (match_operand:MODEF 1 "register_operand"))]
14269 "TARGET_USE_FANCY_MATH_387
14270 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14271 || TARGET_MIX_SSE_I387)
14272 && flag_unsafe_math_optimizations"
14273 {
14274 rtx op0 = gen_reg_rtx (XFmode);
14275
14276 rtx op2 = gen_reg_rtx (XFmode);
14277 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14278
14279 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14280 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14281 DONE;
14282 })
14283
14284 (define_expand "log10xf2"
14285 [(parallel [(set (match_operand:XF 0 "register_operand")
14286 (unspec:XF [(match_operand:XF 1 "register_operand")
14287 (match_dup 2)] UNSPEC_FYL2X))
14288 (clobber (match_scratch:XF 3))])]
14289 "TARGET_USE_FANCY_MATH_387
14290 && flag_unsafe_math_optimizations"
14291 {
14292 operands[2] = gen_reg_rtx (XFmode);
14293 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14294 })
14295
14296 (define_expand "log10<mode>2"
14297 [(use (match_operand:MODEF 0 "register_operand"))
14298 (use (match_operand:MODEF 1 "register_operand"))]
14299 "TARGET_USE_FANCY_MATH_387
14300 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14301 || TARGET_MIX_SSE_I387)
14302 && flag_unsafe_math_optimizations"
14303 {
14304 rtx op0 = gen_reg_rtx (XFmode);
14305
14306 rtx op2 = gen_reg_rtx (XFmode);
14307 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14308
14309 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14310 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14311 DONE;
14312 })
14313
14314 (define_expand "log2xf2"
14315 [(parallel [(set (match_operand:XF 0 "register_operand")
14316 (unspec:XF [(match_operand:XF 1 "register_operand")
14317 (match_dup 2)] UNSPEC_FYL2X))
14318 (clobber (match_scratch:XF 3))])]
14319 "TARGET_USE_FANCY_MATH_387
14320 && flag_unsafe_math_optimizations"
14321 {
14322 operands[2] = gen_reg_rtx (XFmode);
14323 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14324 })
14325
14326 (define_expand "log2<mode>2"
14327 [(use (match_operand:MODEF 0 "register_operand"))
14328 (use (match_operand:MODEF 1 "register_operand"))]
14329 "TARGET_USE_FANCY_MATH_387
14330 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14331 || TARGET_MIX_SSE_I387)
14332 && flag_unsafe_math_optimizations"
14333 {
14334 rtx op0 = gen_reg_rtx (XFmode);
14335
14336 rtx op2 = gen_reg_rtx (XFmode);
14337 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14338
14339 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14340 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14341 DONE;
14342 })
14343
14344 (define_insn "fyl2xp1xf3_i387"
14345 [(set (match_operand:XF 0 "register_operand" "=f")
14346 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14347 (match_operand:XF 2 "register_operand" "u")]
14348 UNSPEC_FYL2XP1))
14349 (clobber (match_scratch:XF 3 "=2"))]
14350 "TARGET_USE_FANCY_MATH_387
14351 && flag_unsafe_math_optimizations"
14352 "fyl2xp1"
14353 [(set_attr "type" "fpspc")
14354 (set_attr "mode" "XF")])
14355
14356 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14357 [(set (match_operand:XF 0 "register_operand" "=f")
14358 (unspec:XF [(float_extend:XF
14359 (match_operand:MODEF 1 "register_operand" "0"))
14360 (match_operand:XF 2 "register_operand" "u")]
14361 UNSPEC_FYL2XP1))
14362 (clobber (match_scratch:XF 3 "=2"))]
14363 "TARGET_USE_FANCY_MATH_387
14364 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14365 || TARGET_MIX_SSE_I387)
14366 && flag_unsafe_math_optimizations"
14367 "fyl2xp1"
14368 [(set_attr "type" "fpspc")
14369 (set_attr "mode" "XF")])
14370
14371 (define_expand "log1pxf2"
14372 [(use (match_operand:XF 0 "register_operand"))
14373 (use (match_operand:XF 1 "register_operand"))]
14374 "TARGET_USE_FANCY_MATH_387
14375 && flag_unsafe_math_optimizations"
14376 {
14377 if (optimize_insn_for_size_p ())
14378 FAIL;
14379
14380 ix86_emit_i387_log1p (operands[0], operands[1]);
14381 DONE;
14382 })
14383
14384 (define_expand "log1p<mode>2"
14385 [(use (match_operand:MODEF 0 "register_operand"))
14386 (use (match_operand:MODEF 1 "register_operand"))]
14387 "TARGET_USE_FANCY_MATH_387
14388 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14389 || TARGET_MIX_SSE_I387)
14390 && flag_unsafe_math_optimizations"
14391 {
14392 rtx op0;
14393
14394 if (optimize_insn_for_size_p ())
14395 FAIL;
14396
14397 op0 = gen_reg_rtx (XFmode);
14398
14399 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14400
14401 ix86_emit_i387_log1p (op0, operands[1]);
14402 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14403 DONE;
14404 })
14405
14406 (define_insn "fxtractxf3_i387"
14407 [(set (match_operand:XF 0 "register_operand" "=f")
14408 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14409 UNSPEC_XTRACT_FRACT))
14410 (set (match_operand:XF 1 "register_operand" "=u")
14411 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14412 "TARGET_USE_FANCY_MATH_387
14413 && flag_unsafe_math_optimizations"
14414 "fxtract"
14415 [(set_attr "type" "fpspc")
14416 (set_attr "mode" "XF")])
14417
14418 (define_insn "fxtract_extend<mode>xf3_i387"
14419 [(set (match_operand:XF 0 "register_operand" "=f")
14420 (unspec:XF [(float_extend:XF
14421 (match_operand:MODEF 2 "register_operand" "0"))]
14422 UNSPEC_XTRACT_FRACT))
14423 (set (match_operand:XF 1 "register_operand" "=u")
14424 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14425 "TARGET_USE_FANCY_MATH_387
14426 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14427 || TARGET_MIX_SSE_I387)
14428 && flag_unsafe_math_optimizations"
14429 "fxtract"
14430 [(set_attr "type" "fpspc")
14431 (set_attr "mode" "XF")])
14432
14433 (define_expand "logbxf2"
14434 [(parallel [(set (match_dup 2)
14435 (unspec:XF [(match_operand:XF 1 "register_operand")]
14436 UNSPEC_XTRACT_FRACT))
14437 (set (match_operand:XF 0 "register_operand")
14438 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14439 "TARGET_USE_FANCY_MATH_387
14440 && flag_unsafe_math_optimizations"
14441 "operands[2] = gen_reg_rtx (XFmode);")
14442
14443 (define_expand "logb<mode>2"
14444 [(use (match_operand:MODEF 0 "register_operand"))
14445 (use (match_operand:MODEF 1 "register_operand"))]
14446 "TARGET_USE_FANCY_MATH_387
14447 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14448 || TARGET_MIX_SSE_I387)
14449 && flag_unsafe_math_optimizations"
14450 {
14451 rtx op0 = gen_reg_rtx (XFmode);
14452 rtx op1 = gen_reg_rtx (XFmode);
14453
14454 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14455 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14456 DONE;
14457 })
14458
14459 (define_expand "ilogbxf2"
14460 [(use (match_operand:SI 0 "register_operand"))
14461 (use (match_operand:XF 1 "register_operand"))]
14462 "TARGET_USE_FANCY_MATH_387
14463 && flag_unsafe_math_optimizations"
14464 {
14465 rtx op0, op1;
14466
14467 if (optimize_insn_for_size_p ())
14468 FAIL;
14469
14470 op0 = gen_reg_rtx (XFmode);
14471 op1 = gen_reg_rtx (XFmode);
14472
14473 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14474 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14475 DONE;
14476 })
14477
14478 (define_expand "ilogb<mode>2"
14479 [(use (match_operand:SI 0 "register_operand"))
14480 (use (match_operand:MODEF 1 "register_operand"))]
14481 "TARGET_USE_FANCY_MATH_387
14482 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14483 || TARGET_MIX_SSE_I387)
14484 && flag_unsafe_math_optimizations"
14485 {
14486 rtx op0, op1;
14487
14488 if (optimize_insn_for_size_p ())
14489 FAIL;
14490
14491 op0 = gen_reg_rtx (XFmode);
14492 op1 = gen_reg_rtx (XFmode);
14493
14494 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14495 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14496 DONE;
14497 })
14498
14499 (define_insn "*f2xm1xf2_i387"
14500 [(set (match_operand:XF 0 "register_operand" "=f")
14501 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14502 UNSPEC_F2XM1))]
14503 "TARGET_USE_FANCY_MATH_387
14504 && flag_unsafe_math_optimizations"
14505 "f2xm1"
14506 [(set_attr "type" "fpspc")
14507 (set_attr "mode" "XF")])
14508
14509 (define_insn "*fscalexf4_i387"
14510 [(set (match_operand:XF 0 "register_operand" "=f")
14511 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14512 (match_operand:XF 3 "register_operand" "1")]
14513 UNSPEC_FSCALE_FRACT))
14514 (set (match_operand:XF 1 "register_operand" "=u")
14515 (unspec:XF [(match_dup 2) (match_dup 3)]
14516 UNSPEC_FSCALE_EXP))]
14517 "TARGET_USE_FANCY_MATH_387
14518 && flag_unsafe_math_optimizations"
14519 "fscale"
14520 [(set_attr "type" "fpspc")
14521 (set_attr "mode" "XF")])
14522
14523 (define_expand "expNcorexf3"
14524 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14525 (match_operand:XF 2 "register_operand")))
14526 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14527 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14528 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14529 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14530 (parallel [(set (match_operand:XF 0 "register_operand")
14531 (unspec:XF [(match_dup 8) (match_dup 4)]
14532 UNSPEC_FSCALE_FRACT))
14533 (set (match_dup 9)
14534 (unspec:XF [(match_dup 8) (match_dup 4)]
14535 UNSPEC_FSCALE_EXP))])]
14536 "TARGET_USE_FANCY_MATH_387
14537 && flag_unsafe_math_optimizations"
14538 {
14539 int i;
14540
14541 if (optimize_insn_for_size_p ())
14542 FAIL;
14543
14544 for (i = 3; i < 10; i++)
14545 operands[i] = gen_reg_rtx (XFmode);
14546
14547 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14548 })
14549
14550 (define_expand "expxf2"
14551 [(use (match_operand:XF 0 "register_operand"))
14552 (use (match_operand:XF 1 "register_operand"))]
14553 "TARGET_USE_FANCY_MATH_387
14554 && flag_unsafe_math_optimizations"
14555 {
14556 rtx op2;
14557
14558 if (optimize_insn_for_size_p ())
14559 FAIL;
14560
14561 op2 = gen_reg_rtx (XFmode);
14562 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14563
14564 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14565 DONE;
14566 })
14567
14568 (define_expand "exp<mode>2"
14569 [(use (match_operand:MODEF 0 "register_operand"))
14570 (use (match_operand:MODEF 1 "general_operand"))]
14571 "TARGET_USE_FANCY_MATH_387
14572 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14573 || TARGET_MIX_SSE_I387)
14574 && flag_unsafe_math_optimizations"
14575 {
14576 rtx op0, op1;
14577
14578 if (optimize_insn_for_size_p ())
14579 FAIL;
14580
14581 op0 = gen_reg_rtx (XFmode);
14582 op1 = gen_reg_rtx (XFmode);
14583
14584 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14585 emit_insn (gen_expxf2 (op0, op1));
14586 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14587 DONE;
14588 })
14589
14590 (define_expand "exp10xf2"
14591 [(use (match_operand:XF 0 "register_operand"))
14592 (use (match_operand:XF 1 "register_operand"))]
14593 "TARGET_USE_FANCY_MATH_387
14594 && flag_unsafe_math_optimizations"
14595 {
14596 rtx op2;
14597
14598 if (optimize_insn_for_size_p ())
14599 FAIL;
14600
14601 op2 = gen_reg_rtx (XFmode);
14602 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14603
14604 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14605 DONE;
14606 })
14607
14608 (define_expand "exp10<mode>2"
14609 [(use (match_operand:MODEF 0 "register_operand"))
14610 (use (match_operand:MODEF 1 "general_operand"))]
14611 "TARGET_USE_FANCY_MATH_387
14612 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14613 || TARGET_MIX_SSE_I387)
14614 && flag_unsafe_math_optimizations"
14615 {
14616 rtx op0, op1;
14617
14618 if (optimize_insn_for_size_p ())
14619 FAIL;
14620
14621 op0 = gen_reg_rtx (XFmode);
14622 op1 = gen_reg_rtx (XFmode);
14623
14624 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14625 emit_insn (gen_exp10xf2 (op0, op1));
14626 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14627 DONE;
14628 })
14629
14630 (define_expand "exp2xf2"
14631 [(use (match_operand:XF 0 "register_operand"))
14632 (use (match_operand:XF 1 "register_operand"))]
14633 "TARGET_USE_FANCY_MATH_387
14634 && flag_unsafe_math_optimizations"
14635 {
14636 rtx op2;
14637
14638 if (optimize_insn_for_size_p ())
14639 FAIL;
14640
14641 op2 = gen_reg_rtx (XFmode);
14642 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14643
14644 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14645 DONE;
14646 })
14647
14648 (define_expand "exp2<mode>2"
14649 [(use (match_operand:MODEF 0 "register_operand"))
14650 (use (match_operand:MODEF 1 "general_operand"))]
14651 "TARGET_USE_FANCY_MATH_387
14652 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14653 || TARGET_MIX_SSE_I387)
14654 && flag_unsafe_math_optimizations"
14655 {
14656 rtx op0, op1;
14657
14658 if (optimize_insn_for_size_p ())
14659 FAIL;
14660
14661 op0 = gen_reg_rtx (XFmode);
14662 op1 = gen_reg_rtx (XFmode);
14663
14664 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14665 emit_insn (gen_exp2xf2 (op0, op1));
14666 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14667 DONE;
14668 })
14669
14670 (define_expand "expm1xf2"
14671 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14672 (match_dup 2)))
14673 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14674 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14675 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14676 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14677 (parallel [(set (match_dup 7)
14678 (unspec:XF [(match_dup 6) (match_dup 4)]
14679 UNSPEC_FSCALE_FRACT))
14680 (set (match_dup 8)
14681 (unspec:XF [(match_dup 6) (match_dup 4)]
14682 UNSPEC_FSCALE_EXP))])
14683 (parallel [(set (match_dup 10)
14684 (unspec:XF [(match_dup 9) (match_dup 8)]
14685 UNSPEC_FSCALE_FRACT))
14686 (set (match_dup 11)
14687 (unspec:XF [(match_dup 9) (match_dup 8)]
14688 UNSPEC_FSCALE_EXP))])
14689 (set (match_dup 12) (minus:XF (match_dup 10)
14690 (float_extend:XF (match_dup 13))))
14691 (set (match_operand:XF 0 "register_operand")
14692 (plus:XF (match_dup 12) (match_dup 7)))]
14693 "TARGET_USE_FANCY_MATH_387
14694 && flag_unsafe_math_optimizations"
14695 {
14696 int i;
14697
14698 if (optimize_insn_for_size_p ())
14699 FAIL;
14700
14701 for (i = 2; i < 13; i++)
14702 operands[i] = gen_reg_rtx (XFmode);
14703
14704 operands[13]
14705 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14706
14707 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14708 })
14709
14710 (define_expand "expm1<mode>2"
14711 [(use (match_operand:MODEF 0 "register_operand"))
14712 (use (match_operand:MODEF 1 "general_operand"))]
14713 "TARGET_USE_FANCY_MATH_387
14714 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14715 || TARGET_MIX_SSE_I387)
14716 && flag_unsafe_math_optimizations"
14717 {
14718 rtx op0, op1;
14719
14720 if (optimize_insn_for_size_p ())
14721 FAIL;
14722
14723 op0 = gen_reg_rtx (XFmode);
14724 op1 = gen_reg_rtx (XFmode);
14725
14726 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14727 emit_insn (gen_expm1xf2 (op0, op1));
14728 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14729 DONE;
14730 })
14731
14732 (define_expand "ldexpxf3"
14733 [(set (match_dup 3)
14734 (float:XF (match_operand:SI 2 "register_operand")))
14735 (parallel [(set (match_operand:XF 0 " register_operand")
14736 (unspec:XF [(match_operand:XF 1 "register_operand")
14737 (match_dup 3)]
14738 UNSPEC_FSCALE_FRACT))
14739 (set (match_dup 4)
14740 (unspec:XF [(match_dup 1) (match_dup 3)]
14741 UNSPEC_FSCALE_EXP))])]
14742 "TARGET_USE_FANCY_MATH_387
14743 && flag_unsafe_math_optimizations"
14744 {
14745 if (optimize_insn_for_size_p ())
14746 FAIL;
14747
14748 operands[3] = gen_reg_rtx (XFmode);
14749 operands[4] = gen_reg_rtx (XFmode);
14750 })
14751
14752 (define_expand "ldexp<mode>3"
14753 [(use (match_operand:MODEF 0 "register_operand"))
14754 (use (match_operand:MODEF 1 "general_operand"))
14755 (use (match_operand:SI 2 "register_operand"))]
14756 "TARGET_USE_FANCY_MATH_387
14757 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14758 || TARGET_MIX_SSE_I387)
14759 && flag_unsafe_math_optimizations"
14760 {
14761 rtx op0, op1;
14762
14763 if (optimize_insn_for_size_p ())
14764 FAIL;
14765
14766 op0 = gen_reg_rtx (XFmode);
14767 op1 = gen_reg_rtx (XFmode);
14768
14769 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14770 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14771 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14772 DONE;
14773 })
14774
14775 (define_expand "scalbxf3"
14776 [(parallel [(set (match_operand:XF 0 " register_operand")
14777 (unspec:XF [(match_operand:XF 1 "register_operand")
14778 (match_operand:XF 2 "register_operand")]
14779 UNSPEC_FSCALE_FRACT))
14780 (set (match_dup 3)
14781 (unspec:XF [(match_dup 1) (match_dup 2)]
14782 UNSPEC_FSCALE_EXP))])]
14783 "TARGET_USE_FANCY_MATH_387
14784 && flag_unsafe_math_optimizations"
14785 {
14786 if (optimize_insn_for_size_p ())
14787 FAIL;
14788
14789 operands[3] = gen_reg_rtx (XFmode);
14790 })
14791
14792 (define_expand "scalb<mode>3"
14793 [(use (match_operand:MODEF 0 "register_operand"))
14794 (use (match_operand:MODEF 1 "general_operand"))
14795 (use (match_operand:MODEF 2 "general_operand"))]
14796 "TARGET_USE_FANCY_MATH_387
14797 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14798 || TARGET_MIX_SSE_I387)
14799 && flag_unsafe_math_optimizations"
14800 {
14801 rtx op0, op1, op2;
14802
14803 if (optimize_insn_for_size_p ())
14804 FAIL;
14805
14806 op0 = gen_reg_rtx (XFmode);
14807 op1 = gen_reg_rtx (XFmode);
14808 op2 = gen_reg_rtx (XFmode);
14809
14810 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14811 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14812 emit_insn (gen_scalbxf3 (op0, op1, op2));
14813 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14814 DONE;
14815 })
14816
14817 (define_expand "significandxf2"
14818 [(parallel [(set (match_operand:XF 0 "register_operand")
14819 (unspec:XF [(match_operand:XF 1 "register_operand")]
14820 UNSPEC_XTRACT_FRACT))
14821 (set (match_dup 2)
14822 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14823 "TARGET_USE_FANCY_MATH_387
14824 && flag_unsafe_math_optimizations"
14825 "operands[2] = gen_reg_rtx (XFmode);")
14826
14827 (define_expand "significand<mode>2"
14828 [(use (match_operand:MODEF 0 "register_operand"))
14829 (use (match_operand:MODEF 1 "register_operand"))]
14830 "TARGET_USE_FANCY_MATH_387
14831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14832 || TARGET_MIX_SSE_I387)
14833 && flag_unsafe_math_optimizations"
14834 {
14835 rtx op0 = gen_reg_rtx (XFmode);
14836 rtx op1 = gen_reg_rtx (XFmode);
14837
14838 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14839 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14840 DONE;
14841 })
14842 \f
14843
14844 (define_insn "sse4_1_round<mode>2"
14845 [(set (match_operand:MODEF 0 "register_operand" "=x")
14846 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14847 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14848 UNSPEC_ROUND))]
14849 "TARGET_ROUND"
14850 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14851 [(set_attr "type" "ssecvt")
14852 (set_attr "prefix_extra" "1")
14853 (set_attr "prefix" "maybe_vex")
14854 (set_attr "mode" "<MODE>")])
14855
14856 (define_insn "rintxf2"
14857 [(set (match_operand:XF 0 "register_operand" "=f")
14858 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14859 UNSPEC_FRNDINT))]
14860 "TARGET_USE_FANCY_MATH_387
14861 && flag_unsafe_math_optimizations"
14862 "frndint"
14863 [(set_attr "type" "fpspc")
14864 (set_attr "mode" "XF")])
14865
14866 (define_expand "rint<mode>2"
14867 [(use (match_operand:MODEF 0 "register_operand"))
14868 (use (match_operand:MODEF 1 "register_operand"))]
14869 "(TARGET_USE_FANCY_MATH_387
14870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14871 || TARGET_MIX_SSE_I387)
14872 && flag_unsafe_math_optimizations)
14873 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14874 && !flag_trapping_math)"
14875 {
14876 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14877 && !flag_trapping_math)
14878 {
14879 if (TARGET_ROUND)
14880 emit_insn (gen_sse4_1_round<mode>2
14881 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14882 else if (optimize_insn_for_size_p ())
14883 FAIL;
14884 else
14885 ix86_expand_rint (operands[0], operands[1]);
14886 }
14887 else
14888 {
14889 rtx op0 = gen_reg_rtx (XFmode);
14890 rtx op1 = gen_reg_rtx (XFmode);
14891
14892 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14893 emit_insn (gen_rintxf2 (op0, op1));
14894
14895 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14896 }
14897 DONE;
14898 })
14899
14900 (define_expand "round<mode>2"
14901 [(match_operand:X87MODEF 0 "register_operand")
14902 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14903 "(TARGET_USE_FANCY_MATH_387
14904 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14905 || TARGET_MIX_SSE_I387)
14906 && flag_unsafe_math_optimizations)
14907 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14908 && !flag_trapping_math && !flag_rounding_math)"
14909 {
14910 if (optimize_insn_for_size_p ())
14911 FAIL;
14912
14913 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14914 && !flag_trapping_math && !flag_rounding_math)
14915 {
14916 if (TARGET_ROUND)
14917 {
14918 operands[1] = force_reg (<MODE>mode, operands[1]);
14919 ix86_expand_round_sse4 (operands[0], operands[1]);
14920 }
14921 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14922 ix86_expand_round (operands[0], operands[1]);
14923 else
14924 ix86_expand_rounddf_32 (operands[0], operands[1]);
14925 }
14926 else
14927 {
14928 operands[1] = force_reg (<MODE>mode, operands[1]);
14929 ix86_emit_i387_round (operands[0], operands[1]);
14930 }
14931 DONE;
14932 })
14933
14934 (define_insn_and_split "*fistdi2_1"
14935 [(set (match_operand:DI 0 "nonimmediate_operand")
14936 (unspec:DI [(match_operand:XF 1 "register_operand")]
14937 UNSPEC_FIST))]
14938 "TARGET_USE_FANCY_MATH_387
14939 && can_create_pseudo_p ()"
14940 "#"
14941 "&& 1"
14942 [(const_int 0)]
14943 {
14944 if (memory_operand (operands[0], VOIDmode))
14945 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14946 else
14947 {
14948 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14949 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14950 operands[2]));
14951 }
14952 DONE;
14953 }
14954 [(set_attr "type" "fpspc")
14955 (set_attr "mode" "DI")])
14956
14957 (define_insn "fistdi2"
14958 [(set (match_operand:DI 0 "memory_operand" "=m")
14959 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14960 UNSPEC_FIST))
14961 (clobber (match_scratch:XF 2 "=&1f"))]
14962 "TARGET_USE_FANCY_MATH_387"
14963 "* return output_fix_trunc (insn, operands, false);"
14964 [(set_attr "type" "fpspc")
14965 (set_attr "mode" "DI")])
14966
14967 (define_insn "fistdi2_with_temp"
14968 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14969 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14970 UNSPEC_FIST))
14971 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14972 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14973 "TARGET_USE_FANCY_MATH_387"
14974 "#"
14975 [(set_attr "type" "fpspc")
14976 (set_attr "mode" "DI")])
14977
14978 (define_split
14979 [(set (match_operand:DI 0 "register_operand")
14980 (unspec:DI [(match_operand:XF 1 "register_operand")]
14981 UNSPEC_FIST))
14982 (clobber (match_operand:DI 2 "memory_operand"))
14983 (clobber (match_scratch 3))]
14984 "reload_completed"
14985 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14986 (clobber (match_dup 3))])
14987 (set (match_dup 0) (match_dup 2))])
14988
14989 (define_split
14990 [(set (match_operand:DI 0 "memory_operand")
14991 (unspec:DI [(match_operand:XF 1 "register_operand")]
14992 UNSPEC_FIST))
14993 (clobber (match_operand:DI 2 "memory_operand"))
14994 (clobber (match_scratch 3))]
14995 "reload_completed"
14996 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14997 (clobber (match_dup 3))])])
14998
14999 (define_insn_and_split "*fist<mode>2_1"
15000 [(set (match_operand:SWI24 0 "register_operand")
15001 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15002 UNSPEC_FIST))]
15003 "TARGET_USE_FANCY_MATH_387
15004 && can_create_pseudo_p ()"
15005 "#"
15006 "&& 1"
15007 [(const_int 0)]
15008 {
15009 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15010 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15011 operands[2]));
15012 DONE;
15013 }
15014 [(set_attr "type" "fpspc")
15015 (set_attr "mode" "<MODE>")])
15016
15017 (define_insn "fist<mode>2"
15018 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15019 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15020 UNSPEC_FIST))]
15021 "TARGET_USE_FANCY_MATH_387"
15022 "* return output_fix_trunc (insn, operands, false);"
15023 [(set_attr "type" "fpspc")
15024 (set_attr "mode" "<MODE>")])
15025
15026 (define_insn "fist<mode>2_with_temp"
15027 [(set (match_operand:SWI24 0 "register_operand" "=r")
15028 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15029 UNSPEC_FIST))
15030 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15031 "TARGET_USE_FANCY_MATH_387"
15032 "#"
15033 [(set_attr "type" "fpspc")
15034 (set_attr "mode" "<MODE>")])
15035
15036 (define_split
15037 [(set (match_operand:SWI24 0 "register_operand")
15038 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15039 UNSPEC_FIST))
15040 (clobber (match_operand:SWI24 2 "memory_operand"))]
15041 "reload_completed"
15042 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15043 (set (match_dup 0) (match_dup 2))])
15044
15045 (define_split
15046 [(set (match_operand:SWI24 0 "memory_operand")
15047 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15048 UNSPEC_FIST))
15049 (clobber (match_operand:SWI24 2 "memory_operand"))]
15050 "reload_completed"
15051 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15052
15053 (define_expand "lrintxf<mode>2"
15054 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15055 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15056 UNSPEC_FIST))]
15057 "TARGET_USE_FANCY_MATH_387")
15058
15059 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15060 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15061 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15062 UNSPEC_FIX_NOTRUNC))]
15063 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15064 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15065
15066 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15067 [(match_operand:SWI248x 0 "nonimmediate_operand")
15068 (match_operand:X87MODEF 1 "register_operand")]
15069 "(TARGET_USE_FANCY_MATH_387
15070 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15071 || TARGET_MIX_SSE_I387)
15072 && flag_unsafe_math_optimizations)
15073 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15074 && <SWI248x:MODE>mode != HImode
15075 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15076 && !flag_trapping_math && !flag_rounding_math)"
15077 {
15078 if (optimize_insn_for_size_p ())
15079 FAIL;
15080
15081 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15082 && <SWI248x:MODE>mode != HImode
15083 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15084 && !flag_trapping_math && !flag_rounding_math)
15085 ix86_expand_lround (operands[0], operands[1]);
15086 else
15087 ix86_emit_i387_round (operands[0], operands[1]);
15088 DONE;
15089 })
15090
15091 (define_int_iterator FRNDINT_ROUNDING
15092 [UNSPEC_FRNDINT_FLOOR
15093 UNSPEC_FRNDINT_CEIL
15094 UNSPEC_FRNDINT_TRUNC])
15095
15096 (define_int_iterator FIST_ROUNDING
15097 [UNSPEC_FIST_FLOOR
15098 UNSPEC_FIST_CEIL])
15099
15100 ;; Base name for define_insn
15101 (define_int_attr rounding_insn
15102 [(UNSPEC_FRNDINT_FLOOR "floor")
15103 (UNSPEC_FRNDINT_CEIL "ceil")
15104 (UNSPEC_FRNDINT_TRUNC "btrunc")
15105 (UNSPEC_FIST_FLOOR "floor")
15106 (UNSPEC_FIST_CEIL "ceil")])
15107
15108 (define_int_attr rounding
15109 [(UNSPEC_FRNDINT_FLOOR "floor")
15110 (UNSPEC_FRNDINT_CEIL "ceil")
15111 (UNSPEC_FRNDINT_TRUNC "trunc")
15112 (UNSPEC_FIST_FLOOR "floor")
15113 (UNSPEC_FIST_CEIL "ceil")])
15114
15115 (define_int_attr ROUNDING
15116 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15117 (UNSPEC_FRNDINT_CEIL "CEIL")
15118 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15119 (UNSPEC_FIST_FLOOR "FLOOR")
15120 (UNSPEC_FIST_CEIL "CEIL")])
15121
15122 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15123 (define_insn_and_split "frndintxf2_<rounding>"
15124 [(set (match_operand:XF 0 "register_operand")
15125 (unspec:XF [(match_operand:XF 1 "register_operand")]
15126 FRNDINT_ROUNDING))
15127 (clobber (reg:CC FLAGS_REG))]
15128 "TARGET_USE_FANCY_MATH_387
15129 && flag_unsafe_math_optimizations
15130 && can_create_pseudo_p ()"
15131 "#"
15132 "&& 1"
15133 [(const_int 0)]
15134 {
15135 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15136
15137 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15138 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15139
15140 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15141 operands[2], operands[3]));
15142 DONE;
15143 }
15144 [(set_attr "type" "frndint")
15145 (set_attr "i387_cw" "<rounding>")
15146 (set_attr "mode" "XF")])
15147
15148 (define_insn "frndintxf2_<rounding>_i387"
15149 [(set (match_operand:XF 0 "register_operand" "=f")
15150 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15151 FRNDINT_ROUNDING))
15152 (use (match_operand:HI 2 "memory_operand" "m"))
15153 (use (match_operand:HI 3 "memory_operand" "m"))]
15154 "TARGET_USE_FANCY_MATH_387
15155 && flag_unsafe_math_optimizations"
15156 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15157 [(set_attr "type" "frndint")
15158 (set_attr "i387_cw" "<rounding>")
15159 (set_attr "mode" "XF")])
15160
15161 (define_expand "<rounding_insn>xf2"
15162 [(parallel [(set (match_operand:XF 0 "register_operand")
15163 (unspec:XF [(match_operand:XF 1 "register_operand")]
15164 FRNDINT_ROUNDING))
15165 (clobber (reg:CC FLAGS_REG))])]
15166 "TARGET_USE_FANCY_MATH_387
15167 && flag_unsafe_math_optimizations
15168 && !optimize_insn_for_size_p ()")
15169
15170 (define_expand "<rounding_insn><mode>2"
15171 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15172 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15173 FRNDINT_ROUNDING))
15174 (clobber (reg:CC FLAGS_REG))])]
15175 "(TARGET_USE_FANCY_MATH_387
15176 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15177 || TARGET_MIX_SSE_I387)
15178 && flag_unsafe_math_optimizations)
15179 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15180 && !flag_trapping_math)"
15181 {
15182 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15183 && !flag_trapping_math)
15184 {
15185 if (TARGET_ROUND)
15186 emit_insn (gen_sse4_1_round<mode>2
15187 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15188 else if (optimize_insn_for_size_p ())
15189 FAIL;
15190 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15191 {
15192 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15193 ix86_expand_floorceil (operands[0], operands[1], true);
15194 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15195 ix86_expand_floorceil (operands[0], operands[1], false);
15196 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15197 ix86_expand_trunc (operands[0], operands[1]);
15198 else
15199 gcc_unreachable ();
15200 }
15201 else
15202 {
15203 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15204 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15205 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15206 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15207 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15208 ix86_expand_truncdf_32 (operands[0], operands[1]);
15209 else
15210 gcc_unreachable ();
15211 }
15212 }
15213 else
15214 {
15215 rtx op0, op1;
15216
15217 if (optimize_insn_for_size_p ())
15218 FAIL;
15219
15220 op0 = gen_reg_rtx (XFmode);
15221 op1 = gen_reg_rtx (XFmode);
15222 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15223 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15224
15225 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15226 }
15227 DONE;
15228 })
15229
15230 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15231 (define_insn_and_split "frndintxf2_mask_pm"
15232 [(set (match_operand:XF 0 "register_operand")
15233 (unspec:XF [(match_operand:XF 1 "register_operand")]
15234 UNSPEC_FRNDINT_MASK_PM))
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_MASK_PM] = 1;
15244
15245 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15246 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15247
15248 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15249 operands[2], operands[3]));
15250 DONE;
15251 }
15252 [(set_attr "type" "frndint")
15253 (set_attr "i387_cw" "mask_pm")
15254 (set_attr "mode" "XF")])
15255
15256 (define_insn "frndintxf2_mask_pm_i387"
15257 [(set (match_operand:XF 0 "register_operand" "=f")
15258 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15259 UNSPEC_FRNDINT_MASK_PM))
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\tfclex\n\tfldcw\t%2"
15265 [(set_attr "type" "frndint")
15266 (set_attr "i387_cw" "mask_pm")
15267 (set_attr "mode" "XF")])
15268
15269 (define_expand "nearbyintxf2"
15270 [(parallel [(set (match_operand:XF 0 "register_operand")
15271 (unspec:XF [(match_operand:XF 1 "register_operand")]
15272 UNSPEC_FRNDINT_MASK_PM))
15273 (clobber (reg:CC FLAGS_REG))])]
15274 "TARGET_USE_FANCY_MATH_387
15275 && flag_unsafe_math_optimizations")
15276
15277 (define_expand "nearbyint<mode>2"
15278 [(use (match_operand:MODEF 0 "register_operand"))
15279 (use (match_operand:MODEF 1 "register_operand"))]
15280 "TARGET_USE_FANCY_MATH_387
15281 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15282 || TARGET_MIX_SSE_I387)
15283 && flag_unsafe_math_optimizations"
15284 {
15285 rtx op0 = gen_reg_rtx (XFmode);
15286 rtx op1 = gen_reg_rtx (XFmode);
15287
15288 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15289 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15290
15291 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15292 DONE;
15293 })
15294
15295 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15296 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15297 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15298 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15299 FIST_ROUNDING))
15300 (clobber (reg:CC FLAGS_REG))]
15301 "TARGET_USE_FANCY_MATH_387
15302 && flag_unsafe_math_optimizations
15303 && can_create_pseudo_p ()"
15304 "#"
15305 "&& 1"
15306 [(const_int 0)]
15307 {
15308 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15309
15310 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15311 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15312 if (memory_operand (operands[0], VOIDmode))
15313 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15314 operands[2], operands[3]));
15315 else
15316 {
15317 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15318 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15319 (operands[0], operands[1], operands[2],
15320 operands[3], operands[4]));
15321 }
15322 DONE;
15323 }
15324 [(set_attr "type" "fistp")
15325 (set_attr "i387_cw" "<rounding>")
15326 (set_attr "mode" "<MODE>")])
15327
15328 (define_insn "fistdi2_<rounding>"
15329 [(set (match_operand:DI 0 "memory_operand" "=m")
15330 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15331 FIST_ROUNDING))
15332 (use (match_operand:HI 2 "memory_operand" "m"))
15333 (use (match_operand:HI 3 "memory_operand" "m"))
15334 (clobber (match_scratch:XF 4 "=&1f"))]
15335 "TARGET_USE_FANCY_MATH_387
15336 && flag_unsafe_math_optimizations"
15337 "* return output_fix_trunc (insn, operands, false);"
15338 [(set_attr "type" "fistp")
15339 (set_attr "i387_cw" "<rounding>")
15340 (set_attr "mode" "DI")])
15341
15342 (define_insn "fistdi2_<rounding>_with_temp"
15343 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15344 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15345 FIST_ROUNDING))
15346 (use (match_operand:HI 2 "memory_operand" "m,m"))
15347 (use (match_operand:HI 3 "memory_operand" "m,m"))
15348 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15349 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15350 "TARGET_USE_FANCY_MATH_387
15351 && flag_unsafe_math_optimizations"
15352 "#"
15353 [(set_attr "type" "fistp")
15354 (set_attr "i387_cw" "<rounding>")
15355 (set_attr "mode" "DI")])
15356
15357 (define_split
15358 [(set (match_operand:DI 0 "register_operand")
15359 (unspec:DI [(match_operand:XF 1 "register_operand")]
15360 FIST_ROUNDING))
15361 (use (match_operand:HI 2 "memory_operand"))
15362 (use (match_operand:HI 3 "memory_operand"))
15363 (clobber (match_operand:DI 4 "memory_operand"))
15364 (clobber (match_scratch 5))]
15365 "reload_completed"
15366 [(parallel [(set (match_dup 4)
15367 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15368 (use (match_dup 2))
15369 (use (match_dup 3))
15370 (clobber (match_dup 5))])
15371 (set (match_dup 0) (match_dup 4))])
15372
15373 (define_split
15374 [(set (match_operand:DI 0 "memory_operand")
15375 (unspec:DI [(match_operand:XF 1 "register_operand")]
15376 FIST_ROUNDING))
15377 (use (match_operand:HI 2 "memory_operand"))
15378 (use (match_operand:HI 3 "memory_operand"))
15379 (clobber (match_operand:DI 4 "memory_operand"))
15380 (clobber (match_scratch 5))]
15381 "reload_completed"
15382 [(parallel [(set (match_dup 0)
15383 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15384 (use (match_dup 2))
15385 (use (match_dup 3))
15386 (clobber (match_dup 5))])])
15387
15388 (define_insn "fist<mode>2_<rounding>"
15389 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15390 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15391 FIST_ROUNDING))
15392 (use (match_operand:HI 2 "memory_operand" "m"))
15393 (use (match_operand:HI 3 "memory_operand" "m"))]
15394 "TARGET_USE_FANCY_MATH_387
15395 && flag_unsafe_math_optimizations"
15396 "* return output_fix_trunc (insn, operands, false);"
15397 [(set_attr "type" "fistp")
15398 (set_attr "i387_cw" "<rounding>")
15399 (set_attr "mode" "<MODE>")])
15400
15401 (define_insn "fist<mode>2_<rounding>_with_temp"
15402 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15403 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15404 FIST_ROUNDING))
15405 (use (match_operand:HI 2 "memory_operand" "m,m"))
15406 (use (match_operand:HI 3 "memory_operand" "m,m"))
15407 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15408 "TARGET_USE_FANCY_MATH_387
15409 && flag_unsafe_math_optimizations"
15410 "#"
15411 [(set_attr "type" "fistp")
15412 (set_attr "i387_cw" "<rounding>")
15413 (set_attr "mode" "<MODE>")])
15414
15415 (define_split
15416 [(set (match_operand:SWI24 0 "register_operand")
15417 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15418 FIST_ROUNDING))
15419 (use (match_operand:HI 2 "memory_operand"))
15420 (use (match_operand:HI 3 "memory_operand"))
15421 (clobber (match_operand:SWI24 4 "memory_operand"))]
15422 "reload_completed"
15423 [(parallel [(set (match_dup 4)
15424 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15425 (use (match_dup 2))
15426 (use (match_dup 3))])
15427 (set (match_dup 0) (match_dup 4))])
15428
15429 (define_split
15430 [(set (match_operand:SWI24 0 "memory_operand")
15431 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15432 FIST_ROUNDING))
15433 (use (match_operand:HI 2 "memory_operand"))
15434 (use (match_operand:HI 3 "memory_operand"))
15435 (clobber (match_operand:SWI24 4 "memory_operand"))]
15436 "reload_completed"
15437 [(parallel [(set (match_dup 0)
15438 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15439 (use (match_dup 2))
15440 (use (match_dup 3))])])
15441
15442 (define_expand "l<rounding_insn>xf<mode>2"
15443 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15444 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15445 FIST_ROUNDING))
15446 (clobber (reg:CC FLAGS_REG))])]
15447 "TARGET_USE_FANCY_MATH_387
15448 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15449 && flag_unsafe_math_optimizations")
15450
15451 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15452 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15453 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15454 FIST_ROUNDING))
15455 (clobber (reg:CC FLAGS_REG))])]
15456 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15457 && !flag_trapping_math"
15458 {
15459 if (TARGET_64BIT && optimize_insn_for_size_p ())
15460 FAIL;
15461
15462 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15463 ix86_expand_lfloorceil (operands[0], operands[1], true);
15464 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15465 ix86_expand_lfloorceil (operands[0], operands[1], false);
15466 else
15467 gcc_unreachable ();
15468
15469 DONE;
15470 })
15471
15472 (define_insn "fxam<mode>2_i387"
15473 [(set (match_operand:HI 0 "register_operand" "=a")
15474 (unspec:HI
15475 [(match_operand:X87MODEF 1 "register_operand" "f")]
15476 UNSPEC_FXAM))]
15477 "TARGET_USE_FANCY_MATH_387"
15478 "fxam\n\tfnstsw\t%0"
15479 [(set_attr "type" "multi")
15480 (set_attr "length" "4")
15481 (set_attr "unit" "i387")
15482 (set_attr "mode" "<MODE>")])
15483
15484 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15485 [(set (match_operand:HI 0 "register_operand")
15486 (unspec:HI
15487 [(match_operand:MODEF 1 "memory_operand")]
15488 UNSPEC_FXAM_MEM))]
15489 "TARGET_USE_FANCY_MATH_387
15490 && can_create_pseudo_p ()"
15491 "#"
15492 "&& 1"
15493 [(set (match_dup 2)(match_dup 1))
15494 (set (match_dup 0)
15495 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15496 {
15497 operands[2] = gen_reg_rtx (<MODE>mode);
15498
15499 MEM_VOLATILE_P (operands[1]) = 1;
15500 }
15501 [(set_attr "type" "multi")
15502 (set_attr "unit" "i387")
15503 (set_attr "mode" "<MODE>")])
15504
15505 (define_expand "isinfxf2"
15506 [(use (match_operand:SI 0 "register_operand"))
15507 (use (match_operand:XF 1 "register_operand"))]
15508 "TARGET_USE_FANCY_MATH_387
15509 && TARGET_C99_FUNCTIONS"
15510 {
15511 rtx mask = GEN_INT (0x45);
15512 rtx val = GEN_INT (0x05);
15513
15514 rtx cond;
15515
15516 rtx scratch = gen_reg_rtx (HImode);
15517 rtx res = gen_reg_rtx (QImode);
15518
15519 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15520
15521 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15522 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15523 cond = gen_rtx_fmt_ee (EQ, QImode,
15524 gen_rtx_REG (CCmode, FLAGS_REG),
15525 const0_rtx);
15526 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15527 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15528 DONE;
15529 })
15530
15531 (define_expand "isinf<mode>2"
15532 [(use (match_operand:SI 0 "register_operand"))
15533 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15534 "TARGET_USE_FANCY_MATH_387
15535 && TARGET_C99_FUNCTIONS
15536 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15537 {
15538 rtx mask = GEN_INT (0x45);
15539 rtx val = GEN_INT (0x05);
15540
15541 rtx cond;
15542
15543 rtx scratch = gen_reg_rtx (HImode);
15544 rtx res = gen_reg_rtx (QImode);
15545
15546 /* Remove excess precision by forcing value through memory. */
15547 if (memory_operand (operands[1], VOIDmode))
15548 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15549 else
15550 {
15551 enum ix86_stack_slot slot = (virtuals_instantiated
15552 ? SLOT_TEMP
15553 : SLOT_VIRTUAL);
15554 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15555
15556 emit_move_insn (temp, operands[1]);
15557 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15558 }
15559
15560 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15561 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15562 cond = gen_rtx_fmt_ee (EQ, QImode,
15563 gen_rtx_REG (CCmode, FLAGS_REG),
15564 const0_rtx);
15565 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15566 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15567 DONE;
15568 })
15569
15570 (define_expand "signbitxf2"
15571 [(use (match_operand:SI 0 "register_operand"))
15572 (use (match_operand:XF 1 "register_operand"))]
15573 "TARGET_USE_FANCY_MATH_387"
15574 {
15575 rtx scratch = gen_reg_rtx (HImode);
15576
15577 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15578 emit_insn (gen_andsi3 (operands[0],
15579 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15580 DONE;
15581 })
15582
15583 (define_insn "movmsk_df"
15584 [(set (match_operand:SI 0 "register_operand" "=r")
15585 (unspec:SI
15586 [(match_operand:DF 1 "register_operand" "x")]
15587 UNSPEC_MOVMSK))]
15588 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15589 "%vmovmskpd\t{%1, %0|%0, %1}"
15590 [(set_attr "type" "ssemov")
15591 (set_attr "prefix" "maybe_vex")
15592 (set_attr "mode" "DF")])
15593
15594 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15595 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15596 (define_expand "signbitdf2"
15597 [(use (match_operand:SI 0 "register_operand"))
15598 (use (match_operand:DF 1 "register_operand"))]
15599 "TARGET_USE_FANCY_MATH_387
15600 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15601 {
15602 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15603 {
15604 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15605 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15606 }
15607 else
15608 {
15609 rtx scratch = gen_reg_rtx (HImode);
15610
15611 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15612 emit_insn (gen_andsi3 (operands[0],
15613 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15614 }
15615 DONE;
15616 })
15617
15618 (define_expand "signbitsf2"
15619 [(use (match_operand:SI 0 "register_operand"))
15620 (use (match_operand:SF 1 "register_operand"))]
15621 "TARGET_USE_FANCY_MATH_387
15622 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15623 {
15624 rtx scratch = gen_reg_rtx (HImode);
15625
15626 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15627 emit_insn (gen_andsi3 (operands[0],
15628 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15629 DONE;
15630 })
15631 \f
15632 ;; Block operation instructions
15633
15634 (define_insn "cld"
15635 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15636 ""
15637 "cld"
15638 [(set_attr "length" "1")
15639 (set_attr "length_immediate" "0")
15640 (set_attr "modrm" "0")])
15641
15642 (define_expand "movmem<mode>"
15643 [(use (match_operand:BLK 0 "memory_operand"))
15644 (use (match_operand:BLK 1 "memory_operand"))
15645 (use (match_operand:SWI48 2 "nonmemory_operand"))
15646 (use (match_operand:SWI48 3 "const_int_operand"))
15647 (use (match_operand:SI 4 "const_int_operand"))
15648 (use (match_operand:SI 5 "const_int_operand"))]
15649 ""
15650 {
15651 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15652 operands[4], operands[5]))
15653 DONE;
15654 else
15655 FAIL;
15656 })
15657
15658 ;; Most CPUs don't like single string operations
15659 ;; Handle this case here to simplify previous expander.
15660
15661 (define_expand "strmov"
15662 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15663 (set (match_operand 1 "memory_operand") (match_dup 4))
15664 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15665 (clobber (reg:CC FLAGS_REG))])
15666 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15667 (clobber (reg:CC FLAGS_REG))])]
15668 ""
15669 {
15670 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15671
15672 /* If .md ever supports :P for Pmode, these can be directly
15673 in the pattern above. */
15674 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15675 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15676
15677 /* Can't use this if the user has appropriated esi or edi. */
15678 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15679 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15680 {
15681 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15682 operands[2], operands[3],
15683 operands[5], operands[6]));
15684 DONE;
15685 }
15686
15687 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15688 })
15689
15690 (define_expand "strmov_singleop"
15691 [(parallel [(set (match_operand 1 "memory_operand")
15692 (match_operand 3 "memory_operand"))
15693 (set (match_operand 0 "register_operand")
15694 (match_operand 4))
15695 (set (match_operand 2 "register_operand")
15696 (match_operand 5))])]
15697 ""
15698 "ix86_current_function_needs_cld = 1;")
15699
15700 (define_insn "*strmovdi_rex_1"
15701 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15702 (mem:DI (match_operand:P 3 "register_operand" "1")))
15703 (set (match_operand:P 0 "register_operand" "=D")
15704 (plus:P (match_dup 2)
15705 (const_int 8)))
15706 (set (match_operand:P 1 "register_operand" "=S")
15707 (plus:P (match_dup 3)
15708 (const_int 8)))]
15709 "TARGET_64BIT
15710 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15711 "%^movsq"
15712 [(set_attr "type" "str")
15713 (set_attr "memory" "both")
15714 (set_attr "mode" "DI")])
15715
15716 (define_insn "*strmovsi_1"
15717 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15718 (mem:SI (match_operand:P 3 "register_operand" "1")))
15719 (set (match_operand:P 0 "register_operand" "=D")
15720 (plus:P (match_dup 2)
15721 (const_int 4)))
15722 (set (match_operand:P 1 "register_operand" "=S")
15723 (plus:P (match_dup 3)
15724 (const_int 4)))]
15725 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15726 "%^movs{l|d}"
15727 [(set_attr "type" "str")
15728 (set_attr "memory" "both")
15729 (set_attr "mode" "SI")])
15730
15731 (define_insn "*strmovhi_1"
15732 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15733 (mem:HI (match_operand:P 3 "register_operand" "1")))
15734 (set (match_operand:P 0 "register_operand" "=D")
15735 (plus:P (match_dup 2)
15736 (const_int 2)))
15737 (set (match_operand:P 1 "register_operand" "=S")
15738 (plus:P (match_dup 3)
15739 (const_int 2)))]
15740 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15741 "%^movsw"
15742 [(set_attr "type" "str")
15743 (set_attr "memory" "both")
15744 (set_attr "mode" "HI")])
15745
15746 (define_insn "*strmovqi_1"
15747 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15748 (mem:QI (match_operand:P 3 "register_operand" "1")))
15749 (set (match_operand:P 0 "register_operand" "=D")
15750 (plus:P (match_dup 2)
15751 (const_int 1)))
15752 (set (match_operand:P 1 "register_operand" "=S")
15753 (plus:P (match_dup 3)
15754 (const_int 1)))]
15755 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15756 "%^movsb"
15757 [(set_attr "type" "str")
15758 (set_attr "memory" "both")
15759 (set (attr "prefix_rex")
15760 (if_then_else
15761 (match_test "<P:MODE>mode == DImode")
15762 (const_string "0")
15763 (const_string "*")))
15764 (set_attr "mode" "QI")])
15765
15766 (define_expand "rep_mov"
15767 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15768 (set (match_operand 0 "register_operand")
15769 (match_operand 5))
15770 (set (match_operand 2 "register_operand")
15771 (match_operand 6))
15772 (set (match_operand 1 "memory_operand")
15773 (match_operand 3 "memory_operand"))
15774 (use (match_dup 4))])]
15775 ""
15776 "ix86_current_function_needs_cld = 1;")
15777
15778 (define_insn "*rep_movdi_rex64"
15779 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15780 (set (match_operand:P 0 "register_operand" "=D")
15781 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15782 (const_int 3))
15783 (match_operand:P 3 "register_operand" "0")))
15784 (set (match_operand:P 1 "register_operand" "=S")
15785 (plus:P (ashift:P (match_dup 5) (const_int 3))
15786 (match_operand:P 4 "register_operand" "1")))
15787 (set (mem:BLK (match_dup 3))
15788 (mem:BLK (match_dup 4)))
15789 (use (match_dup 5))]
15790 "TARGET_64BIT
15791 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15792 "%^rep{%;} movsq"
15793 [(set_attr "type" "str")
15794 (set_attr "prefix_rep" "1")
15795 (set_attr "memory" "both")
15796 (set_attr "mode" "DI")])
15797
15798 (define_insn "*rep_movsi"
15799 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15800 (set (match_operand:P 0 "register_operand" "=D")
15801 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15802 (const_int 2))
15803 (match_operand:P 3 "register_operand" "0")))
15804 (set (match_operand:P 1 "register_operand" "=S")
15805 (plus:P (ashift:P (match_dup 5) (const_int 2))
15806 (match_operand:P 4 "register_operand" "1")))
15807 (set (mem:BLK (match_dup 3))
15808 (mem:BLK (match_dup 4)))
15809 (use (match_dup 5))]
15810 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15811 "%^rep{%;} movs{l|d}"
15812 [(set_attr "type" "str")
15813 (set_attr "prefix_rep" "1")
15814 (set_attr "memory" "both")
15815 (set_attr "mode" "SI")])
15816
15817 (define_insn "*rep_movqi"
15818 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15819 (set (match_operand:P 0 "register_operand" "=D")
15820 (plus:P (match_operand:P 3 "register_operand" "0")
15821 (match_operand:P 5 "register_operand" "2")))
15822 (set (match_operand:P 1 "register_operand" "=S")
15823 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15824 (set (mem:BLK (match_dup 3))
15825 (mem:BLK (match_dup 4)))
15826 (use (match_dup 5))]
15827 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15828 "%^rep{%;} movsb"
15829 [(set_attr "type" "str")
15830 (set_attr "prefix_rep" "1")
15831 (set_attr "memory" "both")
15832 (set_attr "mode" "QI")])
15833
15834 (define_expand "setmem<mode>"
15835 [(use (match_operand:BLK 0 "memory_operand"))
15836 (use (match_operand:SWI48 1 "nonmemory_operand"))
15837 (use (match_operand:QI 2 "nonmemory_operand"))
15838 (use (match_operand 3 "const_int_operand"))
15839 (use (match_operand:SI 4 "const_int_operand"))
15840 (use (match_operand:SI 5 "const_int_operand"))]
15841 ""
15842 {
15843 if (ix86_expand_setmem (operands[0], operands[1],
15844 operands[2], operands[3],
15845 operands[4], operands[5]))
15846 DONE;
15847 else
15848 FAIL;
15849 })
15850
15851 ;; Most CPUs don't like single string operations
15852 ;; Handle this case here to simplify previous expander.
15853
15854 (define_expand "strset"
15855 [(set (match_operand 1 "memory_operand")
15856 (match_operand 2 "register_operand"))
15857 (parallel [(set (match_operand 0 "register_operand")
15858 (match_dup 3))
15859 (clobber (reg:CC FLAGS_REG))])]
15860 ""
15861 {
15862 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15863 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15864
15865 /* If .md ever supports :P for Pmode, this can be directly
15866 in the pattern above. */
15867 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15868 GEN_INT (GET_MODE_SIZE (GET_MODE
15869 (operands[2]))));
15870 /* Can't use this if the user has appropriated eax or edi. */
15871 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15872 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15873 {
15874 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15875 operands[3]));
15876 DONE;
15877 }
15878 })
15879
15880 (define_expand "strset_singleop"
15881 [(parallel [(set (match_operand 1 "memory_operand")
15882 (match_operand 2 "register_operand"))
15883 (set (match_operand 0 "register_operand")
15884 (match_operand 3))])]
15885 ""
15886 "ix86_current_function_needs_cld = 1;")
15887
15888 (define_insn "*strsetdi_rex_1"
15889 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15890 (match_operand:DI 2 "register_operand" "a"))
15891 (set (match_operand:P 0 "register_operand" "=D")
15892 (plus:P (match_dup 1)
15893 (const_int 8)))]
15894 "TARGET_64BIT
15895 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15896 "%^stosq"
15897 [(set_attr "type" "str")
15898 (set_attr "memory" "store")
15899 (set_attr "mode" "DI")])
15900
15901 (define_insn "*strsetsi_1"
15902 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15903 (match_operand:SI 2 "register_operand" "a"))
15904 (set (match_operand:P 0 "register_operand" "=D")
15905 (plus:P (match_dup 1)
15906 (const_int 4)))]
15907 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15908 "%^stos{l|d}"
15909 [(set_attr "type" "str")
15910 (set_attr "memory" "store")
15911 (set_attr "mode" "SI")])
15912
15913 (define_insn "*strsethi_1"
15914 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15915 (match_operand:HI 2 "register_operand" "a"))
15916 (set (match_operand:P 0 "register_operand" "=D")
15917 (plus:P (match_dup 1)
15918 (const_int 2)))]
15919 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15920 "%^stosw"
15921 [(set_attr "type" "str")
15922 (set_attr "memory" "store")
15923 (set_attr "mode" "HI")])
15924
15925 (define_insn "*strsetqi_1"
15926 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15927 (match_operand:QI 2 "register_operand" "a"))
15928 (set (match_operand:P 0 "register_operand" "=D")
15929 (plus:P (match_dup 1)
15930 (const_int 1)))]
15931 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15932 "%^stosb"
15933 [(set_attr "type" "str")
15934 (set_attr "memory" "store")
15935 (set (attr "prefix_rex")
15936 (if_then_else
15937 (match_test "<P:MODE>mode == DImode")
15938 (const_string "0")
15939 (const_string "*")))
15940 (set_attr "mode" "QI")])
15941
15942 (define_expand "rep_stos"
15943 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15944 (set (match_operand 0 "register_operand")
15945 (match_operand 4))
15946 (set (match_operand 2 "memory_operand") (const_int 0))
15947 (use (match_operand 3 "register_operand"))
15948 (use (match_dup 1))])]
15949 ""
15950 "ix86_current_function_needs_cld = 1;")
15951
15952 (define_insn "*rep_stosdi_rex64"
15953 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15954 (set (match_operand:P 0 "register_operand" "=D")
15955 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15956 (const_int 3))
15957 (match_operand:P 3 "register_operand" "0")))
15958 (set (mem:BLK (match_dup 3))
15959 (const_int 0))
15960 (use (match_operand:DI 2 "register_operand" "a"))
15961 (use (match_dup 4))]
15962 "TARGET_64BIT
15963 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15964 "%^rep{%;} stosq"
15965 [(set_attr "type" "str")
15966 (set_attr "prefix_rep" "1")
15967 (set_attr "memory" "store")
15968 (set_attr "mode" "DI")])
15969
15970 (define_insn "*rep_stossi"
15971 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15972 (set (match_operand:P 0 "register_operand" "=D")
15973 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15974 (const_int 2))
15975 (match_operand:P 3 "register_operand" "0")))
15976 (set (mem:BLK (match_dup 3))
15977 (const_int 0))
15978 (use (match_operand:SI 2 "register_operand" "a"))
15979 (use (match_dup 4))]
15980 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15981 "%^rep{%;} stos{l|d}"
15982 [(set_attr "type" "str")
15983 (set_attr "prefix_rep" "1")
15984 (set_attr "memory" "store")
15985 (set_attr "mode" "SI")])
15986
15987 (define_insn "*rep_stosqi"
15988 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15989 (set (match_operand:P 0 "register_operand" "=D")
15990 (plus:P (match_operand:P 3 "register_operand" "0")
15991 (match_operand:P 4 "register_operand" "1")))
15992 (set (mem:BLK (match_dup 3))
15993 (const_int 0))
15994 (use (match_operand:QI 2 "register_operand" "a"))
15995 (use (match_dup 4))]
15996 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15997 "%^rep{%;} stosb"
15998 [(set_attr "type" "str")
15999 (set_attr "prefix_rep" "1")
16000 (set_attr "memory" "store")
16001 (set (attr "prefix_rex")
16002 (if_then_else
16003 (match_test "<P:MODE>mode == DImode")
16004 (const_string "0")
16005 (const_string "*")))
16006 (set_attr "mode" "QI")])
16007
16008 (define_expand "cmpstrnsi"
16009 [(set (match_operand:SI 0 "register_operand")
16010 (compare:SI (match_operand:BLK 1 "general_operand")
16011 (match_operand:BLK 2 "general_operand")))
16012 (use (match_operand 3 "general_operand"))
16013 (use (match_operand 4 "immediate_operand"))]
16014 ""
16015 {
16016 rtx addr1, addr2, out, outlow, count, countreg, align;
16017
16018 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16019 FAIL;
16020
16021 /* Can't use this if the user has appropriated ecx, esi or edi. */
16022 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16023 FAIL;
16024
16025 out = operands[0];
16026 if (!REG_P (out))
16027 out = gen_reg_rtx (SImode);
16028
16029 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16030 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16031 if (addr1 != XEXP (operands[1], 0))
16032 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16033 if (addr2 != XEXP (operands[2], 0))
16034 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16035
16036 count = operands[3];
16037 countreg = ix86_zero_extend_to_Pmode (count);
16038
16039 /* %%% Iff we are testing strict equality, we can use known alignment
16040 to good advantage. This may be possible with combine, particularly
16041 once cc0 is dead. */
16042 align = operands[4];
16043
16044 if (CONST_INT_P (count))
16045 {
16046 if (INTVAL (count) == 0)
16047 {
16048 emit_move_insn (operands[0], const0_rtx);
16049 DONE;
16050 }
16051 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16052 operands[1], operands[2]));
16053 }
16054 else
16055 {
16056 rtx (*gen_cmp) (rtx, rtx);
16057
16058 gen_cmp = (TARGET_64BIT
16059 ? gen_cmpdi_1 : gen_cmpsi_1);
16060
16061 emit_insn (gen_cmp (countreg, countreg));
16062 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16063 operands[1], operands[2]));
16064 }
16065
16066 outlow = gen_lowpart (QImode, out);
16067 emit_insn (gen_cmpintqi (outlow));
16068 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16069
16070 if (operands[0] != out)
16071 emit_move_insn (operands[0], out);
16072
16073 DONE;
16074 })
16075
16076 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16077
16078 (define_expand "cmpintqi"
16079 [(set (match_dup 1)
16080 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16081 (set (match_dup 2)
16082 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16083 (parallel [(set (match_operand:QI 0 "register_operand")
16084 (minus:QI (match_dup 1)
16085 (match_dup 2)))
16086 (clobber (reg:CC FLAGS_REG))])]
16087 ""
16088 {
16089 operands[1] = gen_reg_rtx (QImode);
16090 operands[2] = gen_reg_rtx (QImode);
16091 })
16092
16093 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16094 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16095
16096 (define_expand "cmpstrnqi_nz_1"
16097 [(parallel [(set (reg:CC FLAGS_REG)
16098 (compare:CC (match_operand 4 "memory_operand")
16099 (match_operand 5 "memory_operand")))
16100 (use (match_operand 2 "register_operand"))
16101 (use (match_operand:SI 3 "immediate_operand"))
16102 (clobber (match_operand 0 "register_operand"))
16103 (clobber (match_operand 1 "register_operand"))
16104 (clobber (match_dup 2))])]
16105 ""
16106 "ix86_current_function_needs_cld = 1;")
16107
16108 (define_insn "*cmpstrnqi_nz_1"
16109 [(set (reg:CC FLAGS_REG)
16110 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16111 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16112 (use (match_operand:P 6 "register_operand" "2"))
16113 (use (match_operand:SI 3 "immediate_operand" "i"))
16114 (clobber (match_operand:P 0 "register_operand" "=S"))
16115 (clobber (match_operand:P 1 "register_operand" "=D"))
16116 (clobber (match_operand:P 2 "register_operand" "=c"))]
16117 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16118 "%^repz{%;} cmpsb"
16119 [(set_attr "type" "str")
16120 (set_attr "mode" "QI")
16121 (set (attr "prefix_rex")
16122 (if_then_else
16123 (match_test "<P:MODE>mode == DImode")
16124 (const_string "0")
16125 (const_string "*")))
16126 (set_attr "prefix_rep" "1")])
16127
16128 ;; The same, but the count is not known to not be zero.
16129
16130 (define_expand "cmpstrnqi_1"
16131 [(parallel [(set (reg:CC FLAGS_REG)
16132 (if_then_else:CC (ne (match_operand 2 "register_operand")
16133 (const_int 0))
16134 (compare:CC (match_operand 4 "memory_operand")
16135 (match_operand 5 "memory_operand"))
16136 (const_int 0)))
16137 (use (match_operand:SI 3 "immediate_operand"))
16138 (use (reg:CC FLAGS_REG))
16139 (clobber (match_operand 0 "register_operand"))
16140 (clobber (match_operand 1 "register_operand"))
16141 (clobber (match_dup 2))])]
16142 ""
16143 "ix86_current_function_needs_cld = 1;")
16144
16145 (define_insn "*cmpstrnqi_1"
16146 [(set (reg:CC FLAGS_REG)
16147 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16148 (const_int 0))
16149 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16150 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16151 (const_int 0)))
16152 (use (match_operand:SI 3 "immediate_operand" "i"))
16153 (use (reg:CC FLAGS_REG))
16154 (clobber (match_operand:P 0 "register_operand" "=S"))
16155 (clobber (match_operand:P 1 "register_operand" "=D"))
16156 (clobber (match_operand:P 2 "register_operand" "=c"))]
16157 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16158 "%^repz{%;} cmpsb"
16159 [(set_attr "type" "str")
16160 (set_attr "mode" "QI")
16161 (set (attr "prefix_rex")
16162 (if_then_else
16163 (match_test "<P:MODE>mode == DImode")
16164 (const_string "0")
16165 (const_string "*")))
16166 (set_attr "prefix_rep" "1")])
16167
16168 (define_expand "strlen<mode>"
16169 [(set (match_operand:P 0 "register_operand")
16170 (unspec:P [(match_operand:BLK 1 "general_operand")
16171 (match_operand:QI 2 "immediate_operand")
16172 (match_operand 3 "immediate_operand")]
16173 UNSPEC_SCAS))]
16174 ""
16175 {
16176 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16177 DONE;
16178 else
16179 FAIL;
16180 })
16181
16182 (define_expand "strlenqi_1"
16183 [(parallel [(set (match_operand 0 "register_operand")
16184 (match_operand 2))
16185 (clobber (match_operand 1 "register_operand"))
16186 (clobber (reg:CC FLAGS_REG))])]
16187 ""
16188 "ix86_current_function_needs_cld = 1;")
16189
16190 (define_insn "*strlenqi_1"
16191 [(set (match_operand:P 0 "register_operand" "=&c")
16192 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16193 (match_operand:QI 2 "register_operand" "a")
16194 (match_operand:P 3 "immediate_operand" "i")
16195 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16196 (clobber (match_operand:P 1 "register_operand" "=D"))
16197 (clobber (reg:CC FLAGS_REG))]
16198 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16199 "%^repnz{%;} scasb"
16200 [(set_attr "type" "str")
16201 (set_attr "mode" "QI")
16202 (set (attr "prefix_rex")
16203 (if_then_else
16204 (match_test "<P:MODE>mode == DImode")
16205 (const_string "0")
16206 (const_string "*")))
16207 (set_attr "prefix_rep" "1")])
16208
16209 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16210 ;; handled in combine, but it is not currently up to the task.
16211 ;; When used for their truth value, the cmpstrn* expanders generate
16212 ;; code like this:
16213 ;;
16214 ;; repz cmpsb
16215 ;; seta %al
16216 ;; setb %dl
16217 ;; cmpb %al, %dl
16218 ;; jcc label
16219 ;;
16220 ;; The intermediate three instructions are unnecessary.
16221
16222 ;; This one handles cmpstrn*_nz_1...
16223 (define_peephole2
16224 [(parallel[
16225 (set (reg:CC FLAGS_REG)
16226 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16227 (mem:BLK (match_operand 5 "register_operand"))))
16228 (use (match_operand 6 "register_operand"))
16229 (use (match_operand:SI 3 "immediate_operand"))
16230 (clobber (match_operand 0 "register_operand"))
16231 (clobber (match_operand 1 "register_operand"))
16232 (clobber (match_operand 2 "register_operand"))])
16233 (set (match_operand:QI 7 "register_operand")
16234 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16235 (set (match_operand:QI 8 "register_operand")
16236 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16237 (set (reg FLAGS_REG)
16238 (compare (match_dup 7) (match_dup 8)))
16239 ]
16240 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16241 [(parallel[
16242 (set (reg:CC FLAGS_REG)
16243 (compare:CC (mem:BLK (match_dup 4))
16244 (mem:BLK (match_dup 5))))
16245 (use (match_dup 6))
16246 (use (match_dup 3))
16247 (clobber (match_dup 0))
16248 (clobber (match_dup 1))
16249 (clobber (match_dup 2))])])
16250
16251 ;; ...and this one handles cmpstrn*_1.
16252 (define_peephole2
16253 [(parallel[
16254 (set (reg:CC FLAGS_REG)
16255 (if_then_else:CC (ne (match_operand 6 "register_operand")
16256 (const_int 0))
16257 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16258 (mem:BLK (match_operand 5 "register_operand")))
16259 (const_int 0)))
16260 (use (match_operand:SI 3 "immediate_operand"))
16261 (use (reg:CC FLAGS_REG))
16262 (clobber (match_operand 0 "register_operand"))
16263 (clobber (match_operand 1 "register_operand"))
16264 (clobber (match_operand 2 "register_operand"))])
16265 (set (match_operand:QI 7 "register_operand")
16266 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16267 (set (match_operand:QI 8 "register_operand")
16268 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16269 (set (reg FLAGS_REG)
16270 (compare (match_dup 7) (match_dup 8)))
16271 ]
16272 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16273 [(parallel[
16274 (set (reg:CC FLAGS_REG)
16275 (if_then_else:CC (ne (match_dup 6)
16276 (const_int 0))
16277 (compare:CC (mem:BLK (match_dup 4))
16278 (mem:BLK (match_dup 5)))
16279 (const_int 0)))
16280 (use (match_dup 3))
16281 (use (reg:CC FLAGS_REG))
16282 (clobber (match_dup 0))
16283 (clobber (match_dup 1))
16284 (clobber (match_dup 2))])])
16285 \f
16286 ;; Conditional move instructions.
16287
16288 (define_expand "mov<mode>cc"
16289 [(set (match_operand:SWIM 0 "register_operand")
16290 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16291 (match_operand:SWIM 2 "<general_operand>")
16292 (match_operand:SWIM 3 "<general_operand>")))]
16293 ""
16294 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16295
16296 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16297 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16298 ;; So just document what we're doing explicitly.
16299
16300 (define_expand "x86_mov<mode>cc_0_m1"
16301 [(parallel
16302 [(set (match_operand:SWI48 0 "register_operand")
16303 (if_then_else:SWI48
16304 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16305 [(match_operand 1 "flags_reg_operand")
16306 (const_int 0)])
16307 (const_int -1)
16308 (const_int 0)))
16309 (clobber (reg:CC FLAGS_REG))])])
16310
16311 (define_insn "*x86_mov<mode>cc_0_m1"
16312 [(set (match_operand:SWI48 0 "register_operand" "=r")
16313 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16314 [(reg FLAGS_REG) (const_int 0)])
16315 (const_int -1)
16316 (const_int 0)))
16317 (clobber (reg:CC FLAGS_REG))]
16318 ""
16319 "sbb{<imodesuffix>}\t%0, %0"
16320 ; Since we don't have the proper number of operands for an alu insn,
16321 ; fill in all the blanks.
16322 [(set_attr "type" "alu")
16323 (set_attr "use_carry" "1")
16324 (set_attr "pent_pair" "pu")
16325 (set_attr "memory" "none")
16326 (set_attr "imm_disp" "false")
16327 (set_attr "mode" "<MODE>")
16328 (set_attr "length_immediate" "0")])
16329
16330 (define_insn "*x86_mov<mode>cc_0_m1_se"
16331 [(set (match_operand:SWI48 0 "register_operand" "=r")
16332 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16333 [(reg FLAGS_REG) (const_int 0)])
16334 (const_int 1)
16335 (const_int 0)))
16336 (clobber (reg:CC FLAGS_REG))]
16337 ""
16338 "sbb{<imodesuffix>}\t%0, %0"
16339 [(set_attr "type" "alu")
16340 (set_attr "use_carry" "1")
16341 (set_attr "pent_pair" "pu")
16342 (set_attr "memory" "none")
16343 (set_attr "imm_disp" "false")
16344 (set_attr "mode" "<MODE>")
16345 (set_attr "length_immediate" "0")])
16346
16347 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16348 [(set (match_operand:SWI48 0 "register_operand" "=r")
16349 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16350 [(reg FLAGS_REG) (const_int 0)])))
16351 (clobber (reg:CC FLAGS_REG))]
16352 ""
16353 "sbb{<imodesuffix>}\t%0, %0"
16354 [(set_attr "type" "alu")
16355 (set_attr "use_carry" "1")
16356 (set_attr "pent_pair" "pu")
16357 (set_attr "memory" "none")
16358 (set_attr "imm_disp" "false")
16359 (set_attr "mode" "<MODE>")
16360 (set_attr "length_immediate" "0")])
16361
16362 (define_insn "*mov<mode>cc_noc"
16363 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16364 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16365 [(reg FLAGS_REG) (const_int 0)])
16366 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16367 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16368 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16369 "@
16370 cmov%O2%C1\t{%2, %0|%0, %2}
16371 cmov%O2%c1\t{%3, %0|%0, %3}"
16372 [(set_attr "type" "icmov")
16373 (set_attr "mode" "<MODE>")])
16374
16375 (define_insn "*movqicc_noc"
16376 [(set (match_operand:QI 0 "register_operand" "=r,r")
16377 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16378 [(reg FLAGS_REG) (const_int 0)])
16379 (match_operand:QI 2 "register_operand" "r,0")
16380 (match_operand:QI 3 "register_operand" "0,r")))]
16381 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16382 "#"
16383 [(set_attr "type" "icmov")
16384 (set_attr "mode" "QI")])
16385
16386 (define_split
16387 [(set (match_operand 0 "register_operand")
16388 (if_then_else (match_operator 1 "ix86_comparison_operator"
16389 [(reg FLAGS_REG) (const_int 0)])
16390 (match_operand 2 "register_operand")
16391 (match_operand 3 "register_operand")))]
16392 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16393 && (GET_MODE (operands[0]) == QImode
16394 || GET_MODE (operands[0]) == HImode)
16395 && reload_completed"
16396 [(set (match_dup 0)
16397 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16398 {
16399 operands[0] = gen_lowpart (SImode, operands[0]);
16400 operands[2] = gen_lowpart (SImode, operands[2]);
16401 operands[3] = gen_lowpart (SImode, operands[3]);
16402 })
16403
16404 (define_expand "mov<mode>cc"
16405 [(set (match_operand:X87MODEF 0 "register_operand")
16406 (if_then_else:X87MODEF
16407 (match_operand 1 "ix86_fp_comparison_operator")
16408 (match_operand:X87MODEF 2 "register_operand")
16409 (match_operand:X87MODEF 3 "register_operand")))]
16410 "(TARGET_80387 && TARGET_CMOVE)
16411 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16412 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16413
16414 (define_insn "*movxfcc_1"
16415 [(set (match_operand:XF 0 "register_operand" "=f,f")
16416 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16417 [(reg FLAGS_REG) (const_int 0)])
16418 (match_operand:XF 2 "register_operand" "f,0")
16419 (match_operand:XF 3 "register_operand" "0,f")))]
16420 "TARGET_80387 && TARGET_CMOVE"
16421 "@
16422 fcmov%F1\t{%2, %0|%0, %2}
16423 fcmov%f1\t{%3, %0|%0, %3}"
16424 [(set_attr "type" "fcmov")
16425 (set_attr "mode" "XF")])
16426
16427 (define_insn "*movdfcc_1_rex64"
16428 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16429 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16430 [(reg FLAGS_REG) (const_int 0)])
16431 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16432 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16433 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16434 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16435 "@
16436 fcmov%F1\t{%2, %0|%0, %2}
16437 fcmov%f1\t{%3, %0|%0, %3}
16438 cmov%O2%C1\t{%2, %0|%0, %2}
16439 cmov%O2%c1\t{%3, %0|%0, %3}"
16440 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16441 (set_attr "mode" "DF,DF,DI,DI")])
16442
16443 (define_insn "*movdfcc_1"
16444 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16445 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16446 [(reg FLAGS_REG) (const_int 0)])
16447 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16448 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16449 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16450 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16451 "@
16452 fcmov%F1\t{%2, %0|%0, %2}
16453 fcmov%f1\t{%3, %0|%0, %3}
16454 #
16455 #"
16456 [(set_attr "type" "fcmov,fcmov,multi,multi")
16457 (set_attr "mode" "DF,DF,DI,DI")])
16458
16459 (define_split
16460 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16461 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16462 [(reg FLAGS_REG) (const_int 0)])
16463 (match_operand:DF 2 "nonimmediate_operand")
16464 (match_operand:DF 3 "nonimmediate_operand")))]
16465 "!TARGET_64BIT && reload_completed"
16466 [(set (match_dup 2)
16467 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16468 (set (match_dup 3)
16469 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16470 {
16471 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16472 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16473 })
16474
16475 (define_insn "*movsfcc_1_387"
16476 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16477 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16478 [(reg FLAGS_REG) (const_int 0)])
16479 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16480 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16481 "TARGET_80387 && TARGET_CMOVE
16482 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16483 "@
16484 fcmov%F1\t{%2, %0|%0, %2}
16485 fcmov%f1\t{%3, %0|%0, %3}
16486 cmov%O2%C1\t{%2, %0|%0, %2}
16487 cmov%O2%c1\t{%3, %0|%0, %3}"
16488 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16489 (set_attr "mode" "SF,SF,SI,SI")])
16490
16491 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16492 ;; the scalar versions to have only XMM registers as operands.
16493
16494 ;; XOP conditional move
16495 (define_insn "*xop_pcmov_<mode>"
16496 [(set (match_operand:MODEF 0 "register_operand" "=x")
16497 (if_then_else:MODEF
16498 (match_operand:MODEF 1 "register_operand" "x")
16499 (match_operand:MODEF 2 "register_operand" "x")
16500 (match_operand:MODEF 3 "register_operand" "x")))]
16501 "TARGET_XOP"
16502 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16503 [(set_attr "type" "sse4arg")])
16504
16505 ;; These versions of the min/max patterns are intentionally ignorant of
16506 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16507 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16508 ;; are undefined in this condition, we're certain this is correct.
16509
16510 (define_insn "<code><mode>3"
16511 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16512 (smaxmin:MODEF
16513 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16514 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16515 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16516 "@
16517 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16518 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16519 [(set_attr "isa" "noavx,avx")
16520 (set_attr "prefix" "orig,vex")
16521 (set_attr "type" "sseadd")
16522 (set_attr "mode" "<MODE>")])
16523
16524 ;; These versions of the min/max patterns implement exactly the operations
16525 ;; min = (op1 < op2 ? op1 : op2)
16526 ;; max = (!(op1 < op2) ? op1 : op2)
16527 ;; Their operands are not commutative, and thus they may be used in the
16528 ;; presence of -0.0 and NaN.
16529
16530 (define_int_iterator IEEE_MAXMIN
16531 [UNSPEC_IEEE_MAX
16532 UNSPEC_IEEE_MIN])
16533
16534 (define_int_attr ieee_maxmin
16535 [(UNSPEC_IEEE_MAX "max")
16536 (UNSPEC_IEEE_MIN "min")])
16537
16538 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16539 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16540 (unspec:MODEF
16541 [(match_operand:MODEF 1 "register_operand" "0,x")
16542 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16543 IEEE_MAXMIN))]
16544 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16545 "@
16546 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16547 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16548 [(set_attr "isa" "noavx,avx")
16549 (set_attr "prefix" "orig,vex")
16550 (set_attr "type" "sseadd")
16551 (set_attr "mode" "<MODE>")])
16552
16553 ;; Make two stack loads independent:
16554 ;; fld aa fld aa
16555 ;; fld %st(0) -> fld bb
16556 ;; fmul bb fmul %st(1), %st
16557 ;;
16558 ;; Actually we only match the last two instructions for simplicity.
16559 (define_peephole2
16560 [(set (match_operand 0 "fp_register_operand")
16561 (match_operand 1 "fp_register_operand"))
16562 (set (match_dup 0)
16563 (match_operator 2 "binary_fp_operator"
16564 [(match_dup 0)
16565 (match_operand 3 "memory_operand")]))]
16566 "REGNO (operands[0]) != REGNO (operands[1])"
16567 [(set (match_dup 0) (match_dup 3))
16568 (set (match_dup 0) (match_dup 4))]
16569
16570 ;; The % modifier is not operational anymore in peephole2's, so we have to
16571 ;; swap the operands manually in the case of addition and multiplication.
16572 {
16573 rtx op0, op1;
16574
16575 if (COMMUTATIVE_ARITH_P (operands[2]))
16576 op0 = operands[0], op1 = operands[1];
16577 else
16578 op0 = operands[1], op1 = operands[0];
16579
16580 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16581 GET_MODE (operands[2]),
16582 op0, op1);
16583 })
16584
16585 ;; Conditional addition patterns
16586 (define_expand "add<mode>cc"
16587 [(match_operand:SWI 0 "register_operand")
16588 (match_operand 1 "ordered_comparison_operator")
16589 (match_operand:SWI 2 "register_operand")
16590 (match_operand:SWI 3 "const_int_operand")]
16591 ""
16592 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16593 \f
16594 ;; Misc patterns (?)
16595
16596 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16597 ;; Otherwise there will be nothing to keep
16598 ;;
16599 ;; [(set (reg ebp) (reg esp))]
16600 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16601 ;; (clobber (eflags)]
16602 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16603 ;;
16604 ;; in proper program order.
16605
16606 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16607 [(set (match_operand:P 0 "register_operand" "=r,r")
16608 (plus:P (match_operand:P 1 "register_operand" "0,r")
16609 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16610 (clobber (reg:CC FLAGS_REG))
16611 (clobber (mem:BLK (scratch)))]
16612 ""
16613 {
16614 switch (get_attr_type (insn))
16615 {
16616 case TYPE_IMOV:
16617 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16618
16619 case TYPE_ALU:
16620 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16621 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16622 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16623
16624 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16625
16626 default:
16627 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16628 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16629 }
16630 }
16631 [(set (attr "type")
16632 (cond [(and (eq_attr "alternative" "0")
16633 (not (match_test "TARGET_OPT_AGU")))
16634 (const_string "alu")
16635 (match_operand:<MODE> 2 "const0_operand")
16636 (const_string "imov")
16637 ]
16638 (const_string "lea")))
16639 (set (attr "length_immediate")
16640 (cond [(eq_attr "type" "imov")
16641 (const_string "0")
16642 (and (eq_attr "type" "alu")
16643 (match_operand 2 "const128_operand"))
16644 (const_string "1")
16645 ]
16646 (const_string "*")))
16647 (set_attr "mode" "<MODE>")])
16648
16649 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16650 [(set (match_operand:P 0 "register_operand" "=r")
16651 (minus:P (match_operand:P 1 "register_operand" "0")
16652 (match_operand:P 2 "register_operand" "r")))
16653 (clobber (reg:CC FLAGS_REG))
16654 (clobber (mem:BLK (scratch)))]
16655 ""
16656 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16657 [(set_attr "type" "alu")
16658 (set_attr "mode" "<MODE>")])
16659
16660 (define_insn "allocate_stack_worker_probe_<mode>"
16661 [(set (match_operand:P 0 "register_operand" "=a")
16662 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16663 UNSPECV_STACK_PROBE))
16664 (clobber (reg:CC FLAGS_REG))]
16665 "ix86_target_stack_probe ()"
16666 "call\t___chkstk_ms"
16667 [(set_attr "type" "multi")
16668 (set_attr "length" "5")])
16669
16670 (define_expand "allocate_stack"
16671 [(match_operand 0 "register_operand")
16672 (match_operand 1 "general_operand")]
16673 "ix86_target_stack_probe ()"
16674 {
16675 rtx x;
16676
16677 #ifndef CHECK_STACK_LIMIT
16678 #define CHECK_STACK_LIMIT 0
16679 #endif
16680
16681 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16682 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16683 x = operands[1];
16684 else
16685 {
16686 rtx (*insn) (rtx, rtx);
16687
16688 x = copy_to_mode_reg (Pmode, operands[1]);
16689
16690 insn = (TARGET_64BIT
16691 ? gen_allocate_stack_worker_probe_di
16692 : gen_allocate_stack_worker_probe_si);
16693
16694 emit_insn (insn (x, x));
16695 }
16696
16697 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16698 stack_pointer_rtx, 0, OPTAB_DIRECT);
16699
16700 if (x != stack_pointer_rtx)
16701 emit_move_insn (stack_pointer_rtx, x);
16702
16703 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16704 DONE;
16705 })
16706
16707 ;; Use IOR for stack probes, this is shorter.
16708 (define_expand "probe_stack"
16709 [(match_operand 0 "memory_operand")]
16710 ""
16711 {
16712 rtx (*gen_ior3) (rtx, rtx, rtx);
16713
16714 gen_ior3 = (GET_MODE (operands[0]) == DImode
16715 ? gen_iordi3 : gen_iorsi3);
16716
16717 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16718 DONE;
16719 })
16720
16721 (define_insn "adjust_stack_and_probe<mode>"
16722 [(set (match_operand:P 0 "register_operand" "=r")
16723 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16724 UNSPECV_PROBE_STACK_RANGE))
16725 (set (reg:P SP_REG)
16726 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16727 (clobber (reg:CC FLAGS_REG))
16728 (clobber (mem:BLK (scratch)))]
16729 ""
16730 "* return output_adjust_stack_and_probe (operands[0]);"
16731 [(set_attr "type" "multi")])
16732
16733 (define_insn "probe_stack_range<mode>"
16734 [(set (match_operand:P 0 "register_operand" "=r")
16735 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16736 (match_operand:P 2 "const_int_operand" "n")]
16737 UNSPECV_PROBE_STACK_RANGE))
16738 (clobber (reg:CC FLAGS_REG))]
16739 ""
16740 "* return output_probe_stack_range (operands[0], operands[2]);"
16741 [(set_attr "type" "multi")])
16742
16743 (define_expand "builtin_setjmp_receiver"
16744 [(label_ref (match_operand 0))]
16745 "!TARGET_64BIT && flag_pic"
16746 {
16747 #if TARGET_MACHO
16748 if (TARGET_MACHO)
16749 {
16750 rtx xops[3];
16751 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16752 rtx label_rtx = gen_label_rtx ();
16753 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16754 xops[0] = xops[1] = picreg;
16755 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16756 ix86_expand_binary_operator (MINUS, SImode, xops);
16757 }
16758 else
16759 #endif
16760 emit_insn (gen_set_got (pic_offset_table_rtx));
16761 DONE;
16762 })
16763 \f
16764 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16765
16766 (define_split
16767 [(set (match_operand 0 "register_operand")
16768 (match_operator 3 "promotable_binary_operator"
16769 [(match_operand 1 "register_operand")
16770 (match_operand 2 "aligned_operand")]))
16771 (clobber (reg:CC FLAGS_REG))]
16772 "! TARGET_PARTIAL_REG_STALL && reload_completed
16773 && ((GET_MODE (operands[0]) == HImode
16774 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16775 /* ??? next two lines just !satisfies_constraint_K (...) */
16776 || !CONST_INT_P (operands[2])
16777 || satisfies_constraint_K (operands[2])))
16778 || (GET_MODE (operands[0]) == QImode
16779 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16780 [(parallel [(set (match_dup 0)
16781 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16782 (clobber (reg:CC FLAGS_REG))])]
16783 {
16784 operands[0] = gen_lowpart (SImode, operands[0]);
16785 operands[1] = gen_lowpart (SImode, operands[1]);
16786 if (GET_CODE (operands[3]) != ASHIFT)
16787 operands[2] = gen_lowpart (SImode, operands[2]);
16788 PUT_MODE (operands[3], SImode);
16789 })
16790
16791 ; Promote the QImode tests, as i386 has encoding of the AND
16792 ; instruction with 32-bit sign-extended immediate and thus the
16793 ; instruction size is unchanged, except in the %eax case for
16794 ; which it is increased by one byte, hence the ! optimize_size.
16795 (define_split
16796 [(set (match_operand 0 "flags_reg_operand")
16797 (match_operator 2 "compare_operator"
16798 [(and (match_operand 3 "aligned_operand")
16799 (match_operand 4 "const_int_operand"))
16800 (const_int 0)]))
16801 (set (match_operand 1 "register_operand")
16802 (and (match_dup 3) (match_dup 4)))]
16803 "! TARGET_PARTIAL_REG_STALL && reload_completed
16804 && optimize_insn_for_speed_p ()
16805 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16806 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16807 /* Ensure that the operand will remain sign-extended immediate. */
16808 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16809 [(parallel [(set (match_dup 0)
16810 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16811 (const_int 0)]))
16812 (set (match_dup 1)
16813 (and:SI (match_dup 3) (match_dup 4)))])]
16814 {
16815 operands[4]
16816 = gen_int_mode (INTVAL (operands[4])
16817 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16818 operands[1] = gen_lowpart (SImode, operands[1]);
16819 operands[3] = gen_lowpart (SImode, operands[3]);
16820 })
16821
16822 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16823 ; the TEST instruction with 32-bit sign-extended immediate and thus
16824 ; the instruction size would at least double, which is not what we
16825 ; want even with ! optimize_size.
16826 (define_split
16827 [(set (match_operand 0 "flags_reg_operand")
16828 (match_operator 1 "compare_operator"
16829 [(and (match_operand:HI 2 "aligned_operand")
16830 (match_operand:HI 3 "const_int_operand"))
16831 (const_int 0)]))]
16832 "! TARGET_PARTIAL_REG_STALL && reload_completed
16833 && ! TARGET_FAST_PREFIX
16834 && optimize_insn_for_speed_p ()
16835 /* Ensure that the operand will remain sign-extended immediate. */
16836 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16837 [(set (match_dup 0)
16838 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16839 (const_int 0)]))]
16840 {
16841 operands[3]
16842 = gen_int_mode (INTVAL (operands[3])
16843 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16844 operands[2] = gen_lowpart (SImode, operands[2]);
16845 })
16846
16847 (define_split
16848 [(set (match_operand 0 "register_operand")
16849 (neg (match_operand 1 "register_operand")))
16850 (clobber (reg:CC FLAGS_REG))]
16851 "! TARGET_PARTIAL_REG_STALL && reload_completed
16852 && (GET_MODE (operands[0]) == HImode
16853 || (GET_MODE (operands[0]) == QImode
16854 && (TARGET_PROMOTE_QImode
16855 || optimize_insn_for_size_p ())))"
16856 [(parallel [(set (match_dup 0)
16857 (neg:SI (match_dup 1)))
16858 (clobber (reg:CC FLAGS_REG))])]
16859 {
16860 operands[0] = gen_lowpart (SImode, operands[0]);
16861 operands[1] = gen_lowpart (SImode, operands[1]);
16862 })
16863
16864 (define_split
16865 [(set (match_operand 0 "register_operand")
16866 (not (match_operand 1 "register_operand")))]
16867 "! TARGET_PARTIAL_REG_STALL && reload_completed
16868 && (GET_MODE (operands[0]) == HImode
16869 || (GET_MODE (operands[0]) == QImode
16870 && (TARGET_PROMOTE_QImode
16871 || optimize_insn_for_size_p ())))"
16872 [(set (match_dup 0)
16873 (not:SI (match_dup 1)))]
16874 {
16875 operands[0] = gen_lowpart (SImode, operands[0]);
16876 operands[1] = gen_lowpart (SImode, operands[1]);
16877 })
16878 \f
16879 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16880 ;; transform a complex memory operation into two memory to register operations.
16881
16882 ;; Don't push memory operands
16883 (define_peephole2
16884 [(set (match_operand:SWI 0 "push_operand")
16885 (match_operand:SWI 1 "memory_operand"))
16886 (match_scratch:SWI 2 "<r>")]
16887 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16888 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16889 [(set (match_dup 2) (match_dup 1))
16890 (set (match_dup 0) (match_dup 2))])
16891
16892 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16893 ;; SImode pushes.
16894 (define_peephole2
16895 [(set (match_operand:SF 0 "push_operand")
16896 (match_operand:SF 1 "memory_operand"))
16897 (match_scratch:SF 2 "r")]
16898 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16899 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16900 [(set (match_dup 2) (match_dup 1))
16901 (set (match_dup 0) (match_dup 2))])
16902
16903 ;; Don't move an immediate directly to memory when the instruction
16904 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16905 (define_peephole2
16906 [(match_scratch:SWI124 1 "<r>")
16907 (set (match_operand:SWI124 0 "memory_operand")
16908 (const_int 0))]
16909 "optimize_insn_for_speed_p ()
16910 && ((<MODE>mode == HImode
16911 && TARGET_LCP_STALL)
16912 || (!TARGET_USE_MOV0
16913 && TARGET_SPLIT_LONG_MOVES
16914 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16915 && peep2_regno_dead_p (0, FLAGS_REG)"
16916 [(parallel [(set (match_dup 2) (const_int 0))
16917 (clobber (reg:CC FLAGS_REG))])
16918 (set (match_dup 0) (match_dup 1))]
16919 "operands[2] = gen_lowpart (SImode, operands[1]);")
16920
16921 (define_peephole2
16922 [(match_scratch:SWI124 2 "<r>")
16923 (set (match_operand:SWI124 0 "memory_operand")
16924 (match_operand:SWI124 1 "immediate_operand"))]
16925 "optimize_insn_for_speed_p ()
16926 && ((<MODE>mode == HImode
16927 && TARGET_LCP_STALL)
16928 || (TARGET_SPLIT_LONG_MOVES
16929 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16930 [(set (match_dup 2) (match_dup 1))
16931 (set (match_dup 0) (match_dup 2))])
16932
16933 ;; Don't compare memory with zero, load and use a test instead.
16934 (define_peephole2
16935 [(set (match_operand 0 "flags_reg_operand")
16936 (match_operator 1 "compare_operator"
16937 [(match_operand:SI 2 "memory_operand")
16938 (const_int 0)]))
16939 (match_scratch:SI 3 "r")]
16940 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16941 [(set (match_dup 3) (match_dup 2))
16942 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16943
16944 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16945 ;; Don't split NOTs with a displacement operand, because resulting XOR
16946 ;; will not be pairable anyway.
16947 ;;
16948 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16949 ;; represented using a modRM byte. The XOR replacement is long decoded,
16950 ;; so this split helps here as well.
16951 ;;
16952 ;; Note: Can't do this as a regular split because we can't get proper
16953 ;; lifetime information then.
16954
16955 (define_peephole2
16956 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16957 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16958 "optimize_insn_for_speed_p ()
16959 && ((TARGET_NOT_UNPAIRABLE
16960 && (!MEM_P (operands[0])
16961 || !memory_displacement_operand (operands[0], <MODE>mode)))
16962 || (TARGET_NOT_VECTORMODE
16963 && long_memory_operand (operands[0], <MODE>mode)))
16964 && peep2_regno_dead_p (0, FLAGS_REG)"
16965 [(parallel [(set (match_dup 0)
16966 (xor:SWI124 (match_dup 1) (const_int -1)))
16967 (clobber (reg:CC FLAGS_REG))])])
16968
16969 ;; Non pairable "test imm, reg" instructions can be translated to
16970 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16971 ;; byte opcode instead of two, have a short form for byte operands),
16972 ;; so do it for other CPUs as well. Given that the value was dead,
16973 ;; this should not create any new dependencies. Pass on the sub-word
16974 ;; versions if we're concerned about partial register stalls.
16975
16976 (define_peephole2
16977 [(set (match_operand 0 "flags_reg_operand")
16978 (match_operator 1 "compare_operator"
16979 [(and:SI (match_operand:SI 2 "register_operand")
16980 (match_operand:SI 3 "immediate_operand"))
16981 (const_int 0)]))]
16982 "ix86_match_ccmode (insn, CCNOmode)
16983 && (true_regnum (operands[2]) != AX_REG
16984 || satisfies_constraint_K (operands[3]))
16985 && peep2_reg_dead_p (1, operands[2])"
16986 [(parallel
16987 [(set (match_dup 0)
16988 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16989 (const_int 0)]))
16990 (set (match_dup 2)
16991 (and:SI (match_dup 2) (match_dup 3)))])])
16992
16993 ;; We don't need to handle HImode case, because it will be promoted to SImode
16994 ;; on ! TARGET_PARTIAL_REG_STALL
16995
16996 (define_peephole2
16997 [(set (match_operand 0 "flags_reg_operand")
16998 (match_operator 1 "compare_operator"
16999 [(and:QI (match_operand:QI 2 "register_operand")
17000 (match_operand:QI 3 "immediate_operand"))
17001 (const_int 0)]))]
17002 "! TARGET_PARTIAL_REG_STALL
17003 && ix86_match_ccmode (insn, CCNOmode)
17004 && true_regnum (operands[2]) != AX_REG
17005 && peep2_reg_dead_p (1, operands[2])"
17006 [(parallel
17007 [(set (match_dup 0)
17008 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17009 (const_int 0)]))
17010 (set (match_dup 2)
17011 (and:QI (match_dup 2) (match_dup 3)))])])
17012
17013 (define_peephole2
17014 [(set (match_operand 0 "flags_reg_operand")
17015 (match_operator 1 "compare_operator"
17016 [(and:SI
17017 (zero_extract:SI
17018 (match_operand 2 "ext_register_operand")
17019 (const_int 8)
17020 (const_int 8))
17021 (match_operand 3 "const_int_operand"))
17022 (const_int 0)]))]
17023 "! TARGET_PARTIAL_REG_STALL
17024 && ix86_match_ccmode (insn, CCNOmode)
17025 && true_regnum (operands[2]) != AX_REG
17026 && peep2_reg_dead_p (1, operands[2])"
17027 [(parallel [(set (match_dup 0)
17028 (match_op_dup 1
17029 [(and:SI
17030 (zero_extract:SI
17031 (match_dup 2)
17032 (const_int 8)
17033 (const_int 8))
17034 (match_dup 3))
17035 (const_int 0)]))
17036 (set (zero_extract:SI (match_dup 2)
17037 (const_int 8)
17038 (const_int 8))
17039 (and:SI
17040 (zero_extract:SI
17041 (match_dup 2)
17042 (const_int 8)
17043 (const_int 8))
17044 (match_dup 3)))])])
17045
17046 ;; Don't do logical operations with memory inputs.
17047 (define_peephole2
17048 [(match_scratch:SI 2 "r")
17049 (parallel [(set (match_operand:SI 0 "register_operand")
17050 (match_operator:SI 3 "arith_or_logical_operator"
17051 [(match_dup 0)
17052 (match_operand:SI 1 "memory_operand")]))
17053 (clobber (reg:CC FLAGS_REG))])]
17054 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17055 [(set (match_dup 2) (match_dup 1))
17056 (parallel [(set (match_dup 0)
17057 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17058 (clobber (reg:CC FLAGS_REG))])])
17059
17060 (define_peephole2
17061 [(match_scratch:SI 2 "r")
17062 (parallel [(set (match_operand:SI 0 "register_operand")
17063 (match_operator:SI 3 "arith_or_logical_operator"
17064 [(match_operand:SI 1 "memory_operand")
17065 (match_dup 0)]))
17066 (clobber (reg:CC FLAGS_REG))])]
17067 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17068 [(set (match_dup 2) (match_dup 1))
17069 (parallel [(set (match_dup 0)
17070 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17071 (clobber (reg:CC FLAGS_REG))])])
17072
17073 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17074 ;; refers to the destination of the load!
17075
17076 (define_peephole2
17077 [(set (match_operand:SI 0 "register_operand")
17078 (match_operand:SI 1 "register_operand"))
17079 (parallel [(set (match_dup 0)
17080 (match_operator:SI 3 "commutative_operator"
17081 [(match_dup 0)
17082 (match_operand:SI 2 "memory_operand")]))
17083 (clobber (reg:CC FLAGS_REG))])]
17084 "REGNO (operands[0]) != REGNO (operands[1])
17085 && GENERAL_REGNO_P (REGNO (operands[0]))
17086 && GENERAL_REGNO_P (REGNO (operands[1]))"
17087 [(set (match_dup 0) (match_dup 4))
17088 (parallel [(set (match_dup 0)
17089 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17090 (clobber (reg:CC FLAGS_REG))])]
17091 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17092
17093 (define_peephole2
17094 [(set (match_operand 0 "register_operand")
17095 (match_operand 1 "register_operand"))
17096 (set (match_dup 0)
17097 (match_operator 3 "commutative_operator"
17098 [(match_dup 0)
17099 (match_operand 2 "memory_operand")]))]
17100 "REGNO (operands[0]) != REGNO (operands[1])
17101 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17102 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17103 [(set (match_dup 0) (match_dup 2))
17104 (set (match_dup 0)
17105 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17106
17107 ; Don't do logical operations with memory outputs
17108 ;
17109 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17110 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17111 ; the same decoder scheduling characteristics as the original.
17112
17113 (define_peephole2
17114 [(match_scratch:SI 2 "r")
17115 (parallel [(set (match_operand:SI 0 "memory_operand")
17116 (match_operator:SI 3 "arith_or_logical_operator"
17117 [(match_dup 0)
17118 (match_operand:SI 1 "nonmemory_operand")]))
17119 (clobber (reg:CC FLAGS_REG))])]
17120 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17121 /* Do not split stack checking probes. */
17122 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17123 [(set (match_dup 2) (match_dup 0))
17124 (parallel [(set (match_dup 2)
17125 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17126 (clobber (reg:CC FLAGS_REG))])
17127 (set (match_dup 0) (match_dup 2))])
17128
17129 (define_peephole2
17130 [(match_scratch:SI 2 "r")
17131 (parallel [(set (match_operand:SI 0 "memory_operand")
17132 (match_operator:SI 3 "arith_or_logical_operator"
17133 [(match_operand:SI 1 "nonmemory_operand")
17134 (match_dup 0)]))
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17137 /* Do not split stack checking probes. */
17138 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17139 [(set (match_dup 2) (match_dup 0))
17140 (parallel [(set (match_dup 2)
17141 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17142 (clobber (reg:CC FLAGS_REG))])
17143 (set (match_dup 0) (match_dup 2))])
17144
17145 ;; Attempt to use arith or logical operations with memory outputs with
17146 ;; setting of flags.
17147 (define_peephole2
17148 [(set (match_operand:SWI 0 "register_operand")
17149 (match_operand:SWI 1 "memory_operand"))
17150 (parallel [(set (match_dup 0)
17151 (match_operator:SWI 3 "plusminuslogic_operator"
17152 [(match_dup 0)
17153 (match_operand:SWI 2 "<nonmemory_operand>")]))
17154 (clobber (reg:CC FLAGS_REG))])
17155 (set (match_dup 1) (match_dup 0))
17156 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17157 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17158 && peep2_reg_dead_p (4, operands[0])
17159 && !reg_overlap_mentioned_p (operands[0], operands[1])
17160 && (<MODE>mode != QImode
17161 || immediate_operand (operands[2], QImode)
17162 || q_regs_operand (operands[2], QImode))
17163 && ix86_match_ccmode (peep2_next_insn (3),
17164 (GET_CODE (operands[3]) == PLUS
17165 || GET_CODE (operands[3]) == MINUS)
17166 ? CCGOCmode : CCNOmode)"
17167 [(parallel [(set (match_dup 4) (match_dup 5))
17168 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17169 (match_dup 2)]))])]
17170 {
17171 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17172 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17173 copy_rtx (operands[1]),
17174 copy_rtx (operands[2]));
17175 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17176 operands[5], const0_rtx);
17177 })
17178
17179 (define_peephole2
17180 [(parallel [(set (match_operand:SWI 0 "register_operand")
17181 (match_operator:SWI 2 "plusminuslogic_operator"
17182 [(match_dup 0)
17183 (match_operand:SWI 1 "memory_operand")]))
17184 (clobber (reg:CC FLAGS_REG))])
17185 (set (match_dup 1) (match_dup 0))
17186 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17187 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17188 && GET_CODE (operands[2]) != MINUS
17189 && peep2_reg_dead_p (3, operands[0])
17190 && !reg_overlap_mentioned_p (operands[0], operands[1])
17191 && ix86_match_ccmode (peep2_next_insn (2),
17192 GET_CODE (operands[2]) == PLUS
17193 ? CCGOCmode : CCNOmode)"
17194 [(parallel [(set (match_dup 3) (match_dup 4))
17195 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17196 (match_dup 0)]))])]
17197 {
17198 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17199 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17200 copy_rtx (operands[1]),
17201 copy_rtx (operands[0]));
17202 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17203 operands[4], const0_rtx);
17204 })
17205
17206 (define_peephole2
17207 [(set (match_operand:SWI12 0 "register_operand")
17208 (match_operand:SWI12 1 "memory_operand"))
17209 (parallel [(set (match_operand:SI 4 "register_operand")
17210 (match_operator:SI 3 "plusminuslogic_operator"
17211 [(match_dup 4)
17212 (match_operand:SI 2 "nonmemory_operand")]))
17213 (clobber (reg:CC FLAGS_REG))])
17214 (set (match_dup 1) (match_dup 0))
17215 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17216 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17217 && REG_P (operands[0]) && REG_P (operands[4])
17218 && REGNO (operands[0]) == REGNO (operands[4])
17219 && peep2_reg_dead_p (4, operands[0])
17220 && (<MODE>mode != QImode
17221 || immediate_operand (operands[2], SImode)
17222 || q_regs_operand (operands[2], SImode))
17223 && !reg_overlap_mentioned_p (operands[0], operands[1])
17224 && ix86_match_ccmode (peep2_next_insn (3),
17225 (GET_CODE (operands[3]) == PLUS
17226 || GET_CODE (operands[3]) == MINUS)
17227 ? CCGOCmode : CCNOmode)"
17228 [(parallel [(set (match_dup 4) (match_dup 5))
17229 (set (match_dup 1) (match_dup 6))])]
17230 {
17231 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17232 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17233 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17234 copy_rtx (operands[1]), operands[2]);
17235 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17236 operands[5], const0_rtx);
17237 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17238 copy_rtx (operands[1]),
17239 copy_rtx (operands[2]));
17240 })
17241
17242 ;; Attempt to always use XOR for zeroing registers.
17243 (define_peephole2
17244 [(set (match_operand 0 "register_operand")
17245 (match_operand 1 "const0_operand"))]
17246 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17247 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17248 && GENERAL_REG_P (operands[0])
17249 && peep2_regno_dead_p (0, FLAGS_REG)"
17250 [(parallel [(set (match_dup 0) (const_int 0))
17251 (clobber (reg:CC FLAGS_REG))])]
17252 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17253
17254 (define_peephole2
17255 [(set (strict_low_part (match_operand 0 "register_operand"))
17256 (const_int 0))]
17257 "(GET_MODE (operands[0]) == QImode
17258 || GET_MODE (operands[0]) == HImode)
17259 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17260 && peep2_regno_dead_p (0, FLAGS_REG)"
17261 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17262 (clobber (reg:CC FLAGS_REG))])])
17263
17264 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17265 (define_peephole2
17266 [(set (match_operand:SWI248 0 "register_operand")
17267 (const_int -1))]
17268 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17269 && peep2_regno_dead_p (0, FLAGS_REG)"
17270 [(parallel [(set (match_dup 0) (const_int -1))
17271 (clobber (reg:CC FLAGS_REG))])]
17272 {
17273 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17274 operands[0] = gen_lowpart (SImode, operands[0]);
17275 })
17276
17277 ;; Attempt to convert simple lea to add/shift.
17278 ;; These can be created by move expanders.
17279
17280 (define_peephole2
17281 [(set (match_operand:SWI48 0 "register_operand")
17282 (plus:SWI48 (match_dup 0)
17283 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17284 "peep2_regno_dead_p (0, FLAGS_REG)"
17285 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17286 (clobber (reg:CC FLAGS_REG))])])
17287
17288 (define_peephole2
17289 [(set (match_operand:SWI48 0 "register_operand")
17290 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17291 (match_dup 0)))]
17292 "peep2_regno_dead_p (0, FLAGS_REG)"
17293 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17294 (clobber (reg:CC FLAGS_REG))])])
17295
17296 (define_peephole2
17297 [(set (match_operand:SI 0 "register_operand")
17298 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17299 (match_operand:DI 2 "nonmemory_operand")) 0))]
17300 "TARGET_64BIT
17301 && peep2_regno_dead_p (0, FLAGS_REG)
17302 && REGNO (operands[0]) == REGNO (operands[1])"
17303 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17304 (clobber (reg:CC FLAGS_REG))])]
17305 "operands[2] = gen_lowpart (SImode, operands[2]);")
17306
17307 (define_peephole2
17308 [(set (match_operand:SI 0 "register_operand")
17309 (subreg:SI (plus:DI (match_operand:DI 1 "nonmemory_operand")
17310 (match_operand:DI 2 "register_operand")) 0))]
17311 "TARGET_64BIT
17312 && peep2_regno_dead_p (0, FLAGS_REG)
17313 && REGNO (operands[0]) == REGNO (operands[2])"
17314 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17315 (clobber (reg:CC FLAGS_REG))])]
17316 "operands[1] = gen_lowpart (SImode, operands[1]);")
17317
17318 (define_peephole2
17319 [(set (match_operand:SWI48 0 "register_operand")
17320 (mult:SWI48 (match_dup 0)
17321 (match_operand:SWI48 1 "const_int_operand")))]
17322 "exact_log2 (INTVAL (operands[1])) >= 0
17323 && peep2_regno_dead_p (0, FLAGS_REG)"
17324 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17325 (clobber (reg:CC FLAGS_REG))])]
17326 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17327
17328 (define_peephole2
17329 [(set (match_operand:SI 0 "register_operand")
17330 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17331 (match_operand:DI 2 "const_int_operand")) 0))]
17332 "TARGET_64BIT
17333 && exact_log2 (INTVAL (operands[2])) >= 0
17334 && REGNO (operands[0]) == REGNO (operands[1])
17335 && peep2_regno_dead_p (0, FLAGS_REG)"
17336 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17337 (clobber (reg:CC FLAGS_REG))])]
17338 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17339
17340 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17341 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17342 ;; On many CPUs it is also faster, since special hardware to avoid esp
17343 ;; dependencies is present.
17344
17345 ;; While some of these conversions may be done using splitters, we use
17346 ;; peepholes in order to allow combine_stack_adjustments pass to see
17347 ;; nonobfuscated RTL.
17348
17349 ;; Convert prologue esp subtractions to push.
17350 ;; We need register to push. In order to keep verify_flow_info happy we have
17351 ;; two choices
17352 ;; - use scratch and clobber it in order to avoid dependencies
17353 ;; - use already live register
17354 ;; We can't use the second way right now, since there is no reliable way how to
17355 ;; verify that given register is live. First choice will also most likely in
17356 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17357 ;; call clobbered registers are dead. We may want to use base pointer as an
17358 ;; alternative when no register is available later.
17359
17360 (define_peephole2
17361 [(match_scratch:W 1 "r")
17362 (parallel [(set (reg:P SP_REG)
17363 (plus:P (reg:P SP_REG)
17364 (match_operand:P 0 "const_int_operand")))
17365 (clobber (reg:CC FLAGS_REG))
17366 (clobber (mem:BLK (scratch)))])]
17367 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17368 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17369 [(clobber (match_dup 1))
17370 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17371 (clobber (mem:BLK (scratch)))])])
17372
17373 (define_peephole2
17374 [(match_scratch:W 1 "r")
17375 (parallel [(set (reg:P SP_REG)
17376 (plus:P (reg:P SP_REG)
17377 (match_operand:P 0 "const_int_operand")))
17378 (clobber (reg:CC FLAGS_REG))
17379 (clobber (mem:BLK (scratch)))])]
17380 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17381 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17382 [(clobber (match_dup 1))
17383 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17384 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17385 (clobber (mem:BLK (scratch)))])])
17386
17387 ;; Convert esp subtractions to push.
17388 (define_peephole2
17389 [(match_scratch:W 1 "r")
17390 (parallel [(set (reg:P SP_REG)
17391 (plus:P (reg:P SP_REG)
17392 (match_operand:P 0 "const_int_operand")))
17393 (clobber (reg:CC FLAGS_REG))])]
17394 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17395 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17396 [(clobber (match_dup 1))
17397 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17398
17399 (define_peephole2
17400 [(match_scratch:W 1 "r")
17401 (parallel [(set (reg:P SP_REG)
17402 (plus:P (reg:P SP_REG)
17403 (match_operand:P 0 "const_int_operand")))
17404 (clobber (reg:CC FLAGS_REG))])]
17405 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17406 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17407 [(clobber (match_dup 1))
17408 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17409 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17410
17411 ;; Convert epilogue deallocator to pop.
17412 (define_peephole2
17413 [(match_scratch:W 1 "r")
17414 (parallel [(set (reg:P SP_REG)
17415 (plus:P (reg:P SP_REG)
17416 (match_operand:P 0 "const_int_operand")))
17417 (clobber (reg:CC FLAGS_REG))
17418 (clobber (mem:BLK (scratch)))])]
17419 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17420 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17421 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17422 (clobber (mem:BLK (scratch)))])])
17423
17424 ;; Two pops case is tricky, since pop causes dependency
17425 ;; on destination register. We use two registers if available.
17426 (define_peephole2
17427 [(match_scratch:W 1 "r")
17428 (match_scratch:W 2 "r")
17429 (parallel [(set (reg:P SP_REG)
17430 (plus:P (reg:P SP_REG)
17431 (match_operand:P 0 "const_int_operand")))
17432 (clobber (reg:CC FLAGS_REG))
17433 (clobber (mem:BLK (scratch)))])]
17434 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17435 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17436 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17437 (clobber (mem:BLK (scratch)))])
17438 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17439
17440 (define_peephole2
17441 [(match_scratch:W 1 "r")
17442 (parallel [(set (reg:P SP_REG)
17443 (plus:P (reg:P SP_REG)
17444 (match_operand:P 0 "const_int_operand")))
17445 (clobber (reg:CC FLAGS_REG))
17446 (clobber (mem:BLK (scratch)))])]
17447 "optimize_insn_for_size_p ()
17448 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17449 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17450 (clobber (mem:BLK (scratch)))])
17451 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17452
17453 ;; Convert esp additions to pop.
17454 (define_peephole2
17455 [(match_scratch:W 1 "r")
17456 (parallel [(set (reg:P SP_REG)
17457 (plus:P (reg:P SP_REG)
17458 (match_operand:P 0 "const_int_operand")))
17459 (clobber (reg:CC FLAGS_REG))])]
17460 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17461 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17462
17463 ;; Two pops case is tricky, since pop causes dependency
17464 ;; on destination register. We use two registers if available.
17465 (define_peephole2
17466 [(match_scratch:W 1 "r")
17467 (match_scratch:W 2 "r")
17468 (parallel [(set (reg:P SP_REG)
17469 (plus:P (reg:P SP_REG)
17470 (match_operand:P 0 "const_int_operand")))
17471 (clobber (reg:CC FLAGS_REG))])]
17472 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17473 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17474 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17475
17476 (define_peephole2
17477 [(match_scratch:W 1 "r")
17478 (parallel [(set (reg:P SP_REG)
17479 (plus:P (reg:P SP_REG)
17480 (match_operand:P 0 "const_int_operand")))
17481 (clobber (reg:CC FLAGS_REG))])]
17482 "optimize_insn_for_size_p ()
17483 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17484 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17485 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17486 \f
17487 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17488 ;; required and register dies. Similarly for 128 to -128.
17489 (define_peephole2
17490 [(set (match_operand 0 "flags_reg_operand")
17491 (match_operator 1 "compare_operator"
17492 [(match_operand 2 "register_operand")
17493 (match_operand 3 "const_int_operand")]))]
17494 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17495 && incdec_operand (operands[3], GET_MODE (operands[3])))
17496 || (!TARGET_FUSE_CMP_AND_BRANCH
17497 && INTVAL (operands[3]) == 128))
17498 && ix86_match_ccmode (insn, CCGCmode)
17499 && peep2_reg_dead_p (1, operands[2])"
17500 [(parallel [(set (match_dup 0)
17501 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17502 (clobber (match_dup 2))])])
17503 \f
17504 ;; Convert imul by three, five and nine into lea
17505 (define_peephole2
17506 [(parallel
17507 [(set (match_operand:SWI48 0 "register_operand")
17508 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17509 (match_operand:SWI48 2 "const359_operand")))
17510 (clobber (reg:CC FLAGS_REG))])]
17511 "!TARGET_PARTIAL_REG_STALL
17512 || <MODE>mode == SImode
17513 || optimize_function_for_size_p (cfun)"
17514 [(set (match_dup 0)
17515 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17516 (match_dup 1)))]
17517 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17518
17519 (define_peephole2
17520 [(parallel
17521 [(set (match_operand:SWI48 0 "register_operand")
17522 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17523 (match_operand:SWI48 2 "const359_operand")))
17524 (clobber (reg:CC FLAGS_REG))])]
17525 "optimize_insn_for_speed_p ()
17526 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17527 [(set (match_dup 0) (match_dup 1))
17528 (set (match_dup 0)
17529 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17530 (match_dup 0)))]
17531 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17532
17533 ;; imul $32bit_imm, mem, reg is vector decoded, while
17534 ;; imul $32bit_imm, reg, reg is direct decoded.
17535 (define_peephole2
17536 [(match_scratch:SWI48 3 "r")
17537 (parallel [(set (match_operand:SWI48 0 "register_operand")
17538 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17539 (match_operand:SWI48 2 "immediate_operand")))
17540 (clobber (reg:CC FLAGS_REG))])]
17541 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17542 && !satisfies_constraint_K (operands[2])"
17543 [(set (match_dup 3) (match_dup 1))
17544 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17545 (clobber (reg:CC FLAGS_REG))])])
17546
17547 (define_peephole2
17548 [(match_scratch:SI 3 "r")
17549 (parallel [(set (match_operand:DI 0 "register_operand")
17550 (zero_extend:DI
17551 (mult:SI (match_operand:SI 1 "memory_operand")
17552 (match_operand:SI 2 "immediate_operand"))))
17553 (clobber (reg:CC FLAGS_REG))])]
17554 "TARGET_64BIT
17555 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17556 && !satisfies_constraint_K (operands[2])"
17557 [(set (match_dup 3) (match_dup 1))
17558 (parallel [(set (match_dup 0)
17559 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17560 (clobber (reg:CC FLAGS_REG))])])
17561
17562 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17563 ;; Convert it into imul reg, reg
17564 ;; It would be better to force assembler to encode instruction using long
17565 ;; immediate, but there is apparently no way to do so.
17566 (define_peephole2
17567 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17568 (mult:SWI248
17569 (match_operand:SWI248 1 "nonimmediate_operand")
17570 (match_operand:SWI248 2 "const_int_operand")))
17571 (clobber (reg:CC FLAGS_REG))])
17572 (match_scratch:SWI248 3 "r")]
17573 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17574 && satisfies_constraint_K (operands[2])"
17575 [(set (match_dup 3) (match_dup 2))
17576 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17577 (clobber (reg:CC FLAGS_REG))])]
17578 {
17579 if (!rtx_equal_p (operands[0], operands[1]))
17580 emit_move_insn (operands[0], operands[1]);
17581 })
17582
17583 ;; After splitting up read-modify operations, array accesses with memory
17584 ;; operands might end up in form:
17585 ;; sall $2, %eax
17586 ;; movl 4(%esp), %edx
17587 ;; addl %edx, %eax
17588 ;; instead of pre-splitting:
17589 ;; sall $2, %eax
17590 ;; addl 4(%esp), %eax
17591 ;; Turn it into:
17592 ;; movl 4(%esp), %edx
17593 ;; leal (%edx,%eax,4), %eax
17594
17595 (define_peephole2
17596 [(match_scratch:W 5 "r")
17597 (parallel [(set (match_operand 0 "register_operand")
17598 (ashift (match_operand 1 "register_operand")
17599 (match_operand 2 "const_int_operand")))
17600 (clobber (reg:CC FLAGS_REG))])
17601 (parallel [(set (match_operand 3 "register_operand")
17602 (plus (match_dup 0)
17603 (match_operand 4 "x86_64_general_operand")))
17604 (clobber (reg:CC FLAGS_REG))])]
17605 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17606 /* Validate MODE for lea. */
17607 && ((!TARGET_PARTIAL_REG_STALL
17608 && (GET_MODE (operands[0]) == QImode
17609 || GET_MODE (operands[0]) == HImode))
17610 || GET_MODE (operands[0]) == SImode
17611 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17612 && (rtx_equal_p (operands[0], operands[3])
17613 || peep2_reg_dead_p (2, operands[0]))
17614 /* We reorder load and the shift. */
17615 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17616 [(set (match_dup 5) (match_dup 4))
17617 (set (match_dup 0) (match_dup 1))]
17618 {
17619 enum machine_mode op1mode = GET_MODE (operands[1]);
17620 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17621 int scale = 1 << INTVAL (operands[2]);
17622 rtx index = gen_lowpart (word_mode, operands[1]);
17623 rtx base = gen_lowpart (word_mode, operands[5]);
17624 rtx dest = gen_lowpart (mode, operands[3]);
17625
17626 operands[1] = gen_rtx_PLUS (word_mode, base,
17627 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17628 operands[5] = base;
17629 if (mode != word_mode)
17630 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17631 if (op1mode != word_mode)
17632 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17633 operands[0] = dest;
17634 })
17635 \f
17636 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17637 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17638 ;; caught for use by garbage collectors and the like. Using an insn that
17639 ;; maps to SIGILL makes it more likely the program will rightfully die.
17640 ;; Keeping with tradition, "6" is in honor of #UD.
17641 (define_insn "trap"
17642 [(trap_if (const_int 1) (const_int 6))]
17643 ""
17644 { return ASM_SHORT "0x0b0f"; }
17645 [(set_attr "length" "2")])
17646
17647 (define_expand "prefetch"
17648 [(prefetch (match_operand 0 "address_operand")
17649 (match_operand:SI 1 "const_int_operand")
17650 (match_operand:SI 2 "const_int_operand"))]
17651 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17652 {
17653 int rw = INTVAL (operands[1]);
17654 int locality = INTVAL (operands[2]);
17655
17656 gcc_assert (rw == 0 || rw == 1);
17657 gcc_assert (locality >= 0 && locality <= 3);
17658 gcc_assert (GET_MODE (operands[0]) == Pmode
17659 || GET_MODE (operands[0]) == VOIDmode);
17660
17661 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17662 supported by SSE counterpart or the SSE prefetch is not available
17663 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17664 of locality. */
17665 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17666 operands[2] = GEN_INT (3);
17667 else
17668 operands[1] = const0_rtx;
17669 })
17670
17671 (define_insn "*prefetch_sse_<mode>"
17672 [(prefetch (match_operand:P 0 "address_operand" "p")
17673 (const_int 0)
17674 (match_operand:SI 1 "const_int_operand"))]
17675 "TARGET_PREFETCH_SSE"
17676 {
17677 static const char * const patterns[4] = {
17678 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17679 };
17680
17681 int locality = INTVAL (operands[1]);
17682 gcc_assert (locality >= 0 && locality <= 3);
17683
17684 return patterns[locality];
17685 }
17686 [(set_attr "type" "sse")
17687 (set_attr "atom_sse_attr" "prefetch")
17688 (set (attr "length_address")
17689 (symbol_ref "memory_address_length (operands[0])"))
17690 (set_attr "memory" "none")])
17691
17692 (define_insn "*prefetch_3dnow_<mode>"
17693 [(prefetch (match_operand:P 0 "address_operand" "p")
17694 (match_operand:SI 1 "const_int_operand" "n")
17695 (const_int 3))]
17696 "TARGET_3DNOW"
17697 {
17698 if (INTVAL (operands[1]) == 0)
17699 return "prefetch\t%a0";
17700 else
17701 return "prefetchw\t%a0";
17702 }
17703 [(set_attr "type" "mmx")
17704 (set (attr "length_address")
17705 (symbol_ref "memory_address_length (operands[0])"))
17706 (set_attr "memory" "none")])
17707
17708 (define_expand "stack_protect_set"
17709 [(match_operand 0 "memory_operand")
17710 (match_operand 1 "memory_operand")]
17711 ""
17712 {
17713 rtx (*insn)(rtx, rtx);
17714
17715 #ifdef TARGET_THREAD_SSP_OFFSET
17716 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17717 insn = (TARGET_LP64
17718 ? gen_stack_tls_protect_set_di
17719 : gen_stack_tls_protect_set_si);
17720 #else
17721 insn = (TARGET_LP64
17722 ? gen_stack_protect_set_di
17723 : gen_stack_protect_set_si);
17724 #endif
17725
17726 emit_insn (insn (operands[0], operands[1]));
17727 DONE;
17728 })
17729
17730 (define_insn "stack_protect_set_<mode>"
17731 [(set (match_operand:PTR 0 "memory_operand" "=m")
17732 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17733 UNSPEC_SP_SET))
17734 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17735 (clobber (reg:CC FLAGS_REG))]
17736 ""
17737 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17738 [(set_attr "type" "multi")])
17739
17740 (define_insn "stack_tls_protect_set_<mode>"
17741 [(set (match_operand:PTR 0 "memory_operand" "=m")
17742 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17743 UNSPEC_SP_TLS_SET))
17744 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17745 (clobber (reg:CC FLAGS_REG))]
17746 ""
17747 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17748 [(set_attr "type" "multi")])
17749
17750 (define_expand "stack_protect_test"
17751 [(match_operand 0 "memory_operand")
17752 (match_operand 1 "memory_operand")
17753 (match_operand 2)]
17754 ""
17755 {
17756 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17757
17758 rtx (*insn)(rtx, rtx, rtx);
17759
17760 #ifdef TARGET_THREAD_SSP_OFFSET
17761 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17762 insn = (TARGET_LP64
17763 ? gen_stack_tls_protect_test_di
17764 : gen_stack_tls_protect_test_si);
17765 #else
17766 insn = (TARGET_LP64
17767 ? gen_stack_protect_test_di
17768 : gen_stack_protect_test_si);
17769 #endif
17770
17771 emit_insn (insn (flags, operands[0], operands[1]));
17772
17773 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17774 flags, const0_rtx, operands[2]));
17775 DONE;
17776 })
17777
17778 (define_insn "stack_protect_test_<mode>"
17779 [(set (match_operand:CCZ 0 "flags_reg_operand")
17780 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17781 (match_operand:PTR 2 "memory_operand" "m")]
17782 UNSPEC_SP_TEST))
17783 (clobber (match_scratch:PTR 3 "=&r"))]
17784 ""
17785 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17786 [(set_attr "type" "multi")])
17787
17788 (define_insn "stack_tls_protect_test_<mode>"
17789 [(set (match_operand:CCZ 0 "flags_reg_operand")
17790 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17791 (match_operand:PTR 2 "const_int_operand" "i")]
17792 UNSPEC_SP_TLS_TEST))
17793 (clobber (match_scratch:PTR 3 "=r"))]
17794 ""
17795 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17796 [(set_attr "type" "multi")])
17797
17798 (define_insn "sse4_2_crc32<mode>"
17799 [(set (match_operand:SI 0 "register_operand" "=r")
17800 (unspec:SI
17801 [(match_operand:SI 1 "register_operand" "0")
17802 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17803 UNSPEC_CRC32))]
17804 "TARGET_SSE4_2 || TARGET_CRC32"
17805 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17806 [(set_attr "type" "sselog1")
17807 (set_attr "prefix_rep" "1")
17808 (set_attr "prefix_extra" "1")
17809 (set (attr "prefix_data16")
17810 (if_then_else (match_operand:HI 2)
17811 (const_string "1")
17812 (const_string "*")))
17813 (set (attr "prefix_rex")
17814 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17815 (const_string "1")
17816 (const_string "*")))
17817 (set_attr "mode" "SI")])
17818
17819 (define_insn "sse4_2_crc32di"
17820 [(set (match_operand:DI 0 "register_operand" "=r")
17821 (unspec:DI
17822 [(match_operand:DI 1 "register_operand" "0")
17823 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17824 UNSPEC_CRC32))]
17825 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17826 "crc32{q}\t{%2, %0|%0, %2}"
17827 [(set_attr "type" "sselog1")
17828 (set_attr "prefix_rep" "1")
17829 (set_attr "prefix_extra" "1")
17830 (set_attr "mode" "DI")])
17831
17832 (define_expand "rdpmc"
17833 [(match_operand:DI 0 "register_operand")
17834 (match_operand:SI 1 "register_operand")]
17835 ""
17836 {
17837 rtx reg = gen_reg_rtx (DImode);
17838 rtx si;
17839
17840 /* Force operand 1 into ECX. */
17841 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17842 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17843 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17844 UNSPECV_RDPMC);
17845
17846 if (TARGET_64BIT)
17847 {
17848 rtvec vec = rtvec_alloc (2);
17849 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17850 rtx upper = gen_reg_rtx (DImode);
17851 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17852 gen_rtvec (1, const0_rtx),
17853 UNSPECV_RDPMC);
17854 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17855 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17856 emit_insn (load);
17857 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17858 NULL, 1, OPTAB_DIRECT);
17859 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17860 OPTAB_DIRECT);
17861 }
17862 else
17863 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17864 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17865 DONE;
17866 })
17867
17868 (define_insn "*rdpmc"
17869 [(set (match_operand:DI 0 "register_operand" "=A")
17870 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17871 UNSPECV_RDPMC))]
17872 "!TARGET_64BIT"
17873 "rdpmc"
17874 [(set_attr "type" "other")
17875 (set_attr "length" "2")])
17876
17877 (define_insn "*rdpmc_rex64"
17878 [(set (match_operand:DI 0 "register_operand" "=a")
17879 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17880 UNSPECV_RDPMC))
17881 (set (match_operand:DI 1 "register_operand" "=d")
17882 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17883 "TARGET_64BIT"
17884 "rdpmc"
17885 [(set_attr "type" "other")
17886 (set_attr "length" "2")])
17887
17888 (define_expand "rdtsc"
17889 [(set (match_operand:DI 0 "register_operand")
17890 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17891 ""
17892 {
17893 if (TARGET_64BIT)
17894 {
17895 rtvec vec = rtvec_alloc (2);
17896 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17897 rtx upper = gen_reg_rtx (DImode);
17898 rtx lower = gen_reg_rtx (DImode);
17899 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17900 gen_rtvec (1, const0_rtx),
17901 UNSPECV_RDTSC);
17902 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17903 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17904 emit_insn (load);
17905 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17906 NULL, 1, OPTAB_DIRECT);
17907 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17908 OPTAB_DIRECT);
17909 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17910 DONE;
17911 }
17912 })
17913
17914 (define_insn "*rdtsc"
17915 [(set (match_operand:DI 0 "register_operand" "=A")
17916 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17917 "!TARGET_64BIT"
17918 "rdtsc"
17919 [(set_attr "type" "other")
17920 (set_attr "length" "2")])
17921
17922 (define_insn "*rdtsc_rex64"
17923 [(set (match_operand:DI 0 "register_operand" "=a")
17924 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17925 (set (match_operand:DI 1 "register_operand" "=d")
17926 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17927 "TARGET_64BIT"
17928 "rdtsc"
17929 [(set_attr "type" "other")
17930 (set_attr "length" "2")])
17931
17932 (define_expand "rdtscp"
17933 [(match_operand:DI 0 "register_operand")
17934 (match_operand:SI 1 "memory_operand")]
17935 ""
17936 {
17937 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17938 gen_rtvec (1, const0_rtx),
17939 UNSPECV_RDTSCP);
17940 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17941 gen_rtvec (1, const0_rtx),
17942 UNSPECV_RDTSCP);
17943 rtx reg = gen_reg_rtx (DImode);
17944 rtx tmp = gen_reg_rtx (SImode);
17945
17946 if (TARGET_64BIT)
17947 {
17948 rtvec vec = rtvec_alloc (3);
17949 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17950 rtx upper = gen_reg_rtx (DImode);
17951 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17952 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17953 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17954 emit_insn (load);
17955 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17956 NULL, 1, OPTAB_DIRECT);
17957 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17958 OPTAB_DIRECT);
17959 }
17960 else
17961 {
17962 rtvec vec = rtvec_alloc (2);
17963 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17964 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17965 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17966 emit_insn (load);
17967 }
17968 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17969 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17970 DONE;
17971 })
17972
17973 (define_insn "*rdtscp"
17974 [(set (match_operand:DI 0 "register_operand" "=A")
17975 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17976 (set (match_operand:SI 1 "register_operand" "=c")
17977 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17978 "!TARGET_64BIT"
17979 "rdtscp"
17980 [(set_attr "type" "other")
17981 (set_attr "length" "3")])
17982
17983 (define_insn "*rdtscp_rex64"
17984 [(set (match_operand:DI 0 "register_operand" "=a")
17985 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17986 (set (match_operand:DI 1 "register_operand" "=d")
17987 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17988 (set (match_operand:SI 2 "register_operand" "=c")
17989 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17990 "TARGET_64BIT"
17991 "rdtscp"
17992 [(set_attr "type" "other")
17993 (set_attr "length" "3")])
17994
17995 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17996 ;;
17997 ;; LWP instructions
17998 ;;
17999 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18000
18001 (define_expand "lwp_llwpcb"
18002 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18003 UNSPECV_LLWP_INTRINSIC)]
18004 "TARGET_LWP")
18005
18006 (define_insn "*lwp_llwpcb<mode>1"
18007 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18008 UNSPECV_LLWP_INTRINSIC)]
18009 "TARGET_LWP"
18010 "llwpcb\t%0"
18011 [(set_attr "type" "lwp")
18012 (set_attr "mode" "<MODE>")
18013 (set_attr "length" "5")])
18014
18015 (define_expand "lwp_slwpcb"
18016 [(set (match_operand 0 "register_operand" "=r")
18017 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18018 "TARGET_LWP"
18019 {
18020 rtx (*insn)(rtx);
18021
18022 insn = (Pmode == DImode
18023 ? gen_lwp_slwpcbdi
18024 : gen_lwp_slwpcbsi);
18025
18026 emit_insn (insn (operands[0]));
18027 DONE;
18028 })
18029
18030 (define_insn "lwp_slwpcb<mode>"
18031 [(set (match_operand:P 0 "register_operand" "=r")
18032 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18033 "TARGET_LWP"
18034 "slwpcb\t%0"
18035 [(set_attr "type" "lwp")
18036 (set_attr "mode" "<MODE>")
18037 (set_attr "length" "5")])
18038
18039 (define_expand "lwp_lwpval<mode>3"
18040 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18041 (match_operand:SI 2 "nonimmediate_operand" "rm")
18042 (match_operand:SI 3 "const_int_operand" "i")]
18043 UNSPECV_LWPVAL_INTRINSIC)]
18044 "TARGET_LWP"
18045 ;; Avoid unused variable warning.
18046 "(void) operands[0];")
18047
18048 (define_insn "*lwp_lwpval<mode>3_1"
18049 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18050 (match_operand:SI 1 "nonimmediate_operand" "rm")
18051 (match_operand:SI 2 "const_int_operand" "i")]
18052 UNSPECV_LWPVAL_INTRINSIC)]
18053 "TARGET_LWP"
18054 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18055 [(set_attr "type" "lwp")
18056 (set_attr "mode" "<MODE>")
18057 (set (attr "length")
18058 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18059
18060 (define_expand "lwp_lwpins<mode>3"
18061 [(set (reg:CCC FLAGS_REG)
18062 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18063 (match_operand:SI 2 "nonimmediate_operand" "rm")
18064 (match_operand:SI 3 "const_int_operand" "i")]
18065 UNSPECV_LWPINS_INTRINSIC))
18066 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18067 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18068 "TARGET_LWP")
18069
18070 (define_insn "*lwp_lwpins<mode>3_1"
18071 [(set (reg:CCC FLAGS_REG)
18072 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18073 (match_operand:SI 1 "nonimmediate_operand" "rm")
18074 (match_operand:SI 2 "const_int_operand" "i")]
18075 UNSPECV_LWPINS_INTRINSIC))]
18076 "TARGET_LWP"
18077 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18078 [(set_attr "type" "lwp")
18079 (set_attr "mode" "<MODE>")
18080 (set (attr "length")
18081 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18082
18083 (define_int_iterator RDFSGSBASE
18084 [UNSPECV_RDFSBASE
18085 UNSPECV_RDGSBASE])
18086
18087 (define_int_iterator WRFSGSBASE
18088 [UNSPECV_WRFSBASE
18089 UNSPECV_WRGSBASE])
18090
18091 (define_int_attr fsgs
18092 [(UNSPECV_RDFSBASE "fs")
18093 (UNSPECV_RDGSBASE "gs")
18094 (UNSPECV_WRFSBASE "fs")
18095 (UNSPECV_WRGSBASE "gs")])
18096
18097 (define_insn "rd<fsgs>base<mode>"
18098 [(set (match_operand:SWI48 0 "register_operand" "=r")
18099 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18100 "TARGET_64BIT && TARGET_FSGSBASE"
18101 "rd<fsgs>base\t%0"
18102 [(set_attr "type" "other")
18103 (set_attr "prefix_extra" "2")])
18104
18105 (define_insn "wr<fsgs>base<mode>"
18106 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18107 WRFSGSBASE)]
18108 "TARGET_64BIT && TARGET_FSGSBASE"
18109 "wr<fsgs>base\t%0"
18110 [(set_attr "type" "other")
18111 (set_attr "prefix_extra" "2")])
18112
18113 (define_insn "rdrand<mode>_1"
18114 [(set (match_operand:SWI248 0 "register_operand" "=r")
18115 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18116 (set (reg:CCC FLAGS_REG)
18117 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18118 "TARGET_RDRND"
18119 "rdrand\t%0"
18120 [(set_attr "type" "other")
18121 (set_attr "prefix_extra" "1")])
18122
18123 (define_expand "pause"
18124 [(set (match_dup 0)
18125 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18126 ""
18127 {
18128 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18129 MEM_VOLATILE_P (operands[0]) = 1;
18130 })
18131
18132 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18133 ;; They have the same encoding.
18134 (define_insn "*pause"
18135 [(set (match_operand:BLK 0)
18136 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18137 ""
18138 "rep%; nop"
18139 [(set_attr "length" "2")
18140 (set_attr "memory" "unknown")])
18141
18142 (define_expand "xbegin"
18143 [(set (match_operand:SI 0 "register_operand")
18144 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18145 "TARGET_RTM"
18146 {
18147 rtx label = gen_label_rtx ();
18148
18149 operands[1] = force_reg (SImode, constm1_rtx);
18150
18151 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18152
18153 emit_label (label);
18154 LABEL_NUSES (label) = 1;
18155
18156 emit_move_insn (operands[0], operands[1]);
18157
18158 DONE;
18159 })
18160
18161 (define_insn "xbegin_1"
18162 [(set (pc)
18163 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18164 (const_int 0))
18165 (label_ref (match_operand 1))
18166 (pc)))
18167 (set (match_operand:SI 0 "register_operand" "+a")
18168 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18169 "TARGET_RTM"
18170 "xbegin\t%l1"
18171 [(set_attr "type" "other")
18172 (set_attr "length" "6")])
18173
18174 (define_insn "xend"
18175 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18176 "TARGET_RTM"
18177 "xend"
18178 [(set_attr "type" "other")
18179 (set_attr "length" "3")])
18180
18181 (define_insn "xabort"
18182 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18183 UNSPECV_XABORT)]
18184 "TARGET_RTM"
18185 "xabort\t%0"
18186 [(set_attr "type" "other")
18187 (set_attr "length" "3")])
18188
18189 (define_expand "xtest"
18190 [(set (match_operand:QI 0 "register_operand")
18191 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18192 "TARGET_RTM"
18193 {
18194 emit_insn (gen_xtest_1 ());
18195
18196 ix86_expand_setcc (operands[0], NE,
18197 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18198 DONE;
18199 })
18200
18201 (define_insn "xtest_1"
18202 [(set (reg:CCZ FLAGS_REG)
18203 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18204 "TARGET_RTM"
18205 "xtest"
18206 [(set_attr "type" "other")
18207 (set_attr "length" "3")])
18208
18209 (include "mmx.md")
18210 (include "sse.md")
18211 (include "sync.md")