i386.c (ix86_decompose_address): Use simplify_gen_subreg to generate SImode equivalen...
[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 UNSPECV_FXSAVE
206 UNSPECV_FXRSTOR
207 UNSPECV_FXSAVE64
208 UNSPECV_FXRSTOR64
209 UNSPECV_XSAVE
210 UNSPECV_XRSTOR
211 UNSPECV_XSAVE64
212 UNSPECV_XRSTOR64
213 UNSPECV_XSAVEOPT
214 UNSPECV_XSAVEOPT64
215
216 ;; For RDRAND support
217 UNSPECV_RDRAND
218
219 ;; For RDSEED support
220 UNSPECV_RDSEED
221
222 ;; For RTM support
223 UNSPECV_XBEGIN
224 UNSPECV_XEND
225 UNSPECV_XABORT
226 UNSPECV_XTEST
227 ])
228
229 ;; Constants to represent rounding modes in the ROUND instruction
230 (define_constants
231 [(ROUND_FLOOR 0x1)
232 (ROUND_CEIL 0x2)
233 (ROUND_TRUNC 0x3)
234 (ROUND_MXCSR 0x4)
235 (ROUND_NO_EXC 0x8)
236 ])
237
238 ;; Constants to represent pcomtrue/pcomfalse variants
239 (define_constants
240 [(PCOM_FALSE 0)
241 (PCOM_TRUE 1)
242 (COM_FALSE_S 2)
243 (COM_FALSE_P 3)
244 (COM_TRUE_S 4)
245 (COM_TRUE_P 5)
246 ])
247
248 ;; Constants used in the XOP pperm instruction
249 (define_constants
250 [(PPERM_SRC 0x00) /* copy source */
251 (PPERM_INVERT 0x20) /* invert source */
252 (PPERM_REVERSE 0x40) /* bit reverse source */
253 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
254 (PPERM_ZERO 0x80) /* all 0's */
255 (PPERM_ONES 0xa0) /* all 1's */
256 (PPERM_SIGN 0xc0) /* propagate sign bit */
257 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
258 (PPERM_SRC1 0x00) /* use first source byte */
259 (PPERM_SRC2 0x10) /* use second source byte */
260 ])
261
262 ;; Registers by name.
263 (define_constants
264 [(AX_REG 0)
265 (DX_REG 1)
266 (CX_REG 2)
267 (BX_REG 3)
268 (SI_REG 4)
269 (DI_REG 5)
270 (BP_REG 6)
271 (SP_REG 7)
272 (ST0_REG 8)
273 (ST1_REG 9)
274 (ST2_REG 10)
275 (ST3_REG 11)
276 (ST4_REG 12)
277 (ST5_REG 13)
278 (ST6_REG 14)
279 (ST7_REG 15)
280 (FLAGS_REG 17)
281 (FPSR_REG 18)
282 (FPCR_REG 19)
283 (XMM0_REG 21)
284 (XMM1_REG 22)
285 (XMM2_REG 23)
286 (XMM3_REG 24)
287 (XMM4_REG 25)
288 (XMM5_REG 26)
289 (XMM6_REG 27)
290 (XMM7_REG 28)
291 (MM0_REG 29)
292 (MM1_REG 30)
293 (MM2_REG 31)
294 (MM3_REG 32)
295 (MM4_REG 33)
296 (MM5_REG 34)
297 (MM6_REG 35)
298 (MM7_REG 36)
299 (R8_REG 37)
300 (R9_REG 38)
301 (R10_REG 39)
302 (R11_REG 40)
303 (R12_REG 41)
304 (R13_REG 42)
305 (XMM8_REG 45)
306 (XMM9_REG 46)
307 (XMM10_REG 47)
308 (XMM11_REG 48)
309 (XMM12_REG 49)
310 (XMM13_REG 50)
311 (XMM14_REG 51)
312 (XMM15_REG 52)
313 ])
314
315 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
316 ;; from i386.c.
317
318 ;; In C guard expressions, put expressions which may be compile-time
319 ;; constants first. This allows for better optimization. For
320 ;; example, write "TARGET_64BIT && reload_completed", not
321 ;; "reload_completed && TARGET_64BIT".
322
323 \f
324 ;; Processor type.
325 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
326 atom,generic64,amdfam10,bdver1,bdver2,btver1,btver2"
327 (const (symbol_ref "ix86_schedule")))
328
329 ;; A basic instruction type. Refinements due to arguments to be
330 ;; provided in other attributes.
331 (define_attr "type"
332 "other,multi,
333 alu,alu1,negnot,imov,imovx,lea,
334 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
335 icmp,test,ibr,setcc,icmov,
336 push,pop,call,callv,leave,
337 str,bitmanip,
338 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
339 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
340 sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
341 ssediv,sseins,ssemuladd,sse4arg,lwp,
342 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
343 (const_string "other"))
344
345 ;; Main data type used by the insn
346 (define_attr "mode"
347 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
348 (const_string "unknown"))
349
350 ;; The CPU unit operations uses.
351 (define_attr "unit" "integer,i387,sse,mmx,unknown"
352 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
353 (const_string "i387")
354 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
355 sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,
356 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
357 (const_string "sse")
358 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
359 (const_string "mmx")
360 (eq_attr "type" "other")
361 (const_string "unknown")]
362 (const_string "integer")))
363
364 ;; The (bounding maximum) length of an instruction immediate.
365 (define_attr "length_immediate" ""
366 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
367 bitmanip,imulx")
368 (const_int 0)
369 (eq_attr "unit" "i387,sse,mmx")
370 (const_int 0)
371 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
372 rotate,rotatex,rotate1,imul,icmp,push,pop")
373 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
374 (eq_attr "type" "imov,test")
375 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
376 (eq_attr "type" "call")
377 (if_then_else (match_operand 0 "constant_call_address_operand")
378 (const_int 4)
379 (const_int 0))
380 (eq_attr "type" "callv")
381 (if_then_else (match_operand 1 "constant_call_address_operand")
382 (const_int 4)
383 (const_int 0))
384 ;; We don't know the size before shorten_branches. Expect
385 ;; the instruction to fit for better scheduling.
386 (eq_attr "type" "ibr")
387 (const_int 1)
388 ]
389 (symbol_ref "/* Update immediate_length and other attributes! */
390 gcc_unreachable (),1")))
391
392 ;; The (bounding maximum) length of an instruction address.
393 (define_attr "length_address" ""
394 (cond [(eq_attr "type" "str,other,multi,fxch")
395 (const_int 0)
396 (and (eq_attr "type" "call")
397 (match_operand 0 "constant_call_address_operand"))
398 (const_int 0)
399 (and (eq_attr "type" "callv")
400 (match_operand 1 "constant_call_address_operand"))
401 (const_int 0)
402 ]
403 (symbol_ref "ix86_attr_length_address_default (insn)")))
404
405 ;; Set when length prefix is used.
406 (define_attr "prefix_data16" ""
407 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
408 (const_int 0)
409 (eq_attr "mode" "HI")
410 (const_int 1)
411 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
412 (const_int 1)
413 ]
414 (const_int 0)))
415
416 ;; Set when string REP prefix is used.
417 (define_attr "prefix_rep" ""
418 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
419 (const_int 0)
420 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
421 (const_int 1)
422 ]
423 (const_int 0)))
424
425 ;; Set when 0f opcode prefix is used.
426 (define_attr "prefix_0f" ""
427 (if_then_else
428 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
429 (eq_attr "unit" "sse,mmx"))
430 (const_int 1)
431 (const_int 0)))
432
433 ;; Set when REX opcode prefix is used.
434 (define_attr "prefix_rex" ""
435 (cond [(not (match_test "TARGET_64BIT"))
436 (const_int 0)
437 (and (eq_attr "mode" "DI")
438 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
439 (eq_attr "unit" "!mmx")))
440 (const_int 1)
441 (and (eq_attr "mode" "QI")
442 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
443 (const_int 1)
444 (match_test "x86_extended_reg_mentioned_p (insn)")
445 (const_int 1)
446 (and (eq_attr "type" "imovx")
447 (match_operand:QI 1 "ext_QIreg_operand"))
448 (const_int 1)
449 ]
450 (const_int 0)))
451
452 ;; There are also additional prefixes in 3DNOW, SSSE3.
453 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
454 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
455 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
456 (define_attr "prefix_extra" ""
457 (cond [(eq_attr "type" "ssemuladd,sse4arg")
458 (const_int 2)
459 (eq_attr "type" "sseiadd1,ssecvt1")
460 (const_int 1)
461 ]
462 (const_int 0)))
463
464 ;; Prefix used: original, VEX or maybe VEX.
465 (define_attr "prefix" "orig,vex,maybe_vex"
466 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
467 (const_string "vex")
468 (const_string "orig")))
469
470 ;; VEX W bit is used.
471 (define_attr "prefix_vex_w" "" (const_int 0))
472
473 ;; The length of VEX prefix
474 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
475 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
476 ;; still prefix_0f 1, with prefix_extra 1.
477 (define_attr "length_vex" ""
478 (if_then_else (and (eq_attr "prefix_0f" "1")
479 (eq_attr "prefix_extra" "0"))
480 (if_then_else (eq_attr "prefix_vex_w" "1")
481 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
482 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
483 (if_then_else (eq_attr "prefix_vex_w" "1")
484 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
485 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
486
487 ;; Set when modrm byte is used.
488 (define_attr "modrm" ""
489 (cond [(eq_attr "type" "str,leave")
490 (const_int 0)
491 (eq_attr "unit" "i387")
492 (const_int 0)
493 (and (eq_attr "type" "incdec")
494 (and (not (match_test "TARGET_64BIT"))
495 (ior (match_operand:SI 1 "register_operand")
496 (match_operand:HI 1 "register_operand"))))
497 (const_int 0)
498 (and (eq_attr "type" "push")
499 (not (match_operand 1 "memory_operand")))
500 (const_int 0)
501 (and (eq_attr "type" "pop")
502 (not (match_operand 0 "memory_operand")))
503 (const_int 0)
504 (and (eq_attr "type" "imov")
505 (and (not (eq_attr "mode" "DI"))
506 (ior (and (match_operand 0 "register_operand")
507 (match_operand 1 "immediate_operand"))
508 (ior (and (match_operand 0 "ax_reg_operand")
509 (match_operand 1 "memory_displacement_only_operand"))
510 (and (match_operand 0 "memory_displacement_only_operand")
511 (match_operand 1 "ax_reg_operand"))))))
512 (const_int 0)
513 (and (eq_attr "type" "call")
514 (match_operand 0 "constant_call_address_operand"))
515 (const_int 0)
516 (and (eq_attr "type" "callv")
517 (match_operand 1 "constant_call_address_operand"))
518 (const_int 0)
519 (and (eq_attr "type" "alu,alu1,icmp,test")
520 (match_operand 0 "ax_reg_operand"))
521 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
522 ]
523 (const_int 1)))
524
525 ;; The (bounding maximum) length of an instruction in bytes.
526 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
527 ;; Later we may want to split them and compute proper length as for
528 ;; other insns.
529 (define_attr "length" ""
530 (cond [(eq_attr "type" "other,multi,fistp,frndint")
531 (const_int 16)
532 (eq_attr "type" "fcmp")
533 (const_int 4)
534 (eq_attr "unit" "i387")
535 (plus (const_int 2)
536 (plus (attr "prefix_data16")
537 (attr "length_address")))
538 (ior (eq_attr "prefix" "vex")
539 (and (eq_attr "prefix" "maybe_vex")
540 (match_test "TARGET_AVX")))
541 (plus (attr "length_vex")
542 (plus (attr "length_immediate")
543 (plus (attr "modrm")
544 (attr "length_address"))))]
545 (plus (plus (attr "modrm")
546 (plus (attr "prefix_0f")
547 (plus (attr "prefix_rex")
548 (plus (attr "prefix_extra")
549 (const_int 1)))))
550 (plus (attr "prefix_rep")
551 (plus (attr "prefix_data16")
552 (plus (attr "length_immediate")
553 (attr "length_address")))))))
554
555 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
556 ;; `store' if there is a simple memory reference therein, or `unknown'
557 ;; if the instruction is complex.
558
559 (define_attr "memory" "none,load,store,both,unknown"
560 (cond [(eq_attr "type" "other,multi,str,lwp")
561 (const_string "unknown")
562 (eq_attr "type" "lea,fcmov,fpspc")
563 (const_string "none")
564 (eq_attr "type" "fistp,leave")
565 (const_string "both")
566 (eq_attr "type" "frndint")
567 (const_string "load")
568 (eq_attr "type" "push")
569 (if_then_else (match_operand 1 "memory_operand")
570 (const_string "both")
571 (const_string "store"))
572 (eq_attr "type" "pop")
573 (if_then_else (match_operand 0 "memory_operand")
574 (const_string "both")
575 (const_string "load"))
576 (eq_attr "type" "setcc")
577 (if_then_else (match_operand 0 "memory_operand")
578 (const_string "store")
579 (const_string "none"))
580 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
581 (if_then_else (ior (match_operand 0 "memory_operand")
582 (match_operand 1 "memory_operand"))
583 (const_string "load")
584 (const_string "none"))
585 (eq_attr "type" "ibr")
586 (if_then_else (match_operand 0 "memory_operand")
587 (const_string "load")
588 (const_string "none"))
589 (eq_attr "type" "call")
590 (if_then_else (match_operand 0 "constant_call_address_operand")
591 (const_string "none")
592 (const_string "load"))
593 (eq_attr "type" "callv")
594 (if_then_else (match_operand 1 "constant_call_address_operand")
595 (const_string "none")
596 (const_string "load"))
597 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
598 (match_operand 1 "memory_operand"))
599 (const_string "both")
600 (and (match_operand 0 "memory_operand")
601 (match_operand 1 "memory_operand"))
602 (const_string "both")
603 (match_operand 0 "memory_operand")
604 (const_string "store")
605 (match_operand 1 "memory_operand")
606 (const_string "load")
607 (and (eq_attr "type"
608 "!alu1,negnot,ishift1,
609 imov,imovx,icmp,test,bitmanip,
610 fmov,fcmp,fsgn,
611 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
612 sseadd1,sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
613 (match_operand 2 "memory_operand"))
614 (const_string "load")
615 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
616 (match_operand 3 "memory_operand"))
617 (const_string "load")
618 ]
619 (const_string "none")))
620
621 ;; Indicates if an instruction has both an immediate and a displacement.
622
623 (define_attr "imm_disp" "false,true,unknown"
624 (cond [(eq_attr "type" "other,multi")
625 (const_string "unknown")
626 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
627 (and (match_operand 0 "memory_displacement_operand")
628 (match_operand 1 "immediate_operand")))
629 (const_string "true")
630 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
631 (and (match_operand 0 "memory_displacement_operand")
632 (match_operand 2 "immediate_operand")))
633 (const_string "true")
634 ]
635 (const_string "false")))
636
637 ;; Indicates if an FP operation has an integer source.
638
639 (define_attr "fp_int_src" "false,true"
640 (const_string "false"))
641
642 ;; Defines rounding mode of an FP operation.
643
644 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
645 (const_string "any"))
646
647 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
648 (define_attr "use_carry" "0,1" (const_string "0"))
649
650 ;; Define attribute to indicate unaligned ssemov insns
651 (define_attr "movu" "0,1" (const_string "0"))
652
653 ;; Used to control the "enabled" attribute on a per-instruction basis.
654 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
655 avx2,noavx2,bmi2,fma,fma4"
656 (const_string "base"))
657
658 (define_attr "enabled" ""
659 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
660 (eq_attr "isa" "sse2_noavx")
661 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
662 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
663 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
664 (eq_attr "isa" "sse4_noavx")
665 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
666 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
667 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
668 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
669 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
670 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
671 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
672 ;; Fma instruction selection has to be done based on
673 ;; register pressure. For generating fma4, a cost model
674 ;; based on register pressure is required. Till then,
675 ;; fma4 instruction is disabled for targets that implement
676 ;; both fma and fma4 instruction sets.
677 (eq_attr "isa" "fma4")
678 (symbol_ref "TARGET_FMA4 && !TARGET_FMA")
679 ]
680 (const_int 1)))
681
682 ;; Describe a user's asm statement.
683 (define_asm_attributes
684 [(set_attr "length" "128")
685 (set_attr "type" "multi")])
686
687 (define_code_iterator plusminus [plus minus])
688
689 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690
691 ;; Base name for define_insn
692 (define_code_attr plusminus_insn
693 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
694 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695
696 ;; Base name for insn mnemonic.
697 (define_code_attr plusminus_mnemonic
698 [(plus "add") (ss_plus "adds") (us_plus "addus")
699 (minus "sub") (ss_minus "subs") (us_minus "subus")])
700 (define_code_attr plusminus_carry_mnemonic
701 [(plus "adc") (minus "sbb")])
702
703 ;; Mark commutative operators as such in constraints.
704 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
705 (minus "") (ss_minus "") (us_minus "")])
706
707 ;; Mapping of max and min
708 (define_code_iterator maxmin [smax smin umax umin])
709
710 ;; Mapping of signed max and min
711 (define_code_iterator smaxmin [smax smin])
712
713 ;; Mapping of unsigned max and min
714 (define_code_iterator umaxmin [umax umin])
715
716 ;; Base name for integer and FP insn mnemonic
717 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
718 (umax "maxu") (umin "minu")])
719 (define_code_attr maxmin_float [(smax "max") (smin "min")])
720
721 ;; Mapping of logic operators
722 (define_code_iterator any_logic [and ior xor])
723 (define_code_iterator any_or [ior xor])
724
725 ;; Base name for insn mnemonic.
726 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
727
728 ;; Mapping of logic-shift operators
729 (define_code_iterator any_lshift [ashift lshiftrt])
730
731 ;; Mapping of shift-right operators
732 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
733
734 ;; Mapping of all shift operators
735 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
736
737 ;; Base name for define_insn
738 (define_code_attr shift_insn
739 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
740
741 ;; Base name for insn mnemonic.
742 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
743 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
744
745 ;; Mapping of rotate operators
746 (define_code_iterator any_rotate [rotate rotatert])
747
748 ;; Base name for define_insn
749 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
750
751 ;; Base name for insn mnemonic.
752 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
753
754 ;; Mapping of abs neg operators
755 (define_code_iterator absneg [abs neg])
756
757 ;; Base name for x87 insn mnemonic.
758 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
759
760 ;; Used in signed and unsigned widening multiplications.
761 (define_code_iterator any_extend [sign_extend zero_extend])
762
763 ;; Prefix for insn menmonic.
764 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
765
766 ;; Prefix for define_insn
767 (define_code_attr u [(sign_extend "") (zero_extend "u")])
768 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
769 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
770
771 ;; All integer modes.
772 (define_mode_iterator SWI1248x [QI HI SI DI])
773
774 ;; All integer modes without QImode.
775 (define_mode_iterator SWI248x [HI SI DI])
776
777 ;; All integer modes without QImode and HImode.
778 (define_mode_iterator SWI48x [SI DI])
779
780 ;; All integer modes without SImode and DImode.
781 (define_mode_iterator SWI12 [QI HI])
782
783 ;; All integer modes without DImode.
784 (define_mode_iterator SWI124 [QI HI SI])
785
786 ;; All integer modes without QImode and DImode.
787 (define_mode_iterator SWI24 [HI SI])
788
789 ;; Single word integer modes.
790 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
791
792 ;; Single word integer modes without QImode.
793 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
794
795 ;; Single word integer modes without QImode and HImode.
796 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
797
798 ;; All math-dependant single and double word integer modes.
799 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
800 (HI "TARGET_HIMODE_MATH")
801 SI DI (TI "TARGET_64BIT")])
802
803 ;; Math-dependant single word integer modes.
804 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
805 (HI "TARGET_HIMODE_MATH")
806 SI (DI "TARGET_64BIT")])
807
808 ;; Math-dependant integer modes without DImode.
809 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
810 (HI "TARGET_HIMODE_MATH")
811 SI])
812
813 ;; Math-dependant single word integer modes without QImode.
814 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
815 SI (DI "TARGET_64BIT")])
816
817 ;; Double word integer modes.
818 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
819 (TI "TARGET_64BIT")])
820
821 ;; Double word integer modes as mode attribute.
822 (define_mode_attr DWI [(SI "DI") (DI "TI")])
823 (define_mode_attr dwi [(SI "di") (DI "ti")])
824
825 ;; Half mode for double word integer modes.
826 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
827 (DI "TARGET_64BIT")])
828
829 ;; Instruction suffix for integer modes.
830 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
831
832 ;; Pointer size prefix for integer modes (Intel asm dialect)
833 (define_mode_attr iptrsize [(QI "BYTE")
834 (HI "WORD")
835 (SI "DWORD")
836 (DI "QWORD")])
837
838 ;; Register class for integer modes.
839 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
840
841 ;; Immediate operand constraint for integer modes.
842 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
843
844 ;; General operand constraint for word modes.
845 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
846
847 ;; Immediate operand constraint for double integer modes.
848 (define_mode_attr di [(SI "nF") (DI "e")])
849
850 ;; Immediate operand constraint for shifts.
851 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
852
853 ;; General operand predicate for integer modes.
854 (define_mode_attr general_operand
855 [(QI "general_operand")
856 (HI "general_operand")
857 (SI "x86_64_general_operand")
858 (DI "x86_64_general_operand")
859 (TI "x86_64_general_operand")])
860
861 ;; General sign/zero extend operand predicate for integer modes.
862 (define_mode_attr general_szext_operand
863 [(QI "general_operand")
864 (HI "general_operand")
865 (SI "x86_64_szext_general_operand")
866 (DI "x86_64_szext_general_operand")])
867
868 ;; Immediate operand predicate for integer modes.
869 (define_mode_attr immediate_operand
870 [(QI "immediate_operand")
871 (HI "immediate_operand")
872 (SI "x86_64_immediate_operand")
873 (DI "x86_64_immediate_operand")])
874
875 ;; Nonmemory operand predicate for integer modes.
876 (define_mode_attr nonmemory_operand
877 [(QI "nonmemory_operand")
878 (HI "nonmemory_operand")
879 (SI "x86_64_nonmemory_operand")
880 (DI "x86_64_nonmemory_operand")])
881
882 ;; Operand predicate for shifts.
883 (define_mode_attr shift_operand
884 [(QI "nonimmediate_operand")
885 (HI "nonimmediate_operand")
886 (SI "nonimmediate_operand")
887 (DI "shiftdi_operand")
888 (TI "register_operand")])
889
890 ;; Operand predicate for shift argument.
891 (define_mode_attr shift_immediate_operand
892 [(QI "const_1_to_31_operand")
893 (HI "const_1_to_31_operand")
894 (SI "const_1_to_31_operand")
895 (DI "const_1_to_63_operand")])
896
897 ;; Input operand predicate for arithmetic left shifts.
898 (define_mode_attr ashl_input_operand
899 [(QI "nonimmediate_operand")
900 (HI "nonimmediate_operand")
901 (SI "nonimmediate_operand")
902 (DI "ashldi_input_operand")
903 (TI "reg_or_pm1_operand")])
904
905 ;; SSE and x87 SFmode and DFmode floating point modes
906 (define_mode_iterator MODEF [SF DF])
907
908 ;; All x87 floating point modes
909 (define_mode_iterator X87MODEF [SF DF XF])
910
911 ;; SSE instruction suffix for various modes
912 (define_mode_attr ssemodesuffix
913 [(SF "ss") (DF "sd")
914 (V8SF "ps") (V4DF "pd")
915 (V4SF "ps") (V2DF "pd")
916 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
917 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
918
919 ;; SSE vector suffix for floating point modes
920 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
921
922 ;; SSE vector mode corresponding to a scalar mode
923 (define_mode_attr ssevecmode
924 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
925
926 ;; Instruction suffix for REX 64bit operators.
927 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
928
929 ;; This mode iterator allows :P to be used for patterns that operate on
930 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
931 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
932
933 ;; This mode iterator allows :W to be used for patterns that operate on
934 ;; word_mode sized quantities.
935 (define_mode_iterator W
936 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
937
938 ;; This mode iterator allows :PTR to be used for patterns that operate on
939 ;; ptr_mode sized quantities.
940 (define_mode_iterator PTR
941 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
942 \f
943 ;; Scheduling descriptions
944
945 (include "pentium.md")
946 (include "ppro.md")
947 (include "k6.md")
948 (include "athlon.md")
949 (include "bdver1.md")
950 (include "geode.md")
951 (include "atom.md")
952 (include "core2.md")
953
954 \f
955 ;; Operand and operator predicates and constraints
956
957 (include "predicates.md")
958 (include "constraints.md")
959
960 \f
961 ;; Compare and branch/compare and store instructions.
962
963 (define_expand "cbranch<mode>4"
964 [(set (reg:CC FLAGS_REG)
965 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
966 (match_operand:SDWIM 2 "<general_operand>")))
967 (set (pc) (if_then_else
968 (match_operator 0 "ordered_comparison_operator"
969 [(reg:CC FLAGS_REG) (const_int 0)])
970 (label_ref (match_operand 3))
971 (pc)))]
972 ""
973 {
974 if (MEM_P (operands[1]) && MEM_P (operands[2]))
975 operands[1] = force_reg (<MODE>mode, operands[1]);
976 ix86_expand_branch (GET_CODE (operands[0]),
977 operands[1], operands[2], operands[3]);
978 DONE;
979 })
980
981 (define_expand "cstore<mode>4"
982 [(set (reg:CC FLAGS_REG)
983 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
984 (match_operand:SWIM 3 "<general_operand>")))
985 (set (match_operand:QI 0 "register_operand")
986 (match_operator 1 "ordered_comparison_operator"
987 [(reg:CC FLAGS_REG) (const_int 0)]))]
988 ""
989 {
990 if (MEM_P (operands[2]) && MEM_P (operands[3]))
991 operands[2] = force_reg (<MODE>mode, operands[2]);
992 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
993 operands[2], operands[3]);
994 DONE;
995 })
996
997 (define_expand "cmp<mode>_1"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1000 (match_operand:SWI48 1 "<general_operand>")))])
1001
1002 (define_insn "*cmp<mode>_ccno_1"
1003 [(set (reg FLAGS_REG)
1004 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1005 (match_operand:SWI 1 "const0_operand")))]
1006 "ix86_match_ccmode (insn, CCNOmode)"
1007 "@
1008 test{<imodesuffix>}\t%0, %0
1009 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1010 [(set_attr "type" "test,icmp")
1011 (set_attr "length_immediate" "0,1")
1012 (set_attr "mode" "<MODE>")])
1013
1014 (define_insn "*cmp<mode>_1"
1015 [(set (reg FLAGS_REG)
1016 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1017 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1018 "ix86_match_ccmode (insn, CCmode)"
1019 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1020 [(set_attr "type" "icmp")
1021 (set_attr "mode" "<MODE>")])
1022
1023 (define_insn "*cmp<mode>_minus_1"
1024 [(set (reg FLAGS_REG)
1025 (compare
1026 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1027 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1028 (const_int 0)))]
1029 "ix86_match_ccmode (insn, CCGOCmode)"
1030 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1031 [(set_attr "type" "icmp")
1032 (set_attr "mode" "<MODE>")])
1033
1034 (define_insn "*cmpqi_ext_1"
1035 [(set (reg FLAGS_REG)
1036 (compare
1037 (match_operand:QI 0 "general_operand" "Qm")
1038 (subreg:QI
1039 (zero_extract:SI
1040 (match_operand 1 "ext_register_operand" "Q")
1041 (const_int 8)
1042 (const_int 8)) 0)))]
1043 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1044 "cmp{b}\t{%h1, %0|%0, %h1}"
1045 [(set_attr "type" "icmp")
1046 (set_attr "mode" "QI")])
1047
1048 (define_insn "*cmpqi_ext_1_rex64"
1049 [(set (reg FLAGS_REG)
1050 (compare
1051 (match_operand:QI 0 "register_operand" "Q")
1052 (subreg:QI
1053 (zero_extract:SI
1054 (match_operand 1 "ext_register_operand" "Q")
1055 (const_int 8)
1056 (const_int 8)) 0)))]
1057 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1058 "cmp{b}\t{%h1, %0|%0, %h1}"
1059 [(set_attr "type" "icmp")
1060 (set_attr "mode" "QI")])
1061
1062 (define_insn "*cmpqi_ext_2"
1063 [(set (reg FLAGS_REG)
1064 (compare
1065 (subreg:QI
1066 (zero_extract:SI
1067 (match_operand 0 "ext_register_operand" "Q")
1068 (const_int 8)
1069 (const_int 8)) 0)
1070 (match_operand:QI 1 "const0_operand")))]
1071 "ix86_match_ccmode (insn, CCNOmode)"
1072 "test{b}\t%h0, %h0"
1073 [(set_attr "type" "test")
1074 (set_attr "length_immediate" "0")
1075 (set_attr "mode" "QI")])
1076
1077 (define_expand "cmpqi_ext_3"
1078 [(set (reg:CC FLAGS_REG)
1079 (compare:CC
1080 (subreg:QI
1081 (zero_extract:SI
1082 (match_operand 0 "ext_register_operand")
1083 (const_int 8)
1084 (const_int 8)) 0)
1085 (match_operand:QI 1 "immediate_operand")))])
1086
1087 (define_insn "*cmpqi_ext_3_insn"
1088 [(set (reg FLAGS_REG)
1089 (compare
1090 (subreg:QI
1091 (zero_extract:SI
1092 (match_operand 0 "ext_register_operand" "Q")
1093 (const_int 8)
1094 (const_int 8)) 0)
1095 (match_operand:QI 1 "general_operand" "Qmn")))]
1096 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1097 "cmp{b}\t{%1, %h0|%h0, %1}"
1098 [(set_attr "type" "icmp")
1099 (set_attr "modrm" "1")
1100 (set_attr "mode" "QI")])
1101
1102 (define_insn "*cmpqi_ext_3_insn_rex64"
1103 [(set (reg FLAGS_REG)
1104 (compare
1105 (subreg:QI
1106 (zero_extract:SI
1107 (match_operand 0 "ext_register_operand" "Q")
1108 (const_int 8)
1109 (const_int 8)) 0)
1110 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1111 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1112 "cmp{b}\t{%1, %h0|%h0, %1}"
1113 [(set_attr "type" "icmp")
1114 (set_attr "modrm" "1")
1115 (set_attr "mode" "QI")])
1116
1117 (define_insn "*cmpqi_ext_4"
1118 [(set (reg FLAGS_REG)
1119 (compare
1120 (subreg:QI
1121 (zero_extract:SI
1122 (match_operand 0 "ext_register_operand" "Q")
1123 (const_int 8)
1124 (const_int 8)) 0)
1125 (subreg:QI
1126 (zero_extract:SI
1127 (match_operand 1 "ext_register_operand" "Q")
1128 (const_int 8)
1129 (const_int 8)) 0)))]
1130 "ix86_match_ccmode (insn, CCmode)"
1131 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1132 [(set_attr "type" "icmp")
1133 (set_attr "mode" "QI")])
1134
1135 ;; These implement float point compares.
1136 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1137 ;; which would allow mix and match FP modes on the compares. Which is what
1138 ;; the old patterns did, but with many more of them.
1139
1140 (define_expand "cbranchxf4"
1141 [(set (reg:CC FLAGS_REG)
1142 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1143 (match_operand:XF 2 "nonmemory_operand")))
1144 (set (pc) (if_then_else
1145 (match_operator 0 "ix86_fp_comparison_operator"
1146 [(reg:CC FLAGS_REG)
1147 (const_int 0)])
1148 (label_ref (match_operand 3))
1149 (pc)))]
1150 "TARGET_80387"
1151 {
1152 ix86_expand_branch (GET_CODE (operands[0]),
1153 operands[1], operands[2], operands[3]);
1154 DONE;
1155 })
1156
1157 (define_expand "cstorexf4"
1158 [(set (reg:CC FLAGS_REG)
1159 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1160 (match_operand:XF 3 "nonmemory_operand")))
1161 (set (match_operand:QI 0 "register_operand")
1162 (match_operator 1 "ix86_fp_comparison_operator"
1163 [(reg:CC FLAGS_REG)
1164 (const_int 0)]))]
1165 "TARGET_80387"
1166 {
1167 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1168 operands[2], operands[3]);
1169 DONE;
1170 })
1171
1172 (define_expand "cbranch<mode>4"
1173 [(set (reg:CC FLAGS_REG)
1174 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1175 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1176 (set (pc) (if_then_else
1177 (match_operator 0 "ix86_fp_comparison_operator"
1178 [(reg:CC FLAGS_REG)
1179 (const_int 0)])
1180 (label_ref (match_operand 3))
1181 (pc)))]
1182 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1183 {
1184 ix86_expand_branch (GET_CODE (operands[0]),
1185 operands[1], operands[2], operands[3]);
1186 DONE;
1187 })
1188
1189 (define_expand "cstore<mode>4"
1190 [(set (reg:CC FLAGS_REG)
1191 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1192 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1193 (set (match_operand:QI 0 "register_operand")
1194 (match_operator 1 "ix86_fp_comparison_operator"
1195 [(reg:CC FLAGS_REG)
1196 (const_int 0)]))]
1197 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1198 {
1199 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1200 operands[2], operands[3]);
1201 DONE;
1202 })
1203
1204 (define_expand "cbranchcc4"
1205 [(set (pc) (if_then_else
1206 (match_operator 0 "comparison_operator"
1207 [(match_operand 1 "flags_reg_operand")
1208 (match_operand 2 "const0_operand")])
1209 (label_ref (match_operand 3))
1210 (pc)))]
1211 ""
1212 {
1213 ix86_expand_branch (GET_CODE (operands[0]),
1214 operands[1], operands[2], operands[3]);
1215 DONE;
1216 })
1217
1218 (define_expand "cstorecc4"
1219 [(set (match_operand:QI 0 "register_operand")
1220 (match_operator 1 "comparison_operator"
1221 [(match_operand 2 "flags_reg_operand")
1222 (match_operand 3 "const0_operand")]))]
1223 ""
1224 {
1225 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1226 operands[2], operands[3]);
1227 DONE;
1228 })
1229
1230
1231 ;; FP compares, step 1:
1232 ;; Set the FP condition codes.
1233 ;;
1234 ;; CCFPmode compare with exceptions
1235 ;; CCFPUmode compare with no exceptions
1236
1237 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1238 ;; used to manage the reg stack popping would not be preserved.
1239
1240 (define_insn "*cmpfp_0"
1241 [(set (match_operand:HI 0 "register_operand" "=a")
1242 (unspec:HI
1243 [(compare:CCFP
1244 (match_operand 1 "register_operand" "f")
1245 (match_operand 2 "const0_operand"))]
1246 UNSPEC_FNSTSW))]
1247 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1248 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1249 "* return output_fp_compare (insn, operands, false, false);"
1250 [(set_attr "type" "multi")
1251 (set_attr "unit" "i387")
1252 (set (attr "mode")
1253 (cond [(match_operand:SF 1)
1254 (const_string "SF")
1255 (match_operand:DF 1)
1256 (const_string "DF")
1257 ]
1258 (const_string "XF")))])
1259
1260 (define_insn_and_split "*cmpfp_0_cc"
1261 [(set (reg:CCFP FLAGS_REG)
1262 (compare:CCFP
1263 (match_operand 1 "register_operand" "f")
1264 (match_operand 2 "const0_operand")))
1265 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1266 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1267 && TARGET_SAHF && !TARGET_CMOVE
1268 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1269 "#"
1270 "&& reload_completed"
1271 [(set (match_dup 0)
1272 (unspec:HI
1273 [(compare:CCFP (match_dup 1)(match_dup 2))]
1274 UNSPEC_FNSTSW))
1275 (set (reg:CC FLAGS_REG)
1276 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1277 ""
1278 [(set_attr "type" "multi")
1279 (set_attr "unit" "i387")
1280 (set (attr "mode")
1281 (cond [(match_operand:SF 1)
1282 (const_string "SF")
1283 (match_operand:DF 1)
1284 (const_string "DF")
1285 ]
1286 (const_string "XF")))])
1287
1288 (define_insn "*cmpfp_xf"
1289 [(set (match_operand:HI 0 "register_operand" "=a")
1290 (unspec:HI
1291 [(compare:CCFP
1292 (match_operand:XF 1 "register_operand" "f")
1293 (match_operand:XF 2 "register_operand" "f"))]
1294 UNSPEC_FNSTSW))]
1295 "TARGET_80387"
1296 "* return output_fp_compare (insn, operands, false, false);"
1297 [(set_attr "type" "multi")
1298 (set_attr "unit" "i387")
1299 (set_attr "mode" "XF")])
1300
1301 (define_insn_and_split "*cmpfp_xf_cc"
1302 [(set (reg:CCFP FLAGS_REG)
1303 (compare:CCFP
1304 (match_operand:XF 1 "register_operand" "f")
1305 (match_operand:XF 2 "register_operand" "f")))
1306 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1307 "TARGET_80387
1308 && TARGET_SAHF && !TARGET_CMOVE"
1309 "#"
1310 "&& reload_completed"
1311 [(set (match_dup 0)
1312 (unspec:HI
1313 [(compare:CCFP (match_dup 1)(match_dup 2))]
1314 UNSPEC_FNSTSW))
1315 (set (reg:CC FLAGS_REG)
1316 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1317 ""
1318 [(set_attr "type" "multi")
1319 (set_attr "unit" "i387")
1320 (set_attr "mode" "XF")])
1321
1322 (define_insn "*cmpfp_<mode>"
1323 [(set (match_operand:HI 0 "register_operand" "=a")
1324 (unspec:HI
1325 [(compare:CCFP
1326 (match_operand:MODEF 1 "register_operand" "f")
1327 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1328 UNSPEC_FNSTSW))]
1329 "TARGET_80387"
1330 "* return output_fp_compare (insn, operands, false, false);"
1331 [(set_attr "type" "multi")
1332 (set_attr "unit" "i387")
1333 (set_attr "mode" "<MODE>")])
1334
1335 (define_insn_and_split "*cmpfp_<mode>_cc"
1336 [(set (reg:CCFP FLAGS_REG)
1337 (compare:CCFP
1338 (match_operand:MODEF 1 "register_operand" "f")
1339 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1340 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1341 "TARGET_80387
1342 && TARGET_SAHF && !TARGET_CMOVE"
1343 "#"
1344 "&& reload_completed"
1345 [(set (match_dup 0)
1346 (unspec:HI
1347 [(compare:CCFP (match_dup 1)(match_dup 2))]
1348 UNSPEC_FNSTSW))
1349 (set (reg:CC FLAGS_REG)
1350 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1351 ""
1352 [(set_attr "type" "multi")
1353 (set_attr "unit" "i387")
1354 (set_attr "mode" "<MODE>")])
1355
1356 (define_insn "*cmpfp_u"
1357 [(set (match_operand:HI 0 "register_operand" "=a")
1358 (unspec:HI
1359 [(compare:CCFPU
1360 (match_operand 1 "register_operand" "f")
1361 (match_operand 2 "register_operand" "f"))]
1362 UNSPEC_FNSTSW))]
1363 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1364 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1365 "* return output_fp_compare (insn, operands, false, true);"
1366 [(set_attr "type" "multi")
1367 (set_attr "unit" "i387")
1368 (set (attr "mode")
1369 (cond [(match_operand:SF 1)
1370 (const_string "SF")
1371 (match_operand:DF 1)
1372 (const_string "DF")
1373 ]
1374 (const_string "XF")))])
1375
1376 (define_insn_and_split "*cmpfp_u_cc"
1377 [(set (reg:CCFPU FLAGS_REG)
1378 (compare:CCFPU
1379 (match_operand 1 "register_operand" "f")
1380 (match_operand 2 "register_operand" "f")))
1381 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1382 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1383 && TARGET_SAHF && !TARGET_CMOVE
1384 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1385 "#"
1386 "&& reload_completed"
1387 [(set (match_dup 0)
1388 (unspec:HI
1389 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1390 UNSPEC_FNSTSW))
1391 (set (reg:CC FLAGS_REG)
1392 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1393 ""
1394 [(set_attr "type" "multi")
1395 (set_attr "unit" "i387")
1396 (set (attr "mode")
1397 (cond [(match_operand:SF 1)
1398 (const_string "SF")
1399 (match_operand:DF 1)
1400 (const_string "DF")
1401 ]
1402 (const_string "XF")))])
1403
1404 (define_insn "*cmpfp_<mode>"
1405 [(set (match_operand:HI 0 "register_operand" "=a")
1406 (unspec:HI
1407 [(compare:CCFP
1408 (match_operand 1 "register_operand" "f")
1409 (match_operator 3 "float_operator"
1410 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1411 UNSPEC_FNSTSW))]
1412 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1413 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1414 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1415 "* return output_fp_compare (insn, operands, false, false);"
1416 [(set_attr "type" "multi")
1417 (set_attr "unit" "i387")
1418 (set_attr "fp_int_src" "true")
1419 (set_attr "mode" "<MODE>")])
1420
1421 (define_insn_and_split "*cmpfp_<mode>_cc"
1422 [(set (reg:CCFP FLAGS_REG)
1423 (compare:CCFP
1424 (match_operand 1 "register_operand" "f")
1425 (match_operator 3 "float_operator"
1426 [(match_operand:SWI24 2 "memory_operand" "m")])))
1427 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1428 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1429 && TARGET_SAHF && !TARGET_CMOVE
1430 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1431 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1432 "#"
1433 "&& reload_completed"
1434 [(set (match_dup 0)
1435 (unspec:HI
1436 [(compare:CCFP
1437 (match_dup 1)
1438 (match_op_dup 3 [(match_dup 2)]))]
1439 UNSPEC_FNSTSW))
1440 (set (reg:CC FLAGS_REG)
1441 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1442 ""
1443 [(set_attr "type" "multi")
1444 (set_attr "unit" "i387")
1445 (set_attr "fp_int_src" "true")
1446 (set_attr "mode" "<MODE>")])
1447
1448 ;; FP compares, step 2
1449 ;; Move the fpsw to ax.
1450
1451 (define_insn "x86_fnstsw_1"
1452 [(set (match_operand:HI 0 "register_operand" "=a")
1453 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1454 "TARGET_80387"
1455 "fnstsw\t%0"
1456 [(set (attr "length")
1457 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1458 (set_attr "mode" "SI")
1459 (set_attr "unit" "i387")])
1460
1461 ;; FP compares, step 3
1462 ;; Get ax into flags, general case.
1463
1464 (define_insn "x86_sahf_1"
1465 [(set (reg:CC FLAGS_REG)
1466 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1467 UNSPEC_SAHF))]
1468 "TARGET_SAHF"
1469 {
1470 #ifndef HAVE_AS_IX86_SAHF
1471 if (TARGET_64BIT)
1472 return ASM_BYTE "0x9e";
1473 else
1474 #endif
1475 return "sahf";
1476 }
1477 [(set_attr "length" "1")
1478 (set_attr "athlon_decode" "vector")
1479 (set_attr "amdfam10_decode" "direct")
1480 (set_attr "bdver1_decode" "direct")
1481 (set_attr "mode" "SI")])
1482
1483 ;; Pentium Pro can do steps 1 through 3 in one go.
1484 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1485 ;; (these i387 instructions set flags directly)
1486 (define_insn "*cmpfp_i_mixed"
1487 [(set (reg:CCFP FLAGS_REG)
1488 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1489 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1490 "TARGET_MIX_SSE_I387
1491 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1492 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1493 "* return output_fp_compare (insn, operands, true, false);"
1494 [(set_attr "type" "fcmp,ssecomi")
1495 (set_attr "prefix" "orig,maybe_vex")
1496 (set (attr "mode")
1497 (if_then_else (match_operand:SF 1)
1498 (const_string "SF")
1499 (const_string "DF")))
1500 (set (attr "prefix_rep")
1501 (if_then_else (eq_attr "type" "ssecomi")
1502 (const_string "0")
1503 (const_string "*")))
1504 (set (attr "prefix_data16")
1505 (cond [(eq_attr "type" "fcmp")
1506 (const_string "*")
1507 (eq_attr "mode" "DF")
1508 (const_string "1")
1509 ]
1510 (const_string "0")))
1511 (set_attr "athlon_decode" "vector")
1512 (set_attr "amdfam10_decode" "direct")
1513 (set_attr "bdver1_decode" "double")])
1514
1515 (define_insn "*cmpfp_i_sse"
1516 [(set (reg:CCFP FLAGS_REG)
1517 (compare:CCFP (match_operand 0 "register_operand" "x")
1518 (match_operand 1 "nonimmediate_operand" "xm")))]
1519 "TARGET_SSE_MATH
1520 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1521 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1522 "* return output_fp_compare (insn, operands, true, false);"
1523 [(set_attr "type" "ssecomi")
1524 (set_attr "prefix" "maybe_vex")
1525 (set (attr "mode")
1526 (if_then_else (match_operand:SF 1)
1527 (const_string "SF")
1528 (const_string "DF")))
1529 (set_attr "prefix_rep" "0")
1530 (set (attr "prefix_data16")
1531 (if_then_else (eq_attr "mode" "DF")
1532 (const_string "1")
1533 (const_string "0")))
1534 (set_attr "athlon_decode" "vector")
1535 (set_attr "amdfam10_decode" "direct")
1536 (set_attr "bdver1_decode" "double")])
1537
1538 (define_insn "*cmpfp_i_i387"
1539 [(set (reg:CCFP FLAGS_REG)
1540 (compare:CCFP (match_operand 0 "register_operand" "f")
1541 (match_operand 1 "register_operand" "f")))]
1542 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1543 && TARGET_CMOVE
1544 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1545 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1546 "* return output_fp_compare (insn, operands, true, false);"
1547 [(set_attr "type" "fcmp")
1548 (set (attr "mode")
1549 (cond [(match_operand:SF 1)
1550 (const_string "SF")
1551 (match_operand:DF 1)
1552 (const_string "DF")
1553 ]
1554 (const_string "XF")))
1555 (set_attr "athlon_decode" "vector")
1556 (set_attr "amdfam10_decode" "direct")
1557 (set_attr "bdver1_decode" "double")])
1558
1559 (define_insn "*cmpfp_iu_mixed"
1560 [(set (reg:CCFPU FLAGS_REG)
1561 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1562 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1563 "TARGET_MIX_SSE_I387
1564 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1565 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1566 "* return output_fp_compare (insn, operands, true, true);"
1567 [(set_attr "type" "fcmp,ssecomi")
1568 (set_attr "prefix" "orig,maybe_vex")
1569 (set (attr "mode")
1570 (if_then_else (match_operand:SF 1)
1571 (const_string "SF")
1572 (const_string "DF")))
1573 (set (attr "prefix_rep")
1574 (if_then_else (eq_attr "type" "ssecomi")
1575 (const_string "0")
1576 (const_string "*")))
1577 (set (attr "prefix_data16")
1578 (cond [(eq_attr "type" "fcmp")
1579 (const_string "*")
1580 (eq_attr "mode" "DF")
1581 (const_string "1")
1582 ]
1583 (const_string "0")))
1584 (set_attr "athlon_decode" "vector")
1585 (set_attr "amdfam10_decode" "direct")
1586 (set_attr "bdver1_decode" "double")])
1587
1588 (define_insn "*cmpfp_iu_sse"
1589 [(set (reg:CCFPU FLAGS_REG)
1590 (compare:CCFPU (match_operand 0 "register_operand" "x")
1591 (match_operand 1 "nonimmediate_operand" "xm")))]
1592 "TARGET_SSE_MATH
1593 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1594 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1595 "* return output_fp_compare (insn, operands, true, true);"
1596 [(set_attr "type" "ssecomi")
1597 (set_attr "prefix" "maybe_vex")
1598 (set (attr "mode")
1599 (if_then_else (match_operand:SF 1)
1600 (const_string "SF")
1601 (const_string "DF")))
1602 (set_attr "prefix_rep" "0")
1603 (set (attr "prefix_data16")
1604 (if_then_else (eq_attr "mode" "DF")
1605 (const_string "1")
1606 (const_string "0")))
1607 (set_attr "athlon_decode" "vector")
1608 (set_attr "amdfam10_decode" "direct")
1609 (set_attr "bdver1_decode" "double")])
1610
1611 (define_insn "*cmpfp_iu_387"
1612 [(set (reg:CCFPU FLAGS_REG)
1613 (compare:CCFPU (match_operand 0 "register_operand" "f")
1614 (match_operand 1 "register_operand" "f")))]
1615 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1616 && TARGET_CMOVE
1617 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1618 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1619 "* return output_fp_compare (insn, operands, true, true);"
1620 [(set_attr "type" "fcmp")
1621 (set (attr "mode")
1622 (cond [(match_operand:SF 1)
1623 (const_string "SF")
1624 (match_operand:DF 1)
1625 (const_string "DF")
1626 ]
1627 (const_string "XF")))
1628 (set_attr "athlon_decode" "vector")
1629 (set_attr "amdfam10_decode" "direct")
1630 (set_attr "bdver1_decode" "direct")])
1631 \f
1632 ;; Push/pop instructions.
1633
1634 (define_insn "*push<mode>2"
1635 [(set (match_operand:DWI 0 "push_operand" "=<")
1636 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1637 ""
1638 "#"
1639 [(set_attr "type" "multi")
1640 (set_attr "mode" "<MODE>")])
1641
1642 (define_split
1643 [(set (match_operand:TI 0 "push_operand")
1644 (match_operand:TI 1 "general_operand"))]
1645 "TARGET_64BIT && reload_completed
1646 && !SSE_REG_P (operands[1])"
1647 [(const_int 0)]
1648 "ix86_split_long_move (operands); DONE;")
1649
1650 (define_insn "*pushdi2_rex64"
1651 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1652 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1653 "TARGET_64BIT"
1654 "@
1655 push{q}\t%1
1656 #"
1657 [(set_attr "type" "push,multi")
1658 (set_attr "mode" "DI")])
1659
1660 ;; Convert impossible pushes of immediate to existing instructions.
1661 ;; First try to get scratch register and go through it. In case this
1662 ;; fails, push sign extended lower part first and then overwrite
1663 ;; upper part by 32bit move.
1664 (define_peephole2
1665 [(match_scratch:DI 2 "r")
1666 (set (match_operand:DI 0 "push_operand")
1667 (match_operand:DI 1 "immediate_operand"))]
1668 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1669 && !x86_64_immediate_operand (operands[1], DImode)"
1670 [(set (match_dup 2) (match_dup 1))
1671 (set (match_dup 0) (match_dup 2))])
1672
1673 ;; We need to define this as both peepholer and splitter for case
1674 ;; peephole2 pass is not run.
1675 ;; "&& 1" is needed to keep it from matching the previous pattern.
1676 (define_peephole2
1677 [(set (match_operand:DI 0 "push_operand")
1678 (match_operand:DI 1 "immediate_operand"))]
1679 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1680 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1681 [(set (match_dup 0) (match_dup 1))
1682 (set (match_dup 2) (match_dup 3))]
1683 {
1684 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1685
1686 operands[1] = gen_lowpart (DImode, operands[2]);
1687 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1688 GEN_INT (4)));
1689 })
1690
1691 (define_split
1692 [(set (match_operand:DI 0 "push_operand")
1693 (match_operand:DI 1 "immediate_operand"))]
1694 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1695 ? epilogue_completed : reload_completed)
1696 && !symbolic_operand (operands[1], DImode)
1697 && !x86_64_immediate_operand (operands[1], DImode)"
1698 [(set (match_dup 0) (match_dup 1))
1699 (set (match_dup 2) (match_dup 3))]
1700 {
1701 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1702
1703 operands[1] = gen_lowpart (DImode, operands[2]);
1704 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1705 GEN_INT (4)));
1706 })
1707
1708 (define_split
1709 [(set (match_operand:DI 0 "push_operand")
1710 (match_operand:DI 1 "general_operand"))]
1711 "!TARGET_64BIT && reload_completed
1712 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1713 [(const_int 0)]
1714 "ix86_split_long_move (operands); DONE;")
1715
1716 (define_insn "*pushsi2"
1717 [(set (match_operand:SI 0 "push_operand" "=<")
1718 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1719 "!TARGET_64BIT"
1720 "push{l}\t%1"
1721 [(set_attr "type" "push")
1722 (set_attr "mode" "SI")])
1723
1724 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1725 ;; "push a byte/word". But actually we use pushl, which has the effect
1726 ;; of rounding the amount pushed up to a word.
1727
1728 ;; For TARGET_64BIT we always round up to 8 bytes.
1729 (define_insn "*push<mode>2_rex64"
1730 [(set (match_operand:SWI124 0 "push_operand" "=X")
1731 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1732 "TARGET_64BIT"
1733 "push{q}\t%q1"
1734 [(set_attr "type" "push")
1735 (set_attr "mode" "DI")])
1736
1737 (define_insn "*push<mode>2"
1738 [(set (match_operand:SWI12 0 "push_operand" "=X")
1739 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1740 "!TARGET_64BIT"
1741 "push{l}\t%k1"
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "SI")])
1744
1745 (define_insn "*push<mode>2_prologue"
1746 [(set (match_operand:W 0 "push_operand" "=<")
1747 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1748 (clobber (mem:BLK (scratch)))]
1749 ""
1750 "push{<imodesuffix>}\t%1"
1751 [(set_attr "type" "push")
1752 (set_attr "mode" "<MODE>")])
1753
1754 (define_insn "*pop<mode>1"
1755 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1756 (match_operand:W 1 "pop_operand" ">"))]
1757 ""
1758 "pop{<imodesuffix>}\t%0"
1759 [(set_attr "type" "pop")
1760 (set_attr "mode" "<MODE>")])
1761
1762 (define_insn "*pop<mode>1_epilogue"
1763 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1764 (match_operand:W 1 "pop_operand" ">"))
1765 (clobber (mem:BLK (scratch)))]
1766 ""
1767 "pop{<imodesuffix>}\t%0"
1768 [(set_attr "type" "pop")
1769 (set_attr "mode" "<MODE>")])
1770 \f
1771 ;; Move instructions.
1772
1773 (define_expand "movoi"
1774 [(set (match_operand:OI 0 "nonimmediate_operand")
1775 (match_operand:OI 1 "general_operand"))]
1776 "TARGET_AVX"
1777 "ix86_expand_move (OImode, operands); DONE;")
1778
1779 (define_expand "movti"
1780 [(set (match_operand:TI 0 "nonimmediate_operand")
1781 (match_operand:TI 1 "nonimmediate_operand"))]
1782 "TARGET_64BIT || TARGET_SSE"
1783 {
1784 if (TARGET_64BIT)
1785 ix86_expand_move (TImode, operands);
1786 else if (push_operand (operands[0], TImode))
1787 ix86_expand_push (TImode, operands[1]);
1788 else
1789 ix86_expand_vector_move (TImode, operands);
1790 DONE;
1791 })
1792
1793 ;; This expands to what emit_move_complex would generate if we didn't
1794 ;; have a movti pattern. Having this avoids problems with reload on
1795 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1796 ;; to have around all the time.
1797 (define_expand "movcdi"
1798 [(set (match_operand:CDI 0 "nonimmediate_operand")
1799 (match_operand:CDI 1 "general_operand"))]
1800 ""
1801 {
1802 if (push_operand (operands[0], CDImode))
1803 emit_move_complex_push (CDImode, operands[0], operands[1]);
1804 else
1805 emit_move_complex_parts (operands[0], operands[1]);
1806 DONE;
1807 })
1808
1809 (define_expand "mov<mode>"
1810 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1811 (match_operand:SWI1248x 1 "general_operand"))]
1812 ""
1813 "ix86_expand_move (<MODE>mode, operands); DONE;")
1814
1815 (define_insn "*mov<mode>_xor"
1816 [(set (match_operand:SWI48 0 "register_operand" "=r")
1817 (match_operand:SWI48 1 "const0_operand"))
1818 (clobber (reg:CC FLAGS_REG))]
1819 "reload_completed"
1820 "xor{l}\t%k0, %k0"
1821 [(set_attr "type" "alu1")
1822 (set_attr "mode" "SI")
1823 (set_attr "length_immediate" "0")])
1824
1825 (define_insn "*mov<mode>_or"
1826 [(set (match_operand:SWI48 0 "register_operand" "=r")
1827 (match_operand:SWI48 1 "const_int_operand"))
1828 (clobber (reg:CC FLAGS_REG))]
1829 "reload_completed
1830 && operands[1] == constm1_rtx"
1831 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1832 [(set_attr "type" "alu1")
1833 (set_attr "mode" "<MODE>")
1834 (set_attr "length_immediate" "1")])
1835
1836 (define_insn "*movoi_internal_avx"
1837 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1838 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1839 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1840 {
1841 switch (which_alternative)
1842 {
1843 case 0:
1844 return standard_sse_constant_opcode (insn, operands[1]);
1845 case 1:
1846 case 2:
1847 if (misaligned_operand (operands[0], OImode)
1848 || misaligned_operand (operands[1], OImode))
1849 {
1850 if (get_attr_mode (insn) == MODE_V8SF)
1851 return "vmovups\t{%1, %0|%0, %1}";
1852 else
1853 return "vmovdqu\t{%1, %0|%0, %1}";
1854 }
1855 else
1856 {
1857 if (get_attr_mode (insn) == MODE_V8SF)
1858 return "vmovaps\t{%1, %0|%0, %1}";
1859 else
1860 return "vmovdqa\t{%1, %0|%0, %1}";
1861 }
1862 default:
1863 gcc_unreachable ();
1864 }
1865 }
1866 [(set_attr "type" "sselog1,ssemov,ssemov")
1867 (set_attr "prefix" "vex")
1868 (set (attr "mode")
1869 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1870 (const_string "V8SF")
1871 (and (eq_attr "alternative" "2")
1872 (match_test "TARGET_SSE_TYPELESS_STORES"))
1873 (const_string "V8SF")
1874 ]
1875 (const_string "OI")))])
1876
1877 (define_insn "*movti_internal_rex64"
1878 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1879 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1880 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1881 {
1882 switch (which_alternative)
1883 {
1884 case 0:
1885 case 1:
1886 return "#";
1887 case 2:
1888 return standard_sse_constant_opcode (insn, operands[1]);
1889 case 3:
1890 case 4:
1891 /* TDmode values are passed as TImode on the stack. Moving them
1892 to stack may result in unaligned memory access. */
1893 if (misaligned_operand (operands[0], TImode)
1894 || misaligned_operand (operands[1], TImode))
1895 {
1896 if (get_attr_mode (insn) == MODE_V4SF)
1897 return "%vmovups\t{%1, %0|%0, %1}";
1898 else
1899 return "%vmovdqu\t{%1, %0|%0, %1}";
1900 }
1901 else
1902 {
1903 if (get_attr_mode (insn) == MODE_V4SF)
1904 return "%vmovaps\t{%1, %0|%0, %1}";
1905 else
1906 return "%vmovdqa\t{%1, %0|%0, %1}";
1907 }
1908 default:
1909 gcc_unreachable ();
1910 }
1911 }
1912 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1913 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1914 (set (attr "mode")
1915 (cond [(eq_attr "alternative" "0,1")
1916 (const_string "DI")
1917 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1918 (const_string "V4SF")
1919 (and (eq_attr "alternative" "4")
1920 (match_test "TARGET_SSE_TYPELESS_STORES"))
1921 (const_string "V4SF")
1922 (match_test "TARGET_AVX")
1923 (const_string "TI")
1924 (match_test "optimize_function_for_size_p (cfun)")
1925 (const_string "V4SF")
1926 ]
1927 (const_string "TI")))])
1928
1929 (define_split
1930 [(set (match_operand:TI 0 "nonimmediate_operand")
1931 (match_operand:TI 1 "general_operand"))]
1932 "reload_completed
1933 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1934 [(const_int 0)]
1935 "ix86_split_long_move (operands); DONE;")
1936
1937 (define_insn "*movti_internal_sse"
1938 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1939 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1940 "TARGET_SSE && !TARGET_64BIT
1941 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942 {
1943 switch (which_alternative)
1944 {
1945 case 0:
1946 return standard_sse_constant_opcode (insn, operands[1]);
1947 case 1:
1948 case 2:
1949 /* TDmode values are passed as TImode on the stack. Moving them
1950 to stack may result in unaligned memory access. */
1951 if (misaligned_operand (operands[0], TImode)
1952 || misaligned_operand (operands[1], TImode))
1953 {
1954 if (get_attr_mode (insn) == MODE_V4SF)
1955 return "%vmovups\t{%1, %0|%0, %1}";
1956 else
1957 return "%vmovdqu\t{%1, %0|%0, %1}";
1958 }
1959 else
1960 {
1961 if (get_attr_mode (insn) == MODE_V4SF)
1962 return "%vmovaps\t{%1, %0|%0, %1}";
1963 else
1964 return "%vmovdqa\t{%1, %0|%0, %1}";
1965 }
1966 default:
1967 gcc_unreachable ();
1968 }
1969 }
1970 [(set_attr "type" "sselog1,ssemov,ssemov")
1971 (set_attr "prefix" "maybe_vex")
1972 (set (attr "mode")
1973 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1974 (const_string "V4SF")
1975 (and (eq_attr "alternative" "2")
1976 (match_test "TARGET_SSE_TYPELESS_STORES"))
1977 (const_string "V4SF")
1978 (match_test "TARGET_AVX")
1979 (const_string "TI")
1980 (ior (not (match_test "TARGET_SSE2"))
1981 (match_test "optimize_function_for_size_p (cfun)"))
1982 (const_string "V4SF")
1983 ]
1984 (const_string "TI")))])
1985
1986 (define_insn "*movdi_internal_rex64"
1987 [(set (match_operand:DI 0 "nonimmediate_operand"
1988 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1989 (match_operand:DI 1 "general_operand"
1990 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1991 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1992 {
1993 switch (get_attr_type (insn))
1994 {
1995 case TYPE_SSECVT:
1996 if (SSE_REG_P (operands[0]))
1997 return "movq2dq\t{%1, %0|%0, %1}";
1998 else
1999 return "movdq2q\t{%1, %0|%0, %1}";
2000
2001 case TYPE_SSEMOV:
2002 if (get_attr_mode (insn) == MODE_V4SF)
2003 return "%vmovaps\t{%1, %0|%0, %1}";
2004 else if (get_attr_mode (insn) == MODE_TI)
2005 return "%vmovdqa\t{%1, %0|%0, %1}";
2006
2007 /* Handle broken assemblers that require movd instead of movq. */
2008 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2009 return "%vmovd\t{%1, %0|%0, %1}";
2010 else
2011 return "%vmovq\t{%1, %0|%0, %1}";
2012
2013 case TYPE_MMXMOV:
2014 /* Handle broken assemblers that require movd instead of movq. */
2015 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2016 return "movd\t{%1, %0|%0, %1}";
2017 else
2018 return "movq\t{%1, %0|%0, %1}";
2019
2020 case TYPE_SSELOG1:
2021 return standard_sse_constant_opcode (insn, operands[1]);
2022
2023 case TYPE_MMX:
2024 return "pxor\t%0, %0";
2025
2026 case TYPE_MULTI:
2027 return "#";
2028
2029 case TYPE_LEA:
2030 return "lea{q}\t{%E1, %0|%0, %E1}";
2031
2032 default:
2033 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2034 if (get_attr_mode (insn) == MODE_SI)
2035 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2036 else if (which_alternative == 2)
2037 return "movabs{q}\t{%1, %0|%0, %1}";
2038 else if (ix86_use_lea_for_mov (insn, operands))
2039 return "lea{q}\t{%E1, %0|%0, %E1}";
2040 else
2041 return "mov{q}\t{%1, %0|%0, %1}";
2042 }
2043 }
2044 [(set (attr "type")
2045 (cond [(eq_attr "alternative" "4")
2046 (const_string "multi")
2047 (eq_attr "alternative" "5")
2048 (const_string "mmx")
2049 (eq_attr "alternative" "6,7,8,9")
2050 (const_string "mmxmov")
2051 (eq_attr "alternative" "10")
2052 (const_string "sselog1")
2053 (eq_attr "alternative" "11,12,13,14,15")
2054 (const_string "ssemov")
2055 (eq_attr "alternative" "16,17")
2056 (const_string "ssecvt")
2057 (match_operand 1 "pic_32bit_operand")
2058 (const_string "lea")
2059 ]
2060 (const_string "imov")))
2061 (set (attr "modrm")
2062 (if_then_else
2063 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2064 (const_string "0")
2065 (const_string "*")))
2066 (set (attr "length_immediate")
2067 (if_then_else
2068 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2069 (const_string "8")
2070 (const_string "*")))
2071 (set (attr "prefix_rex")
2072 (if_then_else (eq_attr "alternative" "8,9")
2073 (const_string "1")
2074 (const_string "*")))
2075 (set (attr "prefix_data16")
2076 (if_then_else (eq_attr "alternative" "11")
2077 (const_string "1")
2078 (const_string "*")))
2079 (set (attr "prefix")
2080 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2081 (const_string "maybe_vex")
2082 (const_string "orig")))
2083 (set (attr "mode")
2084 (cond [(eq_attr "alternative" "0,4")
2085 (const_string "SI")
2086 (eq_attr "alternative" "10,12")
2087 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2088 (const_string "V4SF")
2089 (match_test "TARGET_AVX")
2090 (const_string "TI")
2091 (match_test "optimize_function_for_size_p (cfun)")
2092 (const_string "V4SF")
2093 ]
2094 (const_string "TI"))
2095 ]
2096 (const_string "DI")))])
2097
2098 ;; Reload patterns to support multi-word load/store
2099 ;; with non-offsetable address.
2100 (define_expand "reload_noff_store"
2101 [(parallel [(match_operand 0 "memory_operand" "=m")
2102 (match_operand 1 "register_operand" "r")
2103 (match_operand:DI 2 "register_operand" "=&r")])]
2104 "TARGET_64BIT"
2105 {
2106 rtx mem = operands[0];
2107 rtx addr = XEXP (mem, 0);
2108
2109 emit_move_insn (operands[2], addr);
2110 mem = replace_equiv_address_nv (mem, operands[2]);
2111
2112 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2113 DONE;
2114 })
2115
2116 (define_expand "reload_noff_load"
2117 [(parallel [(match_operand 0 "register_operand" "=r")
2118 (match_operand 1 "memory_operand" "m")
2119 (match_operand:DI 2 "register_operand" "=r")])]
2120 "TARGET_64BIT"
2121 {
2122 rtx mem = operands[1];
2123 rtx addr = XEXP (mem, 0);
2124
2125 emit_move_insn (operands[2], addr);
2126 mem = replace_equiv_address_nv (mem, operands[2]);
2127
2128 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2129 DONE;
2130 })
2131
2132 ;; Convert impossible stores of immediate to existing instructions.
2133 ;; First try to get scratch register and go through it. In case this
2134 ;; fails, move by 32bit parts.
2135 (define_peephole2
2136 [(match_scratch:DI 2 "r")
2137 (set (match_operand:DI 0 "memory_operand")
2138 (match_operand:DI 1 "immediate_operand"))]
2139 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2140 && !x86_64_immediate_operand (operands[1], DImode)"
2141 [(set (match_dup 2) (match_dup 1))
2142 (set (match_dup 0) (match_dup 2))])
2143
2144 ;; We need to define this as both peepholer and splitter for case
2145 ;; peephole2 pass is not run.
2146 ;; "&& 1" is needed to keep it from matching the previous pattern.
2147 (define_peephole2
2148 [(set (match_operand:DI 0 "memory_operand")
2149 (match_operand:DI 1 "immediate_operand"))]
2150 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2151 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2152 [(set (match_dup 2) (match_dup 3))
2153 (set (match_dup 4) (match_dup 5))]
2154 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2155
2156 (define_split
2157 [(set (match_operand:DI 0 "memory_operand")
2158 (match_operand:DI 1 "immediate_operand"))]
2159 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2160 ? epilogue_completed : reload_completed)
2161 && !symbolic_operand (operands[1], DImode)
2162 && !x86_64_immediate_operand (operands[1], DImode)"
2163 [(set (match_dup 2) (match_dup 3))
2164 (set (match_dup 4) (match_dup 5))]
2165 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2166
2167 (define_insn "*movdi_internal"
2168 [(set (match_operand:DI 0 "nonimmediate_operand"
2169 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2170 (match_operand:DI 1 "general_operand"
2171 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2172 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2173 {
2174 switch (get_attr_type (insn))
2175 {
2176 case TYPE_SSECVT:
2177 if (SSE_REG_P (operands[0]))
2178 return "movq2dq\t{%1, %0|%0, %1}";
2179 else
2180 return "movdq2q\t{%1, %0|%0, %1}";
2181
2182 case TYPE_SSEMOV:
2183 switch (get_attr_mode (insn))
2184 {
2185 case MODE_TI:
2186 return "%vmovdqa\t{%1, %0|%0, %1}";
2187 case MODE_DI:
2188 return "%vmovq\t{%1, %0|%0, %1}";
2189 case MODE_V4SF:
2190 return "%vmovaps\t{%1, %0|%0, %1}";
2191 case MODE_V2SF:
2192 return "movlps\t{%1, %0|%0, %1}";
2193 default:
2194 gcc_unreachable ();
2195 }
2196
2197 case TYPE_MMXMOV:
2198 return "movq\t{%1, %0|%0, %1}";
2199
2200 case TYPE_SSELOG1:
2201 return standard_sse_constant_opcode (insn, operands[1]);
2202
2203 case TYPE_MMX:
2204 return "pxor\t%0, %0";
2205
2206 case TYPE_MULTI:
2207 return "#";
2208
2209 default:
2210 gcc_unreachable ();
2211 }
2212 }
2213 [(set (attr "isa")
2214 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2215 (const_string "sse2")
2216 (eq_attr "alternative" "9,10,11,12")
2217 (const_string "noavx")
2218 ]
2219 (const_string "*")))
2220 (set (attr "type")
2221 (cond [(eq_attr "alternative" "0,1")
2222 (const_string "multi")
2223 (eq_attr "alternative" "2")
2224 (const_string "mmx")
2225 (eq_attr "alternative" "3,4")
2226 (const_string "mmxmov")
2227 (eq_attr "alternative" "5,9")
2228 (const_string "sselog1")
2229 (eq_attr "alternative" "13,14")
2230 (const_string "ssecvt")
2231 ]
2232 (const_string "ssemov")))
2233 (set (attr "prefix")
2234 (if_then_else (eq_attr "alternative" "5,6,7,8")
2235 (const_string "maybe_vex")
2236 (const_string "orig")))
2237 (set (attr "mode")
2238 (cond [(eq_attr "alternative" "9,11")
2239 (const_string "V4SF")
2240 (eq_attr "alternative" "10,12")
2241 (const_string "V2SF")
2242 (eq_attr "alternative" "5,7")
2243 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2244 (const_string "V4SF")
2245 (match_test "TARGET_AVX")
2246 (const_string "TI")
2247 (match_test "optimize_function_for_size_p (cfun)")
2248 (const_string "V4SF")
2249 ]
2250 (const_string "TI"))
2251 ]
2252 (const_string "DI")))])
2253
2254 (define_split
2255 [(set (match_operand:DI 0 "nonimmediate_operand")
2256 (match_operand:DI 1 "general_operand"))]
2257 "!TARGET_64BIT && reload_completed
2258 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2259 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2260 [(const_int 0)]
2261 "ix86_split_long_move (operands); DONE;")
2262
2263 (define_insn "*movsi_internal"
2264 [(set (match_operand:SI 0 "nonimmediate_operand"
2265 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2266 (match_operand:SI 1 "general_operand"
2267 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2268 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2269 {
2270 switch (get_attr_type (insn))
2271 {
2272 case TYPE_SSELOG1:
2273 return standard_sse_constant_opcode (insn, operands[1]);
2274
2275 case TYPE_SSEMOV:
2276 switch (get_attr_mode (insn))
2277 {
2278 case MODE_TI:
2279 return "%vmovdqa\t{%1, %0|%0, %1}";
2280 case MODE_V4SF:
2281 return "%vmovaps\t{%1, %0|%0, %1}";
2282 case MODE_SI:
2283 return "%vmovd\t{%1, %0|%0, %1}";
2284 case MODE_SF:
2285 return "%vmovss\t{%1, %0|%0, %1}";
2286 default:
2287 gcc_unreachable ();
2288 }
2289
2290 case TYPE_MMX:
2291 return "pxor\t%0, %0";
2292
2293 case TYPE_MMXMOV:
2294 if (get_attr_mode (insn) == MODE_DI)
2295 return "movq\t{%1, %0|%0, %1}";
2296 return "movd\t{%1, %0|%0, %1}";
2297
2298 case TYPE_LEA:
2299 return "lea{l}\t{%E1, %0|%0, %E1}";
2300
2301 default:
2302 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2303 if (ix86_use_lea_for_mov (insn, operands))
2304 return "lea{l}\t{%E1, %0|%0, %E1}";
2305 else
2306 return "mov{l}\t{%1, %0|%0, %1}";
2307 }
2308 }
2309 [(set (attr "type")
2310 (cond [(eq_attr "alternative" "2")
2311 (const_string "mmx")
2312 (eq_attr "alternative" "3,4,5")
2313 (const_string "mmxmov")
2314 (eq_attr "alternative" "6")
2315 (const_string "sselog1")
2316 (eq_attr "alternative" "7,8,9,10,11")
2317 (const_string "ssemov")
2318 (match_operand 1 "pic_32bit_operand")
2319 (const_string "lea")
2320 ]
2321 (const_string "imov")))
2322 (set (attr "prefix")
2323 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2324 (const_string "orig")
2325 (const_string "maybe_vex")))
2326 (set (attr "prefix_data16")
2327 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2328 (const_string "1")
2329 (const_string "*")))
2330 (set (attr "mode")
2331 (cond [(eq_attr "alternative" "2,3")
2332 (const_string "DI")
2333 (eq_attr "alternative" "6,7")
2334 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2335 (const_string "V4SF")
2336 (match_test "TARGET_AVX")
2337 (const_string "TI")
2338 (ior (not (match_test "TARGET_SSE2"))
2339 (match_test "optimize_function_for_size_p (cfun)"))
2340 (const_string "V4SF")
2341 ]
2342 (const_string "TI"))
2343 (and (eq_attr "alternative" "8,9,10,11")
2344 (not (match_test "TARGET_SSE2")))
2345 (const_string "SF")
2346 ]
2347 (const_string "SI")))])
2348
2349 (define_insn "*movhi_internal"
2350 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2351 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2352 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2353 {
2354 switch (get_attr_type (insn))
2355 {
2356 case TYPE_IMOVX:
2357 /* movzwl is faster than movw on p2 due to partial word stalls,
2358 though not as fast as an aligned movl. */
2359 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2360 default:
2361 if (get_attr_mode (insn) == MODE_SI)
2362 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2363 else
2364 return "mov{w}\t{%1, %0|%0, %1}";
2365 }
2366 }
2367 [(set (attr "type")
2368 (cond [(match_test "optimize_function_for_size_p (cfun)")
2369 (const_string "imov")
2370 (and (eq_attr "alternative" "0")
2371 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2372 (not (match_test "TARGET_HIMODE_MATH"))))
2373 (const_string "imov")
2374 (and (eq_attr "alternative" "1,2")
2375 (match_operand:HI 1 "aligned_operand"))
2376 (const_string "imov")
2377 (and (match_test "TARGET_MOVX")
2378 (eq_attr "alternative" "0,2"))
2379 (const_string "imovx")
2380 ]
2381 (const_string "imov")))
2382 (set (attr "mode")
2383 (cond [(eq_attr "type" "imovx")
2384 (const_string "SI")
2385 (and (eq_attr "alternative" "1,2")
2386 (match_operand:HI 1 "aligned_operand"))
2387 (const_string "SI")
2388 (and (eq_attr "alternative" "0")
2389 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2390 (not (match_test "TARGET_HIMODE_MATH"))))
2391 (const_string "SI")
2392 ]
2393 (const_string "HI")))])
2394
2395 ;; Situation is quite tricky about when to choose full sized (SImode) move
2396 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2397 ;; partial register dependency machines (such as AMD Athlon), where QImode
2398 ;; moves issue extra dependency and for partial register stalls machines
2399 ;; that don't use QImode patterns (and QImode move cause stall on the next
2400 ;; instruction).
2401 ;;
2402 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2403 ;; register stall machines with, where we use QImode instructions, since
2404 ;; partial register stall can be caused there. Then we use movzx.
2405 (define_insn "*movqi_internal"
2406 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2407 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2408 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2409 {
2410 switch (get_attr_type (insn))
2411 {
2412 case TYPE_IMOVX:
2413 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2414 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2415 default:
2416 if (get_attr_mode (insn) == MODE_SI)
2417 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2418 else
2419 return "mov{b}\t{%1, %0|%0, %1}";
2420 }
2421 }
2422 [(set (attr "type")
2423 (cond [(and (eq_attr "alternative" "5")
2424 (not (match_operand:QI 1 "aligned_operand")))
2425 (const_string "imovx")
2426 (match_test "optimize_function_for_size_p (cfun)")
2427 (const_string "imov")
2428 (and (eq_attr "alternative" "3")
2429 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2430 (not (match_test "TARGET_QIMODE_MATH"))))
2431 (const_string "imov")
2432 (eq_attr "alternative" "3,5")
2433 (const_string "imovx")
2434 (and (match_test "TARGET_MOVX")
2435 (eq_attr "alternative" "2"))
2436 (const_string "imovx")
2437 ]
2438 (const_string "imov")))
2439 (set (attr "mode")
2440 (cond [(eq_attr "alternative" "3,4,5")
2441 (const_string "SI")
2442 (eq_attr "alternative" "6")
2443 (const_string "QI")
2444 (eq_attr "type" "imovx")
2445 (const_string "SI")
2446 (and (eq_attr "type" "imov")
2447 (and (eq_attr "alternative" "0,1")
2448 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2449 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2450 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2451 (const_string "SI")
2452 ;; Avoid partial register stalls when not using QImode arithmetic
2453 (and (eq_attr "type" "imov")
2454 (and (eq_attr "alternative" "0,1")
2455 (and (match_test "TARGET_PARTIAL_REG_STALL")
2456 (not (match_test "TARGET_QIMODE_MATH")))))
2457 (const_string "SI")
2458 ]
2459 (const_string "QI")))])
2460
2461 ;; Stores and loads of ax to arbitrary constant address.
2462 ;; We fake an second form of instruction to force reload to load address
2463 ;; into register when rax is not available
2464 (define_insn "*movabs<mode>_1"
2465 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2466 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2467 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2468 "@
2469 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2470 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2471 [(set_attr "type" "imov")
2472 (set_attr "modrm" "0,*")
2473 (set_attr "length_address" "8,0")
2474 (set_attr "length_immediate" "0,*")
2475 (set_attr "memory" "store")
2476 (set_attr "mode" "<MODE>")])
2477
2478 (define_insn "*movabs<mode>_2"
2479 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2480 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2481 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2482 "@
2483 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2484 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2485 [(set_attr "type" "imov")
2486 (set_attr "modrm" "0,*")
2487 (set_attr "length_address" "8,0")
2488 (set_attr "length_immediate" "0")
2489 (set_attr "memory" "load")
2490 (set_attr "mode" "<MODE>")])
2491
2492 (define_insn "swap<mode>"
2493 [(set (match_operand:SWI48 0 "register_operand" "+r")
2494 (match_operand:SWI48 1 "register_operand" "+r"))
2495 (set (match_dup 1)
2496 (match_dup 0))]
2497 ""
2498 "xchg{<imodesuffix>}\t%1, %0"
2499 [(set_attr "type" "imov")
2500 (set_attr "mode" "<MODE>")
2501 (set_attr "pent_pair" "np")
2502 (set_attr "athlon_decode" "vector")
2503 (set_attr "amdfam10_decode" "double")
2504 (set_attr "bdver1_decode" "double")])
2505
2506 (define_insn "*swap<mode>_1"
2507 [(set (match_operand:SWI12 0 "register_operand" "+r")
2508 (match_operand:SWI12 1 "register_operand" "+r"))
2509 (set (match_dup 1)
2510 (match_dup 0))]
2511 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2512 "xchg{l}\t%k1, %k0"
2513 [(set_attr "type" "imov")
2514 (set_attr "mode" "SI")
2515 (set_attr "pent_pair" "np")
2516 (set_attr "athlon_decode" "vector")
2517 (set_attr "amdfam10_decode" "double")
2518 (set_attr "bdver1_decode" "double")])
2519
2520 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2521 ;; is disabled for AMDFAM10
2522 (define_insn "*swap<mode>_2"
2523 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2524 (match_operand:SWI12 1 "register_operand" "+<r>"))
2525 (set (match_dup 1)
2526 (match_dup 0))]
2527 "TARGET_PARTIAL_REG_STALL"
2528 "xchg{<imodesuffix>}\t%1, %0"
2529 [(set_attr "type" "imov")
2530 (set_attr "mode" "<MODE>")
2531 (set_attr "pent_pair" "np")
2532 (set_attr "athlon_decode" "vector")])
2533
2534 (define_expand "movstrict<mode>"
2535 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2536 (match_operand:SWI12 1 "general_operand"))]
2537 ""
2538 {
2539 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2540 FAIL;
2541 if (GET_CODE (operands[0]) == SUBREG
2542 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2543 FAIL;
2544 /* Don't generate memory->memory moves, go through a register */
2545 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2546 operands[1] = force_reg (<MODE>mode, operands[1]);
2547 })
2548
2549 (define_insn "*movstrict<mode>_1"
2550 [(set (strict_low_part
2551 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2552 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2553 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2554 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2555 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2556 [(set_attr "type" "imov")
2557 (set_attr "mode" "<MODE>")])
2558
2559 (define_insn "*movstrict<mode>_xor"
2560 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2561 (match_operand:SWI12 1 "const0_operand"))
2562 (clobber (reg:CC FLAGS_REG))]
2563 "reload_completed"
2564 "xor{<imodesuffix>}\t%0, %0"
2565 [(set_attr "type" "alu1")
2566 (set_attr "mode" "<MODE>")
2567 (set_attr "length_immediate" "0")])
2568
2569 (define_insn "*mov<mode>_extv_1"
2570 [(set (match_operand:SWI24 0 "register_operand" "=R")
2571 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2572 (const_int 8)
2573 (const_int 8)))]
2574 ""
2575 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2576 [(set_attr "type" "imovx")
2577 (set_attr "mode" "SI")])
2578
2579 (define_insn "*movqi_extv_1_rex64"
2580 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2581 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2582 (const_int 8)
2583 (const_int 8)))]
2584 "TARGET_64BIT"
2585 {
2586 switch (get_attr_type (insn))
2587 {
2588 case TYPE_IMOVX:
2589 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2590 default:
2591 return "mov{b}\t{%h1, %0|%0, %h1}";
2592 }
2593 }
2594 [(set (attr "type")
2595 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2596 (match_test "TARGET_MOVX"))
2597 (const_string "imovx")
2598 (const_string "imov")))
2599 (set (attr "mode")
2600 (if_then_else (eq_attr "type" "imovx")
2601 (const_string "SI")
2602 (const_string "QI")))])
2603
2604 (define_insn "*movqi_extv_1"
2605 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2606 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2607 (const_int 8)
2608 (const_int 8)))]
2609 "!TARGET_64BIT"
2610 {
2611 switch (get_attr_type (insn))
2612 {
2613 case TYPE_IMOVX:
2614 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2615 default:
2616 return "mov{b}\t{%h1, %0|%0, %h1}";
2617 }
2618 }
2619 [(set (attr "type")
2620 (if_then_else (and (match_operand:QI 0 "register_operand")
2621 (ior (not (match_operand:QI 0 "QIreg_operand"))
2622 (match_test "TARGET_MOVX")))
2623 (const_string "imovx")
2624 (const_string "imov")))
2625 (set (attr "mode")
2626 (if_then_else (eq_attr "type" "imovx")
2627 (const_string "SI")
2628 (const_string "QI")))])
2629
2630 (define_insn "*mov<mode>_extzv_1"
2631 [(set (match_operand:SWI48 0 "register_operand" "=R")
2632 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2633 (const_int 8)
2634 (const_int 8)))]
2635 ""
2636 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2637 [(set_attr "type" "imovx")
2638 (set_attr "mode" "SI")])
2639
2640 (define_insn "*movqi_extzv_2_rex64"
2641 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2642 (subreg:QI
2643 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2644 (const_int 8)
2645 (const_int 8)) 0))]
2646 "TARGET_64BIT"
2647 {
2648 switch (get_attr_type (insn))
2649 {
2650 case TYPE_IMOVX:
2651 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2652 default:
2653 return "mov{b}\t{%h1, %0|%0, %h1}";
2654 }
2655 }
2656 [(set (attr "type")
2657 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2658 (match_test "TARGET_MOVX"))
2659 (const_string "imovx")
2660 (const_string "imov")))
2661 (set (attr "mode")
2662 (if_then_else (eq_attr "type" "imovx")
2663 (const_string "SI")
2664 (const_string "QI")))])
2665
2666 (define_insn "*movqi_extzv_2"
2667 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2668 (subreg:QI
2669 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2670 (const_int 8)
2671 (const_int 8)) 0))]
2672 "!TARGET_64BIT"
2673 {
2674 switch (get_attr_type (insn))
2675 {
2676 case TYPE_IMOVX:
2677 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2678 default:
2679 return "mov{b}\t{%h1, %0|%0, %h1}";
2680 }
2681 }
2682 [(set (attr "type")
2683 (if_then_else (and (match_operand:QI 0 "register_operand")
2684 (ior (not (match_operand:QI 0 "QIreg_operand"))
2685 (match_test "TARGET_MOVX")))
2686 (const_string "imovx")
2687 (const_string "imov")))
2688 (set (attr "mode")
2689 (if_then_else (eq_attr "type" "imovx")
2690 (const_string "SI")
2691 (const_string "QI")))])
2692
2693 (define_expand "mov<mode>_insv_1"
2694 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2695 (const_int 8)
2696 (const_int 8))
2697 (match_operand:SWI48 1 "nonmemory_operand"))])
2698
2699 (define_insn "*mov<mode>_insv_1_rex64"
2700 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2701 (const_int 8)
2702 (const_int 8))
2703 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2704 "TARGET_64BIT"
2705 {
2706 if (CONST_INT_P (operands[1]))
2707 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2708 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2709 }
2710 [(set_attr "type" "imov")
2711 (set_attr "mode" "QI")])
2712
2713 (define_insn "*movsi_insv_1"
2714 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2715 (const_int 8)
2716 (const_int 8))
2717 (match_operand:SI 1 "general_operand" "Qmn"))]
2718 "!TARGET_64BIT"
2719 {
2720 if (CONST_INT_P (operands[1]))
2721 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2722 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2723 }
2724 [(set_attr "type" "imov")
2725 (set_attr "mode" "QI")])
2726
2727 (define_insn "*movqi_insv_2"
2728 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2729 (const_int 8)
2730 (const_int 8))
2731 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2732 (const_int 8)))]
2733 ""
2734 "mov{b}\t{%h1, %h0|%h0, %h1}"
2735 [(set_attr "type" "imov")
2736 (set_attr "mode" "QI")])
2737 \f
2738 ;; Floating point push instructions.
2739
2740 (define_insn "*pushtf"
2741 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2742 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2743 "TARGET_SSE"
2744 {
2745 /* This insn should be already split before reg-stack. */
2746 gcc_unreachable ();
2747 }
2748 [(set_attr "type" "multi")
2749 (set_attr "unit" "sse,*,*")
2750 (set_attr "mode" "TF,SI,SI")])
2751
2752 ;; %%% Kill this when call knows how to work this out.
2753 (define_split
2754 [(set (match_operand:TF 0 "push_operand")
2755 (match_operand:TF 1 "sse_reg_operand"))]
2756 "TARGET_SSE && reload_completed"
2757 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2758 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2759
2760 (define_insn "*pushxf"
2761 [(set (match_operand:XF 0 "push_operand" "=<,<")
2762 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2763 "optimize_function_for_speed_p (cfun)"
2764 {
2765 /* This insn should be already split before reg-stack. */
2766 gcc_unreachable ();
2767 }
2768 [(set_attr "type" "multi")
2769 (set_attr "unit" "i387,*")
2770 (set_attr "mode" "XF,SI")])
2771
2772 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2773 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2774 ;; Pushing using integer instructions is longer except for constants
2775 ;; and direct memory references (assuming that any given constant is pushed
2776 ;; only once, but this ought to be handled elsewhere).
2777
2778 (define_insn "*pushxf_nointeger"
2779 [(set (match_operand:XF 0 "push_operand" "=<,<")
2780 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2781 "optimize_function_for_size_p (cfun)"
2782 {
2783 /* This insn should be already split before reg-stack. */
2784 gcc_unreachable ();
2785 }
2786 [(set_attr "type" "multi")
2787 (set_attr "unit" "i387,*")
2788 (set_attr "mode" "XF,SI")])
2789
2790 ;; %%% Kill this when call knows how to work this out.
2791 (define_split
2792 [(set (match_operand:XF 0 "push_operand")
2793 (match_operand:XF 1 "fp_register_operand"))]
2794 "reload_completed"
2795 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2796 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2797 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2798
2799 (define_insn "*pushdf_rex64"
2800 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2801 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2802 "TARGET_64BIT"
2803 {
2804 /* This insn should be already split before reg-stack. */
2805 gcc_unreachable ();
2806 }
2807 [(set_attr "type" "multi")
2808 (set_attr "unit" "i387,*,*")
2809 (set_attr "mode" "DF,DI,DF")])
2810
2811 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2812 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2813 ;; On the average, pushdf using integers can be still shorter.
2814
2815 (define_insn "*pushdf"
2816 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2817 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2818 "!TARGET_64BIT"
2819 {
2820 /* This insn should be already split before reg-stack. */
2821 gcc_unreachable ();
2822 }
2823 [(set_attr "isa" "*,*,sse2")
2824 (set_attr "type" "multi")
2825 (set_attr "unit" "i387,*,*")
2826 (set_attr "mode" "DF,DI,DF")])
2827
2828 ;; %%% Kill this when call knows how to work this out.
2829 (define_split
2830 [(set (match_operand:DF 0 "push_operand")
2831 (match_operand:DF 1 "any_fp_register_operand"))]
2832 "reload_completed"
2833 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2834 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2835
2836 (define_insn "*pushsf_rex64"
2837 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2838 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2839 "TARGET_64BIT"
2840 {
2841 /* Anything else should be already split before reg-stack. */
2842 gcc_assert (which_alternative == 1);
2843 return "push{q}\t%q1";
2844 }
2845 [(set_attr "type" "multi,push,multi")
2846 (set_attr "unit" "i387,*,*")
2847 (set_attr "mode" "SF,DI,SF")])
2848
2849 (define_insn "*pushsf"
2850 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2851 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2852 "!TARGET_64BIT"
2853 {
2854 /* Anything else should be already split before reg-stack. */
2855 gcc_assert (which_alternative == 1);
2856 return "push{l}\t%1";
2857 }
2858 [(set_attr "type" "multi,push,multi")
2859 (set_attr "unit" "i387,*,*")
2860 (set_attr "mode" "SF,SI,SF")])
2861
2862 ;; %%% Kill this when call knows how to work this out.
2863 (define_split
2864 [(set (match_operand:SF 0 "push_operand")
2865 (match_operand:SF 1 "any_fp_register_operand"))]
2866 "reload_completed"
2867 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2868 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2869 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2870
2871 (define_split
2872 [(set (match_operand:SF 0 "push_operand")
2873 (match_operand:SF 1 "memory_operand"))]
2874 "reload_completed
2875 && (operands[2] = find_constant_src (insn))"
2876 [(set (match_dup 0) (match_dup 2))])
2877
2878 (define_split
2879 [(set (match_operand 0 "push_operand")
2880 (match_operand 1 "general_operand"))]
2881 "reload_completed
2882 && (GET_MODE (operands[0]) == TFmode
2883 || GET_MODE (operands[0]) == XFmode
2884 || GET_MODE (operands[0]) == DFmode)
2885 && !ANY_FP_REG_P (operands[1])"
2886 [(const_int 0)]
2887 "ix86_split_long_move (operands); DONE;")
2888 \f
2889 ;; Floating point move instructions.
2890
2891 (define_expand "movtf"
2892 [(set (match_operand:TF 0 "nonimmediate_operand")
2893 (match_operand:TF 1 "nonimmediate_operand"))]
2894 "TARGET_SSE"
2895 {
2896 ix86_expand_move (TFmode, operands);
2897 DONE;
2898 })
2899
2900 (define_expand "mov<mode>"
2901 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2902 (match_operand:X87MODEF 1 "general_operand"))]
2903 ""
2904 "ix86_expand_move (<MODE>mode, operands); DONE;")
2905
2906 (define_insn "*movtf_internal"
2907 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2908 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2909 "TARGET_SSE
2910 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2911 && (!can_create_pseudo_p ()
2912 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2913 || GET_CODE (operands[1]) != CONST_DOUBLE
2914 || (optimize_function_for_size_p (cfun)
2915 && standard_sse_constant_p (operands[1])
2916 && !memory_operand (operands[0], TFmode))
2917 || (!TARGET_MEMORY_MISMATCH_STALL
2918 && memory_operand (operands[0], TFmode)))"
2919 {
2920 switch (which_alternative)
2921 {
2922 case 0:
2923 return standard_sse_constant_opcode (insn, operands[1]);
2924 case 1:
2925 case 2:
2926 /* Handle misaligned load/store since we
2927 don't have movmisaligntf pattern. */
2928 if (misaligned_operand (operands[0], TFmode)
2929 || misaligned_operand (operands[1], TFmode))
2930 {
2931 if (get_attr_mode (insn) == MODE_V4SF)
2932 return "%vmovups\t{%1, %0|%0, %1}";
2933 else
2934 return "%vmovdqu\t{%1, %0|%0, %1}";
2935 }
2936 else
2937 {
2938 if (get_attr_mode (insn) == MODE_V4SF)
2939 return "%vmovaps\t{%1, %0|%0, %1}";
2940 else
2941 return "%vmovdqa\t{%1, %0|%0, %1}";
2942 }
2943
2944 case 3:
2945 case 4:
2946 return "#";
2947
2948 default:
2949 gcc_unreachable ();
2950 }
2951 }
2952 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2953 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2954 (set (attr "mode")
2955 (cond [(eq_attr "alternative" "3,4")
2956 (const_string "DI")
2957 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2958 (const_string "V4SF")
2959 (and (eq_attr "alternative" "2")
2960 (match_test "TARGET_SSE_TYPELESS_STORES"))
2961 (const_string "V4SF")
2962 (match_test "TARGET_AVX")
2963 (const_string "TI")
2964 (ior (not (match_test "TARGET_SSE2"))
2965 (match_test "optimize_function_for_size_p (cfun)"))
2966 (const_string "V4SF")
2967 ]
2968 (const_string "TI")))])
2969
2970 ;; Possible store forwarding (partial memory) stall in alternative 4.
2971 (define_insn "*movxf_internal"
2972 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2973 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2974 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2975 && (!can_create_pseudo_p ()
2976 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2977 || GET_CODE (operands[1]) != CONST_DOUBLE
2978 || (optimize_function_for_size_p (cfun)
2979 && standard_80387_constant_p (operands[1]) > 0
2980 && !memory_operand (operands[0], XFmode))
2981 || (!TARGET_MEMORY_MISMATCH_STALL
2982 && memory_operand (operands[0], XFmode)))"
2983 {
2984 switch (which_alternative)
2985 {
2986 case 0:
2987 case 1:
2988 return output_387_reg_move (insn, operands);
2989
2990 case 2:
2991 return standard_80387_constant_opcode (operands[1]);
2992
2993 case 3:
2994 case 4:
2995 return "#";
2996
2997 default:
2998 gcc_unreachable ();
2999 }
3000 }
3001 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3002 (set_attr "mode" "XF,XF,XF,SI,SI")])
3003
3004 (define_insn "*movdf_internal_rex64"
3005 [(set (match_operand:DF 0 "nonimmediate_operand"
3006 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
3007 (match_operand:DF 1 "general_operand"
3008 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
3009 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3010 && (!can_create_pseudo_p ()
3011 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3012 || GET_CODE (operands[1]) != CONST_DOUBLE
3013 || (optimize_function_for_size_p (cfun)
3014 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3015 && standard_80387_constant_p (operands[1]) > 0)
3016 || (TARGET_SSE2 && TARGET_SSE_MATH
3017 && standard_sse_constant_p (operands[1]))))
3018 || memory_operand (operands[0], DFmode))"
3019 {
3020 switch (which_alternative)
3021 {
3022 case 0:
3023 case 1:
3024 return output_387_reg_move (insn, operands);
3025
3026 case 2:
3027 return standard_80387_constant_opcode (operands[1]);
3028
3029 case 3:
3030 case 4:
3031 return "mov{q}\t{%1, %0|%0, %1}";
3032
3033 case 5:
3034 return "movabs{q}\t{%1, %0|%0, %1}";
3035
3036 case 6:
3037 return "#";
3038
3039 case 7:
3040 return standard_sse_constant_opcode (insn, operands[1]);
3041
3042 case 8:
3043 case 9:
3044 case 10:
3045 switch (get_attr_mode (insn))
3046 {
3047 case MODE_V2DF:
3048 return "%vmovapd\t{%1, %0|%0, %1}";
3049 case MODE_V4SF:
3050 return "%vmovaps\t{%1, %0|%0, %1}";
3051
3052 case MODE_DI:
3053 return "%vmovq\t{%1, %0|%0, %1}";
3054 case MODE_DF:
3055 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3056 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3057 return "%vmovsd\t{%1, %0|%0, %1}";
3058 case MODE_V1DF:
3059 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3060 case MODE_V2SF:
3061 return "%vmovlps\t{%1, %d0|%d0, %1}";
3062 default:
3063 gcc_unreachable ();
3064 }
3065
3066 case 11:
3067 case 12:
3068 /* Handle broken assemblers that require movd instead of movq. */
3069 return "%vmovd\t{%1, %0|%0, %1}";
3070
3071 default:
3072 gcc_unreachable();
3073 }
3074 }
3075 [(set (attr "type")
3076 (cond [(eq_attr "alternative" "0,1,2")
3077 (const_string "fmov")
3078 (eq_attr "alternative" "3,4,5")
3079 (const_string "imov")
3080 (eq_attr "alternative" "6")
3081 (const_string "multi")
3082 (eq_attr "alternative" "7")
3083 (const_string "sselog1")
3084 ]
3085 (const_string "ssemov")))
3086 (set (attr "modrm")
3087 (if_then_else
3088 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3089 (const_string "0")
3090 (const_string "*")))
3091 (set (attr "length_immediate")
3092 (if_then_else
3093 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3094 (const_string "8")
3095 (const_string "*")))
3096 (set (attr "prefix")
3097 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3098 (const_string "orig")
3099 (const_string "maybe_vex")))
3100 (set (attr "prefix_data16")
3101 (if_then_else (eq_attr "mode" "V1DF")
3102 (const_string "1")
3103 (const_string "*")))
3104 (set (attr "mode")
3105 (cond [(eq_attr "alternative" "0,1,2")
3106 (const_string "DF")
3107 (eq_attr "alternative" "3,4,5,6,11,12")
3108 (const_string "DI")
3109
3110 /* xorps is one byte shorter for !TARGET_AVX. */
3111 (eq_attr "alternative" "7")
3112 (cond [(match_test "TARGET_AVX")
3113 (const_string "V2DF")
3114 (match_test "optimize_function_for_size_p (cfun)")
3115 (const_string "V4SF")
3116 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3117 (const_string "TI")
3118 ]
3119 (const_string "V2DF"))
3120
3121 /* For architectures resolving dependencies on
3122 whole SSE registers use APD move to break dependency
3123 chains, otherwise use short move to avoid extra work.
3124
3125 movaps encodes one byte shorter for !TARGET_AVX. */
3126 (eq_attr "alternative" "8")
3127 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3128 (const_string "V4SF")
3129 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3130 (const_string "V2DF")
3131 (match_test "TARGET_AVX")
3132 (const_string "DF")
3133 (match_test "optimize_function_for_size_p (cfun)")
3134 (const_string "V4SF")
3135 ]
3136 (const_string "DF"))
3137 /* For architectures resolving dependencies on register
3138 parts we may avoid extra work to zero out upper part
3139 of register. */
3140 (eq_attr "alternative" "9")
3141 (if_then_else
3142 (match_test "TARGET_SSE_SPLIT_REGS")
3143 (const_string "V1DF")
3144 (const_string "DF"))
3145 ]
3146 (const_string "DF")))])
3147
3148 ;; Possible store forwarding (partial memory) stall in alternative 4.
3149 (define_insn "*movdf_internal"
3150 [(set (match_operand:DF 0 "nonimmediate_operand"
3151 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3152 (match_operand:DF 1 "general_operand"
3153 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3154 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3155 && (!can_create_pseudo_p ()
3156 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3157 || GET_CODE (operands[1]) != CONST_DOUBLE
3158 || (optimize_function_for_size_p (cfun)
3159 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3160 && standard_80387_constant_p (operands[1]) > 0)
3161 || (TARGET_SSE2 && TARGET_SSE_MATH
3162 && standard_sse_constant_p (operands[1])))
3163 && !memory_operand (operands[0], DFmode))
3164 || (!TARGET_MEMORY_MISMATCH_STALL
3165 && memory_operand (operands[0], DFmode)))"
3166 {
3167 switch (which_alternative)
3168 {
3169 case 0:
3170 case 1:
3171 return output_387_reg_move (insn, operands);
3172
3173 case 2:
3174 return standard_80387_constant_opcode (operands[1]);
3175
3176 case 3:
3177 case 4:
3178 return "#";
3179
3180 case 5:
3181 case 9:
3182 return standard_sse_constant_opcode (insn, operands[1]);
3183
3184 case 6:
3185 case 7:
3186 case 8:
3187 case 10:
3188 case 11:
3189 case 12:
3190 switch (get_attr_mode (insn))
3191 {
3192 case MODE_V2DF:
3193 return "%vmovapd\t{%1, %0|%0, %1}";
3194 case MODE_V4SF:
3195 return "%vmovaps\t{%1, %0|%0, %1}";
3196
3197 case MODE_DI:
3198 return "%vmovq\t{%1, %0|%0, %1}";
3199 case MODE_DF:
3200 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3201 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3202 return "%vmovsd\t{%1, %0|%0, %1}";
3203 case MODE_V1DF:
3204 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3205 case MODE_V2SF:
3206 return "%vmovlps\t{%1, %d0|%d0, %1}";
3207 default:
3208 gcc_unreachable ();
3209 }
3210
3211 default:
3212 gcc_unreachable ();
3213 }
3214 }
3215 [(set (attr "isa")
3216 (if_then_else (eq_attr "alternative" "5,6,7,8")
3217 (const_string "sse2")
3218 (const_string "*")))
3219 (set (attr "type")
3220 (cond [(eq_attr "alternative" "0,1,2")
3221 (const_string "fmov")
3222 (eq_attr "alternative" "3,4")
3223 (const_string "multi")
3224 (eq_attr "alternative" "5,9")
3225 (const_string "sselog1")
3226 ]
3227 (const_string "ssemov")))
3228 (set (attr "prefix")
3229 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3230 (const_string "orig")
3231 (const_string "maybe_vex")))
3232 (set (attr "prefix_data16")
3233 (if_then_else (eq_attr "mode" "V1DF")
3234 (const_string "1")
3235 (const_string "*")))
3236 (set (attr "mode")
3237 (cond [(eq_attr "alternative" "0,1,2")
3238 (const_string "DF")
3239 (eq_attr "alternative" "3,4")
3240 (const_string "SI")
3241
3242 /* For SSE1, we have many fewer alternatives. */
3243 (not (match_test "TARGET_SSE2"))
3244 (if_then_else
3245 (eq_attr "alternative" "5,6,9,10")
3246 (const_string "V4SF")
3247 (const_string "V2SF"))
3248
3249 /* xorps is one byte shorter for !TARGET_AVX. */
3250 (eq_attr "alternative" "5,9")
3251 (cond [(match_test "TARGET_AVX")
3252 (const_string "V2DF")
3253 (match_test "optimize_function_for_size_p (cfun)")
3254 (const_string "V4SF")
3255 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3256 (const_string "TI")
3257 ]
3258 (const_string "V2DF"))
3259
3260 /* For architectures resolving dependencies on
3261 whole SSE registers use APD move to break dependency
3262 chains, otherwise use short move to avoid extra work.
3263
3264 movaps encodes one byte shorter for !TARGET_AVX. */
3265 (eq_attr "alternative" "6,10")
3266 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3267 (const_string "V4SF")
3268 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3269 (const_string "V2DF")
3270 (match_test "TARGET_AVX")
3271 (const_string "DF")
3272 (match_test "optimize_function_for_size_p (cfun)")
3273 (const_string "V4SF")
3274 ]
3275 (const_string "DF"))
3276
3277 /* For architectures resolving dependencies on register
3278 parts we may avoid extra work to zero out upper part
3279 of register. */
3280 (eq_attr "alternative" "7,11")
3281 (if_then_else
3282 (match_test "TARGET_SSE_SPLIT_REGS")
3283 (const_string "V1DF")
3284 (const_string "DF"))
3285 ]
3286 (const_string "DF")))])
3287
3288 (define_insn "*movsf_internal"
3289 [(set (match_operand:SF 0 "nonimmediate_operand"
3290 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3291 (match_operand:SF 1 "general_operand"
3292 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3293 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3294 && (!can_create_pseudo_p ()
3295 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3296 || GET_CODE (operands[1]) != CONST_DOUBLE
3297 || (optimize_function_for_size_p (cfun)
3298 && ((!TARGET_SSE_MATH
3299 && standard_80387_constant_p (operands[1]) > 0)
3300 || (TARGET_SSE_MATH
3301 && standard_sse_constant_p (operands[1]))))
3302 || memory_operand (operands[0], SFmode))"
3303 {
3304 switch (which_alternative)
3305 {
3306 case 0:
3307 case 1:
3308 return output_387_reg_move (insn, operands);
3309
3310 case 2:
3311 return standard_80387_constant_opcode (operands[1]);
3312
3313 case 3:
3314 case 4:
3315 return "mov{l}\t{%1, %0|%0, %1}";
3316
3317 case 5:
3318 return standard_sse_constant_opcode (insn, operands[1]);
3319
3320 case 6:
3321 if (get_attr_mode (insn) == MODE_V4SF)
3322 return "%vmovaps\t{%1, %0|%0, %1}";
3323 if (TARGET_AVX)
3324 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3325
3326 case 7:
3327 case 8:
3328 return "%vmovss\t{%1, %0|%0, %1}";
3329
3330 case 9:
3331 case 10:
3332 case 14:
3333 case 15:
3334 return "movd\t{%1, %0|%0, %1}";
3335
3336 case 11:
3337 return "movq\t{%1, %0|%0, %1}";
3338
3339 case 12:
3340 case 13:
3341 return "%vmovd\t{%1, %0|%0, %1}";
3342
3343 default:
3344 gcc_unreachable ();
3345 }
3346 }
3347 [(set (attr "type")
3348 (cond [(eq_attr "alternative" "0,1,2")
3349 (const_string "fmov")
3350 (eq_attr "alternative" "3,4")
3351 (const_string "multi")
3352 (eq_attr "alternative" "5")
3353 (const_string "sselog1")
3354 (eq_attr "alternative" "9,10,11,14,15")
3355 (const_string "mmxmov")
3356 ]
3357 (const_string "ssemov")))
3358 (set (attr "prefix")
3359 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3360 (const_string "maybe_vex")
3361 (const_string "orig")))
3362 (set (attr "mode")
3363 (cond [(eq_attr "alternative" "3,4,9,10")
3364 (const_string "SI")
3365 (eq_attr "alternative" "5")
3366 (cond [(match_test "TARGET_AVX")
3367 (const_string "V4SF")
3368 (ior (not (match_test "TARGET_SSE2"))
3369 (match_test "optimize_function_for_size_p (cfun)"))
3370 (const_string "V4SF")
3371 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3372 (const_string "TI")
3373 ]
3374 (const_string "V4SF"))
3375
3376 /* For architectures resolving dependencies on
3377 whole SSE registers use APS move to break dependency
3378 chains, otherwise use short move to avoid extra work.
3379
3380 Do the same for architectures resolving dependencies on
3381 the parts. While in DF mode it is better to always handle
3382 just register parts, the SF mode is different due to lack
3383 of instructions to load just part of the register. It is
3384 better to maintain the whole registers in single format
3385 to avoid problems on using packed logical operations. */
3386 (eq_attr "alternative" "6")
3387 (if_then_else
3388 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3389 (match_test "TARGET_SSE_SPLIT_REGS"))
3390 (const_string "V4SF")
3391 (const_string "SF"))
3392 (eq_attr "alternative" "11")
3393 (const_string "DI")]
3394 (const_string "SF")))])
3395
3396 (define_split
3397 [(set (match_operand 0 "any_fp_register_operand")
3398 (match_operand 1 "memory_operand"))]
3399 "reload_completed
3400 && (GET_MODE (operands[0]) == TFmode
3401 || GET_MODE (operands[0]) == XFmode
3402 || GET_MODE (operands[0]) == DFmode
3403 || GET_MODE (operands[0]) == SFmode)
3404 && (operands[2] = find_constant_src (insn))"
3405 [(set (match_dup 0) (match_dup 2))]
3406 {
3407 rtx c = operands[2];
3408 int r = REGNO (operands[0]);
3409
3410 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3411 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3412 FAIL;
3413 })
3414
3415 (define_split
3416 [(set (match_operand 0 "any_fp_register_operand")
3417 (float_extend (match_operand 1 "memory_operand")))]
3418 "reload_completed
3419 && (GET_MODE (operands[0]) == TFmode
3420 || GET_MODE (operands[0]) == XFmode
3421 || GET_MODE (operands[0]) == DFmode)
3422 && (operands[2] = find_constant_src (insn))"
3423 [(set (match_dup 0) (match_dup 2))]
3424 {
3425 rtx c = operands[2];
3426 int r = REGNO (operands[0]);
3427
3428 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3429 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3430 FAIL;
3431 })
3432
3433 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3434 (define_split
3435 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3436 (match_operand:X87MODEF 1 "immediate_operand"))]
3437 "reload_completed
3438 && (standard_80387_constant_p (operands[1]) == 8
3439 || standard_80387_constant_p (operands[1]) == 9)"
3440 [(set (match_dup 0)(match_dup 1))
3441 (set (match_dup 0)
3442 (neg:X87MODEF (match_dup 0)))]
3443 {
3444 REAL_VALUE_TYPE r;
3445
3446 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3447 if (real_isnegzero (&r))
3448 operands[1] = CONST0_RTX (<MODE>mode);
3449 else
3450 operands[1] = CONST1_RTX (<MODE>mode);
3451 })
3452
3453 (define_split
3454 [(set (match_operand 0 "nonimmediate_operand")
3455 (match_operand 1 "general_operand"))]
3456 "reload_completed
3457 && (GET_MODE (operands[0]) == TFmode
3458 || GET_MODE (operands[0]) == XFmode
3459 || GET_MODE (operands[0]) == DFmode)
3460 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3461 [(const_int 0)]
3462 "ix86_split_long_move (operands); DONE;")
3463
3464 (define_insn "swapxf"
3465 [(set (match_operand:XF 0 "register_operand" "+f")
3466 (match_operand:XF 1 "register_operand" "+f"))
3467 (set (match_dup 1)
3468 (match_dup 0))]
3469 "TARGET_80387"
3470 {
3471 if (STACK_TOP_P (operands[0]))
3472 return "fxch\t%1";
3473 else
3474 return "fxch\t%0";
3475 }
3476 [(set_attr "type" "fxch")
3477 (set_attr "mode" "XF")])
3478
3479 (define_insn "*swap<mode>"
3480 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3481 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3482 (set (match_dup 1)
3483 (match_dup 0))]
3484 "TARGET_80387 || reload_completed"
3485 {
3486 if (STACK_TOP_P (operands[0]))
3487 return "fxch\t%1";
3488 else
3489 return "fxch\t%0";
3490 }
3491 [(set_attr "type" "fxch")
3492 (set_attr "mode" "<MODE>")])
3493 \f
3494 ;; Zero extension instructions
3495
3496 (define_expand "zero_extendsidi2"
3497 [(set (match_operand:DI 0 "nonimmediate_operand")
3498 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3499
3500 (define_insn "*zero_extendsidi2_rex64"
3501 [(set (match_operand:DI 0 "nonimmediate_operand"
3502 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3503 (zero_extend:DI
3504 (match_operand:SI 1 "x86_64_zext_general_operand"
3505 "rmWz,0,r ,m ,r ,m")))]
3506 "TARGET_64BIT"
3507 {
3508 switch (get_attr_type (insn))
3509 {
3510 case TYPE_IMOVX:
3511 if (ix86_use_lea_for_mov (insn, operands))
3512 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3513 else
3514 return "mov{l}\t{%1, %k0|%k0, %1}";
3515
3516 case TYPE_MULTI:
3517 return "#";
3518
3519 case TYPE_MMXMOV:
3520 return "movd\t{%1, %0|%0, %1}";
3521
3522 case TYPE_SSEMOV:
3523 return "%vmovd\t{%1, %0|%0, %1}";
3524
3525 default:
3526 gcc_unreachable ();
3527 }
3528 }
3529 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3530 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3531 (set_attr "prefix_0f" "0,*,*,*,*,*")
3532 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3533
3534 (define_insn "*zero_extendsidi2"
3535 [(set (match_operand:DI 0 "nonimmediate_operand"
3536 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3537 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3538 "0 ,rm,r ,r ,m ,r ,m")))]
3539 "!TARGET_64BIT"
3540 "@
3541 #
3542 #
3543 #
3544 movd\t{%1, %0|%0, %1}
3545 movd\t{%1, %0|%0, %1}
3546 %vmovd\t{%1, %0|%0, %1}
3547 %vmovd\t{%1, %0|%0, %1}"
3548 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3549 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3550 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3551 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3552
3553 (define_split
3554 [(set (match_operand:DI 0 "memory_operand")
3555 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3556 "reload_completed"
3557 [(set (match_dup 4) (const_int 0))]
3558 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3559
3560 (define_split
3561 [(set (match_operand:DI 0 "register_operand")
3562 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3563 "!TARGET_64BIT && reload_completed
3564 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3565 && true_regnum (operands[0]) == true_regnum (operands[1])"
3566 [(set (match_dup 4) (const_int 0))]
3567 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3568
3569 (define_split
3570 [(set (match_operand:DI 0 "nonimmediate_operand")
3571 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3572 "!TARGET_64BIT && reload_completed
3573 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3574 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3575 [(set (match_dup 3) (match_dup 1))
3576 (set (match_dup 4) (const_int 0))]
3577 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3578
3579 (define_insn "zero_extend<mode>di2"
3580 [(set (match_operand:DI 0 "register_operand" "=r")
3581 (zero_extend:DI
3582 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3583 "TARGET_64BIT"
3584 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3585 [(set_attr "type" "imovx")
3586 (set_attr "mode" "SI")])
3587
3588 (define_expand "zero_extend<mode>si2"
3589 [(set (match_operand:SI 0 "register_operand")
3590 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3591 ""
3592 {
3593 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3594 {
3595 operands[1] = force_reg (<MODE>mode, operands[1]);
3596 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3597 DONE;
3598 }
3599 })
3600
3601 (define_insn_and_split "zero_extend<mode>si2_and"
3602 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3603 (zero_extend:SI
3604 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3605 (clobber (reg:CC FLAGS_REG))]
3606 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3607 "#"
3608 "&& reload_completed"
3609 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3610 (clobber (reg:CC FLAGS_REG))])]
3611 {
3612 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3613 {
3614 ix86_expand_clear (operands[0]);
3615
3616 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3617 emit_insn (gen_movstrict<mode>
3618 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3619 DONE;
3620 }
3621
3622 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3623 }
3624 [(set_attr "type" "alu1")
3625 (set_attr "mode" "SI")])
3626
3627 (define_insn "*zero_extend<mode>si2"
3628 [(set (match_operand:SI 0 "register_operand" "=r")
3629 (zero_extend:SI
3630 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3631 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3632 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3633 [(set_attr "type" "imovx")
3634 (set_attr "mode" "SI")])
3635
3636 (define_expand "zero_extendqihi2"
3637 [(set (match_operand:HI 0 "register_operand")
3638 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3639 ""
3640 {
3641 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3642 {
3643 operands[1] = force_reg (QImode, operands[1]);
3644 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3645 DONE;
3646 }
3647 })
3648
3649 (define_insn_and_split "zero_extendqihi2_and"
3650 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3651 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3652 (clobber (reg:CC FLAGS_REG))]
3653 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3654 "#"
3655 "&& reload_completed"
3656 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3657 (clobber (reg:CC FLAGS_REG))])]
3658 {
3659 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3660 {
3661 ix86_expand_clear (operands[0]);
3662
3663 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3664 emit_insn (gen_movstrictqi
3665 (gen_lowpart (QImode, operands[0]), operands[1]));
3666 DONE;
3667 }
3668
3669 operands[0] = gen_lowpart (SImode, operands[0]);
3670 }
3671 [(set_attr "type" "alu1")
3672 (set_attr "mode" "SI")])
3673
3674 ; zero extend to SImode to avoid partial register stalls
3675 (define_insn "*zero_extendqihi2"
3676 [(set (match_operand:HI 0 "register_operand" "=r")
3677 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3678 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3679 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3680 [(set_attr "type" "imovx")
3681 (set_attr "mode" "SI")])
3682 \f
3683 ;; Sign extension instructions
3684
3685 (define_expand "extendsidi2"
3686 [(set (match_operand:DI 0 "register_operand")
3687 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3688 ""
3689 {
3690 if (!TARGET_64BIT)
3691 {
3692 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3693 DONE;
3694 }
3695 })
3696
3697 (define_insn "*extendsidi2_rex64"
3698 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3699 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3700 "TARGET_64BIT"
3701 "@
3702 {cltq|cdqe}
3703 movs{lq|x}\t{%1, %0|%0, %1}"
3704 [(set_attr "type" "imovx")
3705 (set_attr "mode" "DI")
3706 (set_attr "prefix_0f" "0")
3707 (set_attr "modrm" "0,1")])
3708
3709 (define_insn "extendsidi2_1"
3710 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3711 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3712 (clobber (reg:CC FLAGS_REG))
3713 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3714 "!TARGET_64BIT"
3715 "#")
3716
3717 ;; Extend to memory case when source register does die.
3718 (define_split
3719 [(set (match_operand:DI 0 "memory_operand")
3720 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3721 (clobber (reg:CC FLAGS_REG))
3722 (clobber (match_operand:SI 2 "register_operand"))]
3723 "(reload_completed
3724 && dead_or_set_p (insn, operands[1])
3725 && !reg_mentioned_p (operands[1], operands[0]))"
3726 [(set (match_dup 3) (match_dup 1))
3727 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3728 (clobber (reg:CC FLAGS_REG))])
3729 (set (match_dup 4) (match_dup 1))]
3730 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3731
3732 ;; Extend to memory case when source register does not die.
3733 (define_split
3734 [(set (match_operand:DI 0 "memory_operand")
3735 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3736 (clobber (reg:CC FLAGS_REG))
3737 (clobber (match_operand:SI 2 "register_operand"))]
3738 "reload_completed"
3739 [(const_int 0)]
3740 {
3741 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3742
3743 emit_move_insn (operands[3], operands[1]);
3744
3745 /* Generate a cltd if possible and doing so it profitable. */
3746 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3747 && true_regnum (operands[1]) == AX_REG
3748 && true_regnum (operands[2]) == DX_REG)
3749 {
3750 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3751 }
3752 else
3753 {
3754 emit_move_insn (operands[2], operands[1]);
3755 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3756 }
3757 emit_move_insn (operands[4], operands[2]);
3758 DONE;
3759 })
3760
3761 ;; Extend to register case. Optimize case where source and destination
3762 ;; registers match and cases where we can use cltd.
3763 (define_split
3764 [(set (match_operand:DI 0 "register_operand")
3765 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3766 (clobber (reg:CC FLAGS_REG))
3767 (clobber (match_scratch:SI 2))]
3768 "reload_completed"
3769 [(const_int 0)]
3770 {
3771 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3772
3773 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3774 emit_move_insn (operands[3], operands[1]);
3775
3776 /* Generate a cltd if possible and doing so it profitable. */
3777 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3778 && true_regnum (operands[3]) == AX_REG
3779 && true_regnum (operands[4]) == DX_REG)
3780 {
3781 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3782 DONE;
3783 }
3784
3785 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3786 emit_move_insn (operands[4], operands[1]);
3787
3788 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3789 DONE;
3790 })
3791
3792 (define_insn "extend<mode>di2"
3793 [(set (match_operand:DI 0 "register_operand" "=r")
3794 (sign_extend:DI
3795 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3796 "TARGET_64BIT"
3797 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3798 [(set_attr "type" "imovx")
3799 (set_attr "mode" "DI")])
3800
3801 (define_insn "extendhisi2"
3802 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3803 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3804 ""
3805 {
3806 switch (get_attr_prefix_0f (insn))
3807 {
3808 case 0:
3809 return "{cwtl|cwde}";
3810 default:
3811 return "movs{wl|x}\t{%1, %0|%0, %1}";
3812 }
3813 }
3814 [(set_attr "type" "imovx")
3815 (set_attr "mode" "SI")
3816 (set (attr "prefix_0f")
3817 ;; movsx is short decodable while cwtl is vector decoded.
3818 (if_then_else (and (eq_attr "cpu" "!k6")
3819 (eq_attr "alternative" "0"))
3820 (const_string "0")
3821 (const_string "1")))
3822 (set (attr "modrm")
3823 (if_then_else (eq_attr "prefix_0f" "0")
3824 (const_string "0")
3825 (const_string "1")))])
3826
3827 (define_insn "*extendhisi2_zext"
3828 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3829 (zero_extend:DI
3830 (sign_extend:SI
3831 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3832 "TARGET_64BIT"
3833 {
3834 switch (get_attr_prefix_0f (insn))
3835 {
3836 case 0:
3837 return "{cwtl|cwde}";
3838 default:
3839 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3840 }
3841 }
3842 [(set_attr "type" "imovx")
3843 (set_attr "mode" "SI")
3844 (set (attr "prefix_0f")
3845 ;; movsx is short decodable while cwtl is vector decoded.
3846 (if_then_else (and (eq_attr "cpu" "!k6")
3847 (eq_attr "alternative" "0"))
3848 (const_string "0")
3849 (const_string "1")))
3850 (set (attr "modrm")
3851 (if_then_else (eq_attr "prefix_0f" "0")
3852 (const_string "0")
3853 (const_string "1")))])
3854
3855 (define_insn "extendqisi2"
3856 [(set (match_operand:SI 0 "register_operand" "=r")
3857 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3858 ""
3859 "movs{bl|x}\t{%1, %0|%0, %1}"
3860 [(set_attr "type" "imovx")
3861 (set_attr "mode" "SI")])
3862
3863 (define_insn "*extendqisi2_zext"
3864 [(set (match_operand:DI 0 "register_operand" "=r")
3865 (zero_extend:DI
3866 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3867 "TARGET_64BIT"
3868 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3869 [(set_attr "type" "imovx")
3870 (set_attr "mode" "SI")])
3871
3872 (define_insn "extendqihi2"
3873 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3874 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3875 ""
3876 {
3877 switch (get_attr_prefix_0f (insn))
3878 {
3879 case 0:
3880 return "{cbtw|cbw}";
3881 default:
3882 return "movs{bw|x}\t{%1, %0|%0, %1}";
3883 }
3884 }
3885 [(set_attr "type" "imovx")
3886 (set_attr "mode" "HI")
3887 (set (attr "prefix_0f")
3888 ;; movsx is short decodable while cwtl is vector decoded.
3889 (if_then_else (and (eq_attr "cpu" "!k6")
3890 (eq_attr "alternative" "0"))
3891 (const_string "0")
3892 (const_string "1")))
3893 (set (attr "modrm")
3894 (if_then_else (eq_attr "prefix_0f" "0")
3895 (const_string "0")
3896 (const_string "1")))])
3897 \f
3898 ;; Conversions between float and double.
3899
3900 ;; These are all no-ops in the model used for the 80387.
3901 ;; So just emit moves.
3902
3903 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3904 (define_split
3905 [(set (match_operand:DF 0 "push_operand")
3906 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3907 "reload_completed"
3908 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3909 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3910
3911 (define_split
3912 [(set (match_operand:XF 0 "push_operand")
3913 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3914 "reload_completed"
3915 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3916 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3917 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3918
3919 (define_expand "extendsfdf2"
3920 [(set (match_operand:DF 0 "nonimmediate_operand")
3921 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3922 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3923 {
3924 /* ??? Needed for compress_float_constant since all fp constants
3925 are TARGET_LEGITIMATE_CONSTANT_P. */
3926 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3927 {
3928 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3929 && standard_80387_constant_p (operands[1]) > 0)
3930 {
3931 operands[1] = simplify_const_unary_operation
3932 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3933 emit_move_insn_1 (operands[0], operands[1]);
3934 DONE;
3935 }
3936 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3937 }
3938 })
3939
3940 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3941 cvtss2sd:
3942 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3943 cvtps2pd xmm2,xmm1
3944 We do the conversion post reload to avoid producing of 128bit spills
3945 that might lead to ICE on 32bit target. The sequence unlikely combine
3946 anyway. */
3947 (define_split
3948 [(set (match_operand:DF 0 "register_operand")
3949 (float_extend:DF
3950 (match_operand:SF 1 "nonimmediate_operand")))]
3951 "TARGET_USE_VECTOR_FP_CONVERTS
3952 && optimize_insn_for_speed_p ()
3953 && reload_completed && SSE_REG_P (operands[0])"
3954 [(set (match_dup 2)
3955 (float_extend:V2DF
3956 (vec_select:V2SF
3957 (match_dup 3)
3958 (parallel [(const_int 0) (const_int 1)]))))]
3959 {
3960 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3961 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3962 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3963 Try to avoid move when unpacking can be done in source. */
3964 if (REG_P (operands[1]))
3965 {
3966 /* If it is unsafe to overwrite upper half of source, we need
3967 to move to destination and unpack there. */
3968 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3969 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3970 && true_regnum (operands[0]) != true_regnum (operands[1]))
3971 {
3972 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3973 emit_move_insn (tmp, operands[1]);
3974 }
3975 else
3976 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3977 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3978 operands[3]));
3979 }
3980 else
3981 emit_insn (gen_vec_setv4sf_0 (operands[3],
3982 CONST0_RTX (V4SFmode), operands[1]));
3983 })
3984
3985 (define_insn "*extendsfdf2_mixed"
3986 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3987 (float_extend:DF
3988 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3989 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3990 {
3991 switch (which_alternative)
3992 {
3993 case 0:
3994 case 1:
3995 return output_387_reg_move (insn, operands);
3996
3997 case 2:
3998 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3999
4000 default:
4001 gcc_unreachable ();
4002 }
4003 }
4004 [(set_attr "type" "fmov,fmov,ssecvt")
4005 (set_attr "prefix" "orig,orig,maybe_vex")
4006 (set_attr "mode" "SF,XF,DF")])
4007
4008 (define_insn "*extendsfdf2_sse"
4009 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4010 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4011 "TARGET_SSE2 && TARGET_SSE_MATH"
4012 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4013 [(set_attr "type" "ssecvt")
4014 (set_attr "prefix" "maybe_vex")
4015 (set_attr "mode" "DF")])
4016
4017 (define_insn "*extendsfdf2_i387"
4018 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4019 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4020 "TARGET_80387"
4021 "* return output_387_reg_move (insn, operands);"
4022 [(set_attr "type" "fmov")
4023 (set_attr "mode" "SF,XF")])
4024
4025 (define_expand "extend<mode>xf2"
4026 [(set (match_operand:XF 0 "nonimmediate_operand")
4027 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4028 "TARGET_80387"
4029 {
4030 /* ??? Needed for compress_float_constant since all fp constants
4031 are TARGET_LEGITIMATE_CONSTANT_P. */
4032 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4033 {
4034 if (standard_80387_constant_p (operands[1]) > 0)
4035 {
4036 operands[1] = simplify_const_unary_operation
4037 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4038 emit_move_insn_1 (operands[0], operands[1]);
4039 DONE;
4040 }
4041 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4042 }
4043 })
4044
4045 (define_insn "*extend<mode>xf2_i387"
4046 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4047 (float_extend:XF
4048 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4049 "TARGET_80387"
4050 "* return output_387_reg_move (insn, operands);"
4051 [(set_attr "type" "fmov")
4052 (set_attr "mode" "<MODE>,XF")])
4053
4054 ;; %%% This seems bad bad news.
4055 ;; This cannot output into an f-reg because there is no way to be sure
4056 ;; of truncating in that case. Otherwise this is just like a simple move
4057 ;; insn. So we pretend we can output to a reg in order to get better
4058 ;; register preferencing, but we really use a stack slot.
4059
4060 ;; Conversion from DFmode to SFmode.
4061
4062 (define_expand "truncdfsf2"
4063 [(set (match_operand:SF 0 "nonimmediate_operand")
4064 (float_truncate:SF
4065 (match_operand:DF 1 "nonimmediate_operand")))]
4066 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4067 {
4068 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4069 ;
4070 else if (flag_unsafe_math_optimizations)
4071 ;
4072 else
4073 {
4074 enum ix86_stack_slot slot = (virtuals_instantiated
4075 ? SLOT_TEMP
4076 : SLOT_VIRTUAL);
4077 rtx temp = assign_386_stack_local (SFmode, slot);
4078 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4079 DONE;
4080 }
4081 })
4082
4083 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4084 cvtsd2ss:
4085 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4086 cvtpd2ps xmm2,xmm1
4087 We do the conversion post reload to avoid producing of 128bit spills
4088 that might lead to ICE on 32bit target. The sequence unlikely combine
4089 anyway. */
4090 (define_split
4091 [(set (match_operand:SF 0 "register_operand")
4092 (float_truncate:SF
4093 (match_operand:DF 1 "nonimmediate_operand")))]
4094 "TARGET_USE_VECTOR_FP_CONVERTS
4095 && optimize_insn_for_speed_p ()
4096 && reload_completed && SSE_REG_P (operands[0])"
4097 [(set (match_dup 2)
4098 (vec_concat:V4SF
4099 (float_truncate:V2SF
4100 (match_dup 4))
4101 (match_dup 3)))]
4102 {
4103 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4104 operands[3] = CONST0_RTX (V2SFmode);
4105 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4106 /* Use movsd for loading from memory, unpcklpd for registers.
4107 Try to avoid move when unpacking can be done in source, or SSE3
4108 movddup is available. */
4109 if (REG_P (operands[1]))
4110 {
4111 if (!TARGET_SSE3
4112 && true_regnum (operands[0]) != true_regnum (operands[1])
4113 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4114 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4115 {
4116 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4117 emit_move_insn (tmp, operands[1]);
4118 operands[1] = tmp;
4119 }
4120 else if (!TARGET_SSE3)
4121 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4122 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4123 }
4124 else
4125 emit_insn (gen_sse2_loadlpd (operands[4],
4126 CONST0_RTX (V2DFmode), operands[1]));
4127 })
4128
4129 (define_expand "truncdfsf2_with_temp"
4130 [(parallel [(set (match_operand:SF 0)
4131 (float_truncate:SF (match_operand:DF 1)))
4132 (clobber (match_operand:SF 2))])])
4133
4134 (define_insn "*truncdfsf_fast_mixed"
4135 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4136 (float_truncate:SF
4137 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4138 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4139 {
4140 switch (which_alternative)
4141 {
4142 case 0:
4143 return output_387_reg_move (insn, operands);
4144 case 1:
4145 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4146 default:
4147 gcc_unreachable ();
4148 }
4149 }
4150 [(set_attr "type" "fmov,ssecvt")
4151 (set_attr "prefix" "orig,maybe_vex")
4152 (set_attr "mode" "SF")])
4153
4154 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4155 ;; because nothing we do here is unsafe.
4156 (define_insn "*truncdfsf_fast_sse"
4157 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4158 (float_truncate:SF
4159 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4160 "TARGET_SSE2 && TARGET_SSE_MATH"
4161 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4162 [(set_attr "type" "ssecvt")
4163 (set_attr "prefix" "maybe_vex")
4164 (set_attr "mode" "SF")])
4165
4166 (define_insn "*truncdfsf_fast_i387"
4167 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4168 (float_truncate:SF
4169 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4170 "TARGET_80387 && flag_unsafe_math_optimizations"
4171 "* return output_387_reg_move (insn, operands);"
4172 [(set_attr "type" "fmov")
4173 (set_attr "mode" "SF")])
4174
4175 (define_insn "*truncdfsf_mixed"
4176 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4177 (float_truncate:SF
4178 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4179 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4180 "TARGET_MIX_SSE_I387"
4181 {
4182 switch (which_alternative)
4183 {
4184 case 0:
4185 return output_387_reg_move (insn, operands);
4186 case 1:
4187 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4188
4189 default:
4190 return "#";
4191 }
4192 }
4193 [(set_attr "isa" "*,sse2,*,*,*")
4194 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4195 (set_attr "unit" "*,*,i387,i387,i387")
4196 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4197 (set_attr "mode" "SF")])
4198
4199 (define_insn "*truncdfsf_i387"
4200 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4201 (float_truncate:SF
4202 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4203 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4204 "TARGET_80387"
4205 {
4206 switch (which_alternative)
4207 {
4208 case 0:
4209 return output_387_reg_move (insn, operands);
4210
4211 default:
4212 return "#";
4213 }
4214 }
4215 [(set_attr "type" "fmov,multi,multi,multi")
4216 (set_attr "unit" "*,i387,i387,i387")
4217 (set_attr "mode" "SF")])
4218
4219 (define_insn "*truncdfsf2_i387_1"
4220 [(set (match_operand:SF 0 "memory_operand" "=m")
4221 (float_truncate:SF
4222 (match_operand:DF 1 "register_operand" "f")))]
4223 "TARGET_80387
4224 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4225 && !TARGET_MIX_SSE_I387"
4226 "* return output_387_reg_move (insn, operands);"
4227 [(set_attr "type" "fmov")
4228 (set_attr "mode" "SF")])
4229
4230 (define_split
4231 [(set (match_operand:SF 0 "register_operand")
4232 (float_truncate:SF
4233 (match_operand:DF 1 "fp_register_operand")))
4234 (clobber (match_operand 2))]
4235 "reload_completed"
4236 [(set (match_dup 2) (match_dup 1))
4237 (set (match_dup 0) (match_dup 2))]
4238 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4239
4240 ;; Conversion from XFmode to {SF,DF}mode
4241
4242 (define_expand "truncxf<mode>2"
4243 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4244 (float_truncate:MODEF
4245 (match_operand:XF 1 "register_operand")))
4246 (clobber (match_dup 2))])]
4247 "TARGET_80387"
4248 {
4249 if (flag_unsafe_math_optimizations)
4250 {
4251 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4252 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4253 if (reg != operands[0])
4254 emit_move_insn (operands[0], reg);
4255 DONE;
4256 }
4257 else
4258 {
4259 enum ix86_stack_slot slot = (virtuals_instantiated
4260 ? SLOT_TEMP
4261 : SLOT_VIRTUAL);
4262 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4263 }
4264 })
4265
4266 (define_insn "*truncxfsf2_mixed"
4267 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4268 (float_truncate:SF
4269 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4270 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4271 "TARGET_80387"
4272 {
4273 gcc_assert (!which_alternative);
4274 return output_387_reg_move (insn, operands);
4275 }
4276 [(set_attr "type" "fmov,multi,multi,multi")
4277 (set_attr "unit" "*,i387,i387,i387")
4278 (set_attr "mode" "SF")])
4279
4280 (define_insn "*truncxfdf2_mixed"
4281 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4282 (float_truncate:DF
4283 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4284 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4285 "TARGET_80387"
4286 {
4287 gcc_assert (!which_alternative);
4288 return output_387_reg_move (insn, operands);
4289 }
4290 [(set_attr "isa" "*,*,sse2,*")
4291 (set_attr "type" "fmov,multi,multi,multi")
4292 (set_attr "unit" "*,i387,i387,i387")
4293 (set_attr "mode" "DF")])
4294
4295 (define_insn "truncxf<mode>2_i387_noop"
4296 [(set (match_operand:MODEF 0 "register_operand" "=f")
4297 (float_truncate:MODEF
4298 (match_operand:XF 1 "register_operand" "f")))]
4299 "TARGET_80387 && flag_unsafe_math_optimizations"
4300 "* return output_387_reg_move (insn, operands);"
4301 [(set_attr "type" "fmov")
4302 (set_attr "mode" "<MODE>")])
4303
4304 (define_insn "*truncxf<mode>2_i387"
4305 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4306 (float_truncate:MODEF
4307 (match_operand:XF 1 "register_operand" "f")))]
4308 "TARGET_80387"
4309 "* return output_387_reg_move (insn, operands);"
4310 [(set_attr "type" "fmov")
4311 (set_attr "mode" "<MODE>")])
4312
4313 (define_split
4314 [(set (match_operand:MODEF 0 "register_operand")
4315 (float_truncate:MODEF
4316 (match_operand:XF 1 "register_operand")))
4317 (clobber (match_operand:MODEF 2 "memory_operand"))]
4318 "TARGET_80387 && reload_completed"
4319 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4320 (set (match_dup 0) (match_dup 2))])
4321
4322 (define_split
4323 [(set (match_operand:MODEF 0 "memory_operand")
4324 (float_truncate:MODEF
4325 (match_operand:XF 1 "register_operand")))
4326 (clobber (match_operand:MODEF 2 "memory_operand"))]
4327 "TARGET_80387"
4328 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4329 \f
4330 ;; Signed conversion to DImode.
4331
4332 (define_expand "fix_truncxfdi2"
4333 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4334 (fix:DI (match_operand:XF 1 "register_operand")))
4335 (clobber (reg:CC FLAGS_REG))])]
4336 "TARGET_80387"
4337 {
4338 if (TARGET_FISTTP)
4339 {
4340 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4341 DONE;
4342 }
4343 })
4344
4345 (define_expand "fix_trunc<mode>di2"
4346 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4347 (fix:DI (match_operand:MODEF 1 "register_operand")))
4348 (clobber (reg:CC FLAGS_REG))])]
4349 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4350 {
4351 if (TARGET_FISTTP
4352 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4353 {
4354 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4355 DONE;
4356 }
4357 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4358 {
4359 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4360 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4361 if (out != operands[0])
4362 emit_move_insn (operands[0], out);
4363 DONE;
4364 }
4365 })
4366
4367 ;; Signed conversion to SImode.
4368
4369 (define_expand "fix_truncxfsi2"
4370 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4371 (fix:SI (match_operand:XF 1 "register_operand")))
4372 (clobber (reg:CC FLAGS_REG))])]
4373 "TARGET_80387"
4374 {
4375 if (TARGET_FISTTP)
4376 {
4377 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4378 DONE;
4379 }
4380 })
4381
4382 (define_expand "fix_trunc<mode>si2"
4383 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4384 (fix:SI (match_operand:MODEF 1 "register_operand")))
4385 (clobber (reg:CC FLAGS_REG))])]
4386 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4387 {
4388 if (TARGET_FISTTP
4389 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4390 {
4391 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4392 DONE;
4393 }
4394 if (SSE_FLOAT_MODE_P (<MODE>mode))
4395 {
4396 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4397 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4398 if (out != operands[0])
4399 emit_move_insn (operands[0], out);
4400 DONE;
4401 }
4402 })
4403
4404 ;; Signed conversion to HImode.
4405
4406 (define_expand "fix_trunc<mode>hi2"
4407 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4408 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4409 (clobber (reg:CC FLAGS_REG))])]
4410 "TARGET_80387
4411 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4412 {
4413 if (TARGET_FISTTP)
4414 {
4415 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4416 DONE;
4417 }
4418 })
4419
4420 ;; Unsigned conversion to SImode.
4421
4422 (define_expand "fixuns_trunc<mode>si2"
4423 [(parallel
4424 [(set (match_operand:SI 0 "register_operand")
4425 (unsigned_fix:SI
4426 (match_operand:MODEF 1 "nonimmediate_operand")))
4427 (use (match_dup 2))
4428 (clobber (match_scratch:<ssevecmode> 3))
4429 (clobber (match_scratch:<ssevecmode> 4))])]
4430 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4431 {
4432 enum machine_mode mode = <MODE>mode;
4433 enum machine_mode vecmode = <ssevecmode>mode;
4434 REAL_VALUE_TYPE TWO31r;
4435 rtx two31;
4436
4437 if (optimize_insn_for_size_p ())
4438 FAIL;
4439
4440 real_ldexp (&TWO31r, &dconst1, 31);
4441 two31 = const_double_from_real_value (TWO31r, mode);
4442 two31 = ix86_build_const_vector (vecmode, true, two31);
4443 operands[2] = force_reg (vecmode, two31);
4444 })
4445
4446 (define_insn_and_split "*fixuns_trunc<mode>_1"
4447 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4448 (unsigned_fix:SI
4449 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4450 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4451 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4452 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4453 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4454 && optimize_function_for_speed_p (cfun)"
4455 "#"
4456 "&& reload_completed"
4457 [(const_int 0)]
4458 {
4459 ix86_split_convert_uns_si_sse (operands);
4460 DONE;
4461 })
4462
4463 ;; Unsigned conversion to HImode.
4464 ;; Without these patterns, we'll try the unsigned SI conversion which
4465 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4466
4467 (define_expand "fixuns_trunc<mode>hi2"
4468 [(set (match_dup 2)
4469 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4470 (set (match_operand:HI 0 "nonimmediate_operand")
4471 (subreg:HI (match_dup 2) 0))]
4472 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4473 "operands[2] = gen_reg_rtx (SImode);")
4474
4475 ;; When SSE is available, it is always faster to use it!
4476 (define_insn "fix_trunc<mode>di_sse"
4477 [(set (match_operand:DI 0 "register_operand" "=r,r")
4478 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4479 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4480 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4481 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4482 [(set_attr "type" "sseicvt")
4483 (set_attr "prefix" "maybe_vex")
4484 (set_attr "prefix_rex" "1")
4485 (set_attr "mode" "<MODE>")
4486 (set_attr "athlon_decode" "double,vector")
4487 (set_attr "amdfam10_decode" "double,double")
4488 (set_attr "bdver1_decode" "double,double")])
4489
4490 (define_insn "fix_trunc<mode>si_sse"
4491 [(set (match_operand:SI 0 "register_operand" "=r,r")
4492 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4493 "SSE_FLOAT_MODE_P (<MODE>mode)
4494 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4495 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4496 [(set_attr "type" "sseicvt")
4497 (set_attr "prefix" "maybe_vex")
4498 (set_attr "mode" "<MODE>")
4499 (set_attr "athlon_decode" "double,vector")
4500 (set_attr "amdfam10_decode" "double,double")
4501 (set_attr "bdver1_decode" "double,double")])
4502
4503 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4504 (define_peephole2
4505 [(set (match_operand:MODEF 0 "register_operand")
4506 (match_operand:MODEF 1 "memory_operand"))
4507 (set (match_operand:SWI48x 2 "register_operand")
4508 (fix:SWI48x (match_dup 0)))]
4509 "TARGET_SHORTEN_X87_SSE
4510 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4511 && peep2_reg_dead_p (2, operands[0])"
4512 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4513
4514 ;; Avoid vector decoded forms of the instruction.
4515 (define_peephole2
4516 [(match_scratch:DF 2 "x")
4517 (set (match_operand:SWI48x 0 "register_operand")
4518 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4519 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4520 [(set (match_dup 2) (match_dup 1))
4521 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4522
4523 (define_peephole2
4524 [(match_scratch:SF 2 "x")
4525 (set (match_operand:SWI48x 0 "register_operand")
4526 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4527 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4528 [(set (match_dup 2) (match_dup 1))
4529 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4530
4531 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4532 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4533 (fix:SWI248x (match_operand 1 "register_operand")))]
4534 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4535 && TARGET_FISTTP
4536 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4537 && (TARGET_64BIT || <MODE>mode != DImode))
4538 && TARGET_SSE_MATH)
4539 && can_create_pseudo_p ()"
4540 "#"
4541 "&& 1"
4542 [(const_int 0)]
4543 {
4544 if (memory_operand (operands[0], VOIDmode))
4545 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4546 else
4547 {
4548 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4549 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4550 operands[1],
4551 operands[2]));
4552 }
4553 DONE;
4554 }
4555 [(set_attr "type" "fisttp")
4556 (set_attr "mode" "<MODE>")])
4557
4558 (define_insn "fix_trunc<mode>_i387_fisttp"
4559 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4560 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4561 (clobber (match_scratch:XF 2 "=&1f"))]
4562 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4563 && TARGET_FISTTP
4564 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4565 && (TARGET_64BIT || <MODE>mode != DImode))
4566 && TARGET_SSE_MATH)"
4567 "* return output_fix_trunc (insn, operands, true);"
4568 [(set_attr "type" "fisttp")
4569 (set_attr "mode" "<MODE>")])
4570
4571 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4572 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4573 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4574 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4575 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4576 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4577 && TARGET_FISTTP
4578 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4579 && (TARGET_64BIT || <MODE>mode != DImode))
4580 && TARGET_SSE_MATH)"
4581 "#"
4582 [(set_attr "type" "fisttp")
4583 (set_attr "mode" "<MODE>")])
4584
4585 (define_split
4586 [(set (match_operand:SWI248x 0 "register_operand")
4587 (fix:SWI248x (match_operand 1 "register_operand")))
4588 (clobber (match_operand:SWI248x 2 "memory_operand"))
4589 (clobber (match_scratch 3))]
4590 "reload_completed"
4591 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4592 (clobber (match_dup 3))])
4593 (set (match_dup 0) (match_dup 2))])
4594
4595 (define_split
4596 [(set (match_operand:SWI248x 0 "memory_operand")
4597 (fix:SWI248x (match_operand 1 "register_operand")))
4598 (clobber (match_operand:SWI248x 2 "memory_operand"))
4599 (clobber (match_scratch 3))]
4600 "reload_completed"
4601 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4602 (clobber (match_dup 3))])])
4603
4604 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4605 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4606 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4607 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4608 ;; function in i386.c.
4609 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4610 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4611 (fix:SWI248x (match_operand 1 "register_operand")))
4612 (clobber (reg:CC FLAGS_REG))]
4613 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4614 && !TARGET_FISTTP
4615 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && (TARGET_64BIT || <MODE>mode != DImode))
4617 && can_create_pseudo_p ()"
4618 "#"
4619 "&& 1"
4620 [(const_int 0)]
4621 {
4622 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4623
4624 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4625 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4626 if (memory_operand (operands[0], VOIDmode))
4627 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4628 operands[2], operands[3]));
4629 else
4630 {
4631 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4632 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4633 operands[2], operands[3],
4634 operands[4]));
4635 }
4636 DONE;
4637 }
4638 [(set_attr "type" "fistp")
4639 (set_attr "i387_cw" "trunc")
4640 (set_attr "mode" "<MODE>")])
4641
4642 (define_insn "fix_truncdi_i387"
4643 [(set (match_operand:DI 0 "memory_operand" "=m")
4644 (fix:DI (match_operand 1 "register_operand" "f")))
4645 (use (match_operand:HI 2 "memory_operand" "m"))
4646 (use (match_operand:HI 3 "memory_operand" "m"))
4647 (clobber (match_scratch:XF 4 "=&1f"))]
4648 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4649 && !TARGET_FISTTP
4650 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4651 "* return output_fix_trunc (insn, operands, false);"
4652 [(set_attr "type" "fistp")
4653 (set_attr "i387_cw" "trunc")
4654 (set_attr "mode" "DI")])
4655
4656 (define_insn "fix_truncdi_i387_with_temp"
4657 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4658 (fix:DI (match_operand 1 "register_operand" "f,f")))
4659 (use (match_operand:HI 2 "memory_operand" "m,m"))
4660 (use (match_operand:HI 3 "memory_operand" "m,m"))
4661 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4662 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4663 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4664 && !TARGET_FISTTP
4665 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4666 "#"
4667 [(set_attr "type" "fistp")
4668 (set_attr "i387_cw" "trunc")
4669 (set_attr "mode" "DI")])
4670
4671 (define_split
4672 [(set (match_operand:DI 0 "register_operand")
4673 (fix:DI (match_operand 1 "register_operand")))
4674 (use (match_operand:HI 2 "memory_operand"))
4675 (use (match_operand:HI 3 "memory_operand"))
4676 (clobber (match_operand:DI 4 "memory_operand"))
4677 (clobber (match_scratch 5))]
4678 "reload_completed"
4679 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4680 (use (match_dup 2))
4681 (use (match_dup 3))
4682 (clobber (match_dup 5))])
4683 (set (match_dup 0) (match_dup 4))])
4684
4685 (define_split
4686 [(set (match_operand:DI 0 "memory_operand")
4687 (fix:DI (match_operand 1 "register_operand")))
4688 (use (match_operand:HI 2 "memory_operand"))
4689 (use (match_operand:HI 3 "memory_operand"))
4690 (clobber (match_operand:DI 4 "memory_operand"))
4691 (clobber (match_scratch 5))]
4692 "reload_completed"
4693 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4694 (use (match_dup 2))
4695 (use (match_dup 3))
4696 (clobber (match_dup 5))])])
4697
4698 (define_insn "fix_trunc<mode>_i387"
4699 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4700 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4701 (use (match_operand:HI 2 "memory_operand" "m"))
4702 (use (match_operand:HI 3 "memory_operand" "m"))]
4703 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4704 && !TARGET_FISTTP
4705 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4706 "* return output_fix_trunc (insn, operands, false);"
4707 [(set_attr "type" "fistp")
4708 (set_attr "i387_cw" "trunc")
4709 (set_attr "mode" "<MODE>")])
4710
4711 (define_insn "fix_trunc<mode>_i387_with_temp"
4712 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4713 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4714 (use (match_operand:HI 2 "memory_operand" "m,m"))
4715 (use (match_operand:HI 3 "memory_operand" "m,m"))
4716 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4717 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4718 && !TARGET_FISTTP
4719 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4720 "#"
4721 [(set_attr "type" "fistp")
4722 (set_attr "i387_cw" "trunc")
4723 (set_attr "mode" "<MODE>")])
4724
4725 (define_split
4726 [(set (match_operand:SWI24 0 "register_operand")
4727 (fix:SWI24 (match_operand 1 "register_operand")))
4728 (use (match_operand:HI 2 "memory_operand"))
4729 (use (match_operand:HI 3 "memory_operand"))
4730 (clobber (match_operand:SWI24 4 "memory_operand"))]
4731 "reload_completed"
4732 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4733 (use (match_dup 2))
4734 (use (match_dup 3))])
4735 (set (match_dup 0) (match_dup 4))])
4736
4737 (define_split
4738 [(set (match_operand:SWI24 0 "memory_operand")
4739 (fix:SWI24 (match_operand 1 "register_operand")))
4740 (use (match_operand:HI 2 "memory_operand"))
4741 (use (match_operand:HI 3 "memory_operand"))
4742 (clobber (match_operand:SWI24 4 "memory_operand"))]
4743 "reload_completed"
4744 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4745 (use (match_dup 2))
4746 (use (match_dup 3))])])
4747
4748 (define_insn "x86_fnstcw_1"
4749 [(set (match_operand:HI 0 "memory_operand" "=m")
4750 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4751 "TARGET_80387"
4752 "fnstcw\t%0"
4753 [(set (attr "length")
4754 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4755 (set_attr "mode" "HI")
4756 (set_attr "unit" "i387")
4757 (set_attr "bdver1_decode" "vector")])
4758
4759 (define_insn "x86_fldcw_1"
4760 [(set (reg:HI FPCR_REG)
4761 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4762 "TARGET_80387"
4763 "fldcw\t%0"
4764 [(set (attr "length")
4765 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4766 (set_attr "mode" "HI")
4767 (set_attr "unit" "i387")
4768 (set_attr "athlon_decode" "vector")
4769 (set_attr "amdfam10_decode" "vector")
4770 (set_attr "bdver1_decode" "vector")])
4771 \f
4772 ;; Conversion between fixed point and floating point.
4773
4774 ;; Even though we only accept memory inputs, the backend _really_
4775 ;; wants to be able to do this between registers.
4776
4777 (define_expand "floathi<mode>2"
4778 [(set (match_operand:X87MODEF 0 "register_operand")
4779 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4780 "TARGET_80387
4781 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4782 || TARGET_MIX_SSE_I387)")
4783
4784 ;; Pre-reload splitter to add memory clobber to the pattern.
4785 (define_insn_and_split "*floathi<mode>2_1"
4786 [(set (match_operand:X87MODEF 0 "register_operand")
4787 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4788 "TARGET_80387
4789 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4790 || TARGET_MIX_SSE_I387)
4791 && can_create_pseudo_p ()"
4792 "#"
4793 "&& 1"
4794 [(parallel [(set (match_dup 0)
4795 (float:X87MODEF (match_dup 1)))
4796 (clobber (match_dup 2))])]
4797 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4798
4799 (define_insn "*floathi<mode>2_i387_with_temp"
4800 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4801 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4802 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4803 "TARGET_80387
4804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4805 || TARGET_MIX_SSE_I387)"
4806 "#"
4807 [(set_attr "type" "fmov,multi")
4808 (set_attr "mode" "<MODE>")
4809 (set_attr "unit" "*,i387")
4810 (set_attr "fp_int_src" "true")])
4811
4812 (define_insn "*floathi<mode>2_i387"
4813 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4814 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4815 "TARGET_80387
4816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4817 || TARGET_MIX_SSE_I387)"
4818 "fild%Z1\t%1"
4819 [(set_attr "type" "fmov")
4820 (set_attr "mode" "<MODE>")
4821 (set_attr "fp_int_src" "true")])
4822
4823 (define_split
4824 [(set (match_operand:X87MODEF 0 "register_operand")
4825 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4826 (clobber (match_operand:HI 2 "memory_operand"))]
4827 "TARGET_80387
4828 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4829 || TARGET_MIX_SSE_I387)
4830 && reload_completed"
4831 [(set (match_dup 2) (match_dup 1))
4832 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4833
4834 (define_split
4835 [(set (match_operand:X87MODEF 0 "register_operand")
4836 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4837 (clobber (match_operand:HI 2 "memory_operand"))]
4838 "TARGET_80387
4839 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4840 || TARGET_MIX_SSE_I387)
4841 && reload_completed"
4842 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4843
4844 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4845 [(set (match_operand:X87MODEF 0 "register_operand")
4846 (float:X87MODEF
4847 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4848 "TARGET_80387
4849 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4850 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4851 {
4852 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4853 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4854 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4855 {
4856 rtx reg = gen_reg_rtx (XFmode);
4857 rtx (*insn)(rtx, rtx);
4858
4859 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4860
4861 if (<X87MODEF:MODE>mode == SFmode)
4862 insn = gen_truncxfsf2;
4863 else if (<X87MODEF:MODE>mode == DFmode)
4864 insn = gen_truncxfdf2;
4865 else
4866 gcc_unreachable ();
4867
4868 emit_insn (insn (operands[0], reg));
4869 DONE;
4870 }
4871 })
4872
4873 ;; Pre-reload splitter to add memory clobber to the pattern.
4874 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4875 [(set (match_operand:X87MODEF 0 "register_operand")
4876 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4877 "((TARGET_80387
4878 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4879 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4880 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4881 || TARGET_MIX_SSE_I387))
4882 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4883 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4884 && ((<SWI48x:MODE>mode == SImode
4885 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4886 && optimize_function_for_speed_p (cfun)
4887 && flag_trapping_math)
4888 || !(TARGET_INTER_UNIT_CONVERSIONS
4889 || optimize_function_for_size_p (cfun)))))
4890 && can_create_pseudo_p ()"
4891 "#"
4892 "&& 1"
4893 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4894 (clobber (match_dup 2))])]
4895 {
4896 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4897
4898 /* Avoid store forwarding (partial memory) stall penalty
4899 by passing DImode value through XMM registers. */
4900 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4901 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4902 && optimize_function_for_speed_p (cfun))
4903 {
4904 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4905 operands[1],
4906 operands[2]));
4907 DONE;
4908 }
4909 })
4910
4911 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4912 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4913 (float:MODEF
4914 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4915 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4916 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4917 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4918 "#"
4919 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4920 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4921 (set_attr "unit" "*,i387,*,*,*")
4922 (set_attr "athlon_decode" "*,*,double,direct,double")
4923 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4924 (set_attr "bdver1_decode" "*,*,double,direct,double")
4925 (set_attr "fp_int_src" "true")])
4926
4927 (define_insn "*floatsi<mode>2_vector_mixed"
4928 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4929 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4930 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4931 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4932 "@
4933 fild%Z1\t%1
4934 #"
4935 [(set_attr "type" "fmov,sseicvt")
4936 (set_attr "mode" "<MODE>,<ssevecmode>")
4937 (set_attr "unit" "i387,*")
4938 (set_attr "athlon_decode" "*,direct")
4939 (set_attr "amdfam10_decode" "*,double")
4940 (set_attr "bdver1_decode" "*,direct")
4941 (set_attr "fp_int_src" "true")])
4942
4943 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4944 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4945 (float:MODEF
4946 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4947 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4948 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4949 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4950 "#"
4951 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4952 (set_attr "mode" "<MODEF:MODE>")
4953 (set_attr "unit" "*,i387,*,*")
4954 (set_attr "athlon_decode" "*,*,double,direct")
4955 (set_attr "amdfam10_decode" "*,*,vector,double")
4956 (set_attr "bdver1_decode" "*,*,double,direct")
4957 (set_attr "fp_int_src" "true")])
4958
4959 (define_split
4960 [(set (match_operand:MODEF 0 "register_operand")
4961 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4962 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4963 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4964 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4965 && TARGET_INTER_UNIT_CONVERSIONS
4966 && reload_completed
4967 && (SSE_REG_P (operands[0])
4968 || (GET_CODE (operands[0]) == SUBREG
4969 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4970 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4971
4972 (define_split
4973 [(set (match_operand:MODEF 0 "register_operand")
4974 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4975 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4976 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4977 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4978 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4979 && reload_completed
4980 && (SSE_REG_P (operands[0])
4981 || (GET_CODE (operands[0]) == SUBREG
4982 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4983 [(set (match_dup 2) (match_dup 1))
4984 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4985
4986 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4987 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4988 (float:MODEF
4989 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4990 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4991 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4992 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4993 "@
4994 fild%Z1\t%1
4995 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4996 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4997 [(set_attr "type" "fmov,sseicvt,sseicvt")
4998 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4999 (set_attr "mode" "<MODEF:MODE>")
5000 (set (attr "prefix_rex")
5001 (if_then_else
5002 (and (eq_attr "prefix" "maybe_vex")
5003 (match_test "<SWI48x:MODE>mode == DImode"))
5004 (const_string "1")
5005 (const_string "*")))
5006 (set_attr "unit" "i387,*,*")
5007 (set_attr "athlon_decode" "*,double,direct")
5008 (set_attr "amdfam10_decode" "*,vector,double")
5009 (set_attr "bdver1_decode" "*,double,direct")
5010 (set_attr "fp_int_src" "true")])
5011
5012 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
5013 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5014 (float:MODEF
5015 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
5016 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5017 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5018 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5019 "@
5020 fild%Z1\t%1
5021 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5022 [(set_attr "type" "fmov,sseicvt")
5023 (set_attr "prefix" "orig,maybe_vex")
5024 (set_attr "mode" "<MODEF:MODE>")
5025 (set (attr "prefix_rex")
5026 (if_then_else
5027 (and (eq_attr "prefix" "maybe_vex")
5028 (match_test "<SWI48x:MODE>mode == DImode"))
5029 (const_string "1")
5030 (const_string "*")))
5031 (set_attr "athlon_decode" "*,direct")
5032 (set_attr "amdfam10_decode" "*,double")
5033 (set_attr "bdver1_decode" "*,direct")
5034 (set_attr "fp_int_src" "true")])
5035
5036 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5037 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5038 (float:MODEF
5039 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5040 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5041 "TARGET_SSE2 && TARGET_SSE_MATH
5042 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5043 "#"
5044 [(set_attr "type" "sseicvt")
5045 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5046 (set_attr "athlon_decode" "double,direct,double")
5047 (set_attr "amdfam10_decode" "vector,double,double")
5048 (set_attr "bdver1_decode" "double,direct,double")
5049 (set_attr "fp_int_src" "true")])
5050
5051 (define_insn "*floatsi<mode>2_vector_sse"
5052 [(set (match_operand:MODEF 0 "register_operand" "=x")
5053 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5054 "TARGET_SSE2 && TARGET_SSE_MATH
5055 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5056 "#"
5057 [(set_attr "type" "sseicvt")
5058 (set_attr "mode" "<MODE>")
5059 (set_attr "athlon_decode" "direct")
5060 (set_attr "amdfam10_decode" "double")
5061 (set_attr "bdver1_decode" "direct")
5062 (set_attr "fp_int_src" "true")])
5063
5064 (define_split
5065 [(set (match_operand:MODEF 0 "register_operand")
5066 (float:MODEF (match_operand:SI 1 "register_operand")))
5067 (clobber (match_operand:SI 2 "memory_operand"))]
5068 "TARGET_SSE2 && TARGET_SSE_MATH
5069 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5070 && reload_completed
5071 && (SSE_REG_P (operands[0])
5072 || (GET_CODE (operands[0]) == SUBREG
5073 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5074 [(const_int 0)]
5075 {
5076 rtx op1 = operands[1];
5077
5078 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5079 <MODE>mode, 0);
5080 if (GET_CODE (op1) == SUBREG)
5081 op1 = SUBREG_REG (op1);
5082
5083 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5084 {
5085 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5086 emit_insn (gen_sse2_loadld (operands[4],
5087 CONST0_RTX (V4SImode), operands[1]));
5088 }
5089 /* We can ignore possible trapping value in the
5090 high part of SSE register for non-trapping math. */
5091 else if (SSE_REG_P (op1) && !flag_trapping_math)
5092 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5093 else
5094 {
5095 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5096 emit_move_insn (operands[2], operands[1]);
5097 emit_insn (gen_sse2_loadld (operands[4],
5098 CONST0_RTX (V4SImode), operands[2]));
5099 }
5100 if (<ssevecmode>mode == V4SFmode)
5101 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5102 else
5103 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5104 DONE;
5105 })
5106
5107 (define_split
5108 [(set (match_operand:MODEF 0 "register_operand")
5109 (float:MODEF (match_operand:SI 1 "memory_operand")))
5110 (clobber (match_operand:SI 2 "memory_operand"))]
5111 "TARGET_SSE2 && TARGET_SSE_MATH
5112 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5113 && reload_completed
5114 && (SSE_REG_P (operands[0])
5115 || (GET_CODE (operands[0]) == SUBREG
5116 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5117 [(const_int 0)]
5118 {
5119 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5120 <MODE>mode, 0);
5121 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5122
5123 emit_insn (gen_sse2_loadld (operands[4],
5124 CONST0_RTX (V4SImode), operands[1]));
5125 if (<ssevecmode>mode == V4SFmode)
5126 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5127 else
5128 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5129 DONE;
5130 })
5131
5132 (define_split
5133 [(set (match_operand:MODEF 0 "register_operand")
5134 (float:MODEF (match_operand:SI 1 "register_operand")))]
5135 "TARGET_SSE2 && TARGET_SSE_MATH
5136 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5137 && reload_completed
5138 && (SSE_REG_P (operands[0])
5139 || (GET_CODE (operands[0]) == SUBREG
5140 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5141 [(const_int 0)]
5142 {
5143 rtx op1 = operands[1];
5144
5145 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5146 <MODE>mode, 0);
5147 if (GET_CODE (op1) == SUBREG)
5148 op1 = SUBREG_REG (op1);
5149
5150 if (GENERAL_REG_P (op1))
5151 {
5152 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5153 if (TARGET_INTER_UNIT_MOVES)
5154 emit_insn (gen_sse2_loadld (operands[4],
5155 CONST0_RTX (V4SImode), operands[1]));
5156 else
5157 {
5158 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5159 operands[1]);
5160 emit_insn (gen_sse2_loadld (operands[4],
5161 CONST0_RTX (V4SImode), operands[5]));
5162 ix86_free_from_memory (GET_MODE (operands[1]));
5163 }
5164 }
5165 /* We can ignore possible trapping value in the
5166 high part of SSE register for non-trapping math. */
5167 else if (SSE_REG_P (op1) && !flag_trapping_math)
5168 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5169 else
5170 gcc_unreachable ();
5171 if (<ssevecmode>mode == V4SFmode)
5172 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5173 else
5174 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5175 DONE;
5176 })
5177
5178 (define_split
5179 [(set (match_operand:MODEF 0 "register_operand")
5180 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5181 "TARGET_SSE2 && TARGET_SSE_MATH
5182 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5183 && reload_completed
5184 && (SSE_REG_P (operands[0])
5185 || (GET_CODE (operands[0]) == SUBREG
5186 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5187 [(const_int 0)]
5188 {
5189 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5190 <MODE>mode, 0);
5191 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5192
5193 emit_insn (gen_sse2_loadld (operands[4],
5194 CONST0_RTX (V4SImode), operands[1]));
5195 if (<ssevecmode>mode == V4SFmode)
5196 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5197 else
5198 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5199 DONE;
5200 })
5201
5202 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5203 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5204 (float:MODEF
5205 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5206 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5207 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5208 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5209 "#"
5210 [(set_attr "type" "sseicvt")
5211 (set_attr "mode" "<MODEF:MODE>")
5212 (set_attr "athlon_decode" "double,direct")
5213 (set_attr "amdfam10_decode" "vector,double")
5214 (set_attr "bdver1_decode" "double,direct")
5215 (set_attr "fp_int_src" "true")])
5216
5217 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5218 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5219 (float:MODEF
5220 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5221 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5222 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5223 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5224 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5225 [(set_attr "type" "sseicvt")
5226 (set_attr "prefix" "maybe_vex")
5227 (set_attr "mode" "<MODEF:MODE>")
5228 (set (attr "prefix_rex")
5229 (if_then_else
5230 (and (eq_attr "prefix" "maybe_vex")
5231 (match_test "<SWI48x:MODE>mode == DImode"))
5232 (const_string "1")
5233 (const_string "*")))
5234 (set_attr "athlon_decode" "double,direct")
5235 (set_attr "amdfam10_decode" "vector,double")
5236 (set_attr "bdver1_decode" "double,direct")
5237 (set_attr "fp_int_src" "true")])
5238
5239 (define_split
5240 [(set (match_operand:MODEF 0 "register_operand")
5241 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5242 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5243 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5244 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5245 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5246 && reload_completed
5247 && (SSE_REG_P (operands[0])
5248 || (GET_CODE (operands[0]) == SUBREG
5249 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5250 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5251
5252 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5253 [(set (match_operand:MODEF 0 "register_operand" "=x")
5254 (float:MODEF
5255 (match_operand:SWI48x 1 "memory_operand" "m")))]
5256 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5257 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5258 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5259 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5260 [(set_attr "type" "sseicvt")
5261 (set_attr "prefix" "maybe_vex")
5262 (set_attr "mode" "<MODEF:MODE>")
5263 (set (attr "prefix_rex")
5264 (if_then_else
5265 (and (eq_attr "prefix" "maybe_vex")
5266 (match_test "<SWI48x:MODE>mode == DImode"))
5267 (const_string "1")
5268 (const_string "*")))
5269 (set_attr "athlon_decode" "direct")
5270 (set_attr "amdfam10_decode" "double")
5271 (set_attr "bdver1_decode" "direct")
5272 (set_attr "fp_int_src" "true")])
5273
5274 (define_split
5275 [(set (match_operand:MODEF 0 "register_operand")
5276 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5277 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5278 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5279 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5280 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5281 && reload_completed
5282 && (SSE_REG_P (operands[0])
5283 || (GET_CODE (operands[0]) == SUBREG
5284 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5285 [(set (match_dup 2) (match_dup 1))
5286 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5287
5288 (define_split
5289 [(set (match_operand:MODEF 0 "register_operand")
5290 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5291 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5292 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5293 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5294 && reload_completed
5295 && (SSE_REG_P (operands[0])
5296 || (GET_CODE (operands[0]) == SUBREG
5297 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5298 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5299
5300 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5301 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5302 (float:X87MODEF
5303 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5304 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5305 "TARGET_80387
5306 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5307 "@
5308 fild%Z1\t%1
5309 #"
5310 [(set_attr "type" "fmov,multi")
5311 (set_attr "mode" "<X87MODEF:MODE>")
5312 (set_attr "unit" "*,i387")
5313 (set_attr "fp_int_src" "true")])
5314
5315 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5316 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5317 (float:X87MODEF
5318 (match_operand:SWI48x 1 "memory_operand" "m")))]
5319 "TARGET_80387
5320 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5321 "fild%Z1\t%1"
5322 [(set_attr "type" "fmov")
5323 (set_attr "mode" "<X87MODEF:MODE>")
5324 (set_attr "fp_int_src" "true")])
5325
5326 (define_split
5327 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5328 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5329 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5330 "TARGET_80387
5331 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5332 && reload_completed"
5333 [(set (match_dup 2) (match_dup 1))
5334 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5335
5336 (define_split
5337 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5338 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5339 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5340 "TARGET_80387
5341 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5342 && reload_completed"
5343 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5344
5345 ;; Avoid store forwarding (partial memory) stall penalty
5346 ;; by passing DImode value through XMM registers. */
5347
5348 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5349 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5350 (float:X87MODEF
5351 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5352 (clobber (match_scratch:V4SI 3 "=X,x"))
5353 (clobber (match_scratch:V4SI 4 "=X,x"))
5354 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5355 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5356 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5357 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5358 "#"
5359 [(set_attr "type" "multi")
5360 (set_attr "mode" "<X87MODEF:MODE>")
5361 (set_attr "unit" "i387")
5362 (set_attr "fp_int_src" "true")])
5363
5364 (define_split
5365 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5366 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5367 (clobber (match_scratch:V4SI 3))
5368 (clobber (match_scratch:V4SI 4))
5369 (clobber (match_operand:DI 2 "memory_operand"))]
5370 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5371 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5372 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5373 && reload_completed"
5374 [(set (match_dup 2) (match_dup 3))
5375 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5376 {
5377 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5378 Assemble the 64-bit DImode value in an xmm register. */
5379 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5380 gen_rtx_SUBREG (SImode, operands[1], 0)));
5381 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5382 gen_rtx_SUBREG (SImode, operands[1], 4)));
5383 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5384 operands[4]));
5385
5386 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5387 })
5388
5389 (define_split
5390 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5391 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5392 (clobber (match_scratch:V4SI 3))
5393 (clobber (match_scratch:V4SI 4))
5394 (clobber (match_operand:DI 2 "memory_operand"))]
5395 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5396 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5397 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5398 && reload_completed"
5399 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5400
5401 ;; Avoid store forwarding (partial memory) stall penalty by extending
5402 ;; SImode value to DImode through XMM register instead of pushing two
5403 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5404 ;; targets benefit from this optimization. Also note that fild
5405 ;; loads from memory only.
5406
5407 (define_insn "*floatunssi<mode>2_1"
5408 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5409 (unsigned_float:X87MODEF
5410 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5411 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5412 (clobber (match_scratch:SI 3 "=X,x"))]
5413 "!TARGET_64BIT
5414 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5415 && TARGET_SSE"
5416 "#"
5417 [(set_attr "type" "multi")
5418 (set_attr "mode" "<MODE>")])
5419
5420 (define_split
5421 [(set (match_operand:X87MODEF 0 "register_operand")
5422 (unsigned_float:X87MODEF
5423 (match_operand:SI 1 "register_operand")))
5424 (clobber (match_operand:DI 2 "memory_operand"))
5425 (clobber (match_scratch:SI 3))]
5426 "!TARGET_64BIT
5427 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5428 && TARGET_SSE
5429 && reload_completed"
5430 [(set (match_dup 2) (match_dup 1))
5431 (set (match_dup 0)
5432 (float:X87MODEF (match_dup 2)))]
5433 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5434
5435 (define_split
5436 [(set (match_operand:X87MODEF 0 "register_operand")
5437 (unsigned_float:X87MODEF
5438 (match_operand:SI 1 "memory_operand")))
5439 (clobber (match_operand:DI 2 "memory_operand"))
5440 (clobber (match_scratch:SI 3))]
5441 "!TARGET_64BIT
5442 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5443 && TARGET_SSE
5444 && reload_completed"
5445 [(set (match_dup 2) (match_dup 3))
5446 (set (match_dup 0)
5447 (float:X87MODEF (match_dup 2)))]
5448 {
5449 emit_move_insn (operands[3], operands[1]);
5450 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5451 })
5452
5453 (define_expand "floatunssi<mode>2"
5454 [(parallel
5455 [(set (match_operand:X87MODEF 0 "register_operand")
5456 (unsigned_float:X87MODEF
5457 (match_operand:SI 1 "nonimmediate_operand")))
5458 (clobber (match_dup 2))
5459 (clobber (match_scratch:SI 3))])]
5460 "!TARGET_64BIT
5461 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5462 && TARGET_SSE)
5463 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5464 {
5465 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5466 {
5467 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5468 DONE;
5469 }
5470 else
5471 {
5472 enum ix86_stack_slot slot = (virtuals_instantiated
5473 ? SLOT_TEMP
5474 : SLOT_VIRTUAL);
5475 operands[2] = assign_386_stack_local (DImode, slot);
5476 }
5477 })
5478
5479 (define_expand "floatunsdisf2"
5480 [(use (match_operand:SF 0 "register_operand"))
5481 (use (match_operand:DI 1 "nonimmediate_operand"))]
5482 "TARGET_64BIT && TARGET_SSE_MATH"
5483 "x86_emit_floatuns (operands); DONE;")
5484
5485 (define_expand "floatunsdidf2"
5486 [(use (match_operand:DF 0 "register_operand"))
5487 (use (match_operand:DI 1 "nonimmediate_operand"))]
5488 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5489 && TARGET_SSE2 && TARGET_SSE_MATH"
5490 {
5491 if (TARGET_64BIT)
5492 x86_emit_floatuns (operands);
5493 else
5494 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5495 DONE;
5496 })
5497 \f
5498 ;; Load effective address instructions
5499
5500 (define_insn_and_split "*lea<mode>"
5501 [(set (match_operand:SWI48 0 "register_operand" "=r")
5502 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5503 ""
5504 {
5505 if (SImode_address_operand (operands[1], VOIDmode))
5506 {
5507 gcc_assert (TARGET_64BIT);
5508 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5509 }
5510 else
5511 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5512 }
5513 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5514 [(const_int 0)]
5515 {
5516 enum machine_mode mode = <MODE>mode;
5517 rtx pat;
5518
5519 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5520 change operands[] array behind our back. */
5521 pat = PATTERN (curr_insn);
5522
5523 operands[0] = SET_DEST (pat);
5524 operands[1] = SET_SRC (pat);
5525
5526 /* Emit all operations in SImode for zero-extended addresses. Recall
5527 that x86_64 inheretly zero-extends SImode operations to DImode. */
5528 if (SImode_address_operand (operands[1], VOIDmode))
5529 mode = SImode;
5530
5531 ix86_split_lea_for_addr (curr_insn, operands, mode);
5532 DONE;
5533 }
5534 [(set_attr "type" "lea")
5535 (set (attr "mode")
5536 (if_then_else
5537 (match_operand 1 "SImode_address_operand")
5538 (const_string "SI")
5539 (const_string "<MODE>")))])
5540 \f
5541 ;; Add instructions
5542
5543 (define_expand "add<mode>3"
5544 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5545 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5546 (match_operand:SDWIM 2 "<general_operand>")))]
5547 ""
5548 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5549
5550 (define_insn_and_split "*add<dwi>3_doubleword"
5551 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5552 (plus:<DWI>
5553 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5554 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5555 (clobber (reg:CC FLAGS_REG))]
5556 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5557 "#"
5558 "reload_completed"
5559 [(parallel [(set (reg:CC FLAGS_REG)
5560 (unspec:CC [(match_dup 1) (match_dup 2)]
5561 UNSPEC_ADD_CARRY))
5562 (set (match_dup 0)
5563 (plus:DWIH (match_dup 1) (match_dup 2)))])
5564 (parallel [(set (match_dup 3)
5565 (plus:DWIH
5566 (match_dup 4)
5567 (plus:DWIH
5568 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5569 (match_dup 5))))
5570 (clobber (reg:CC FLAGS_REG))])]
5571 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5572
5573 (define_insn "*add<mode>3_cc"
5574 [(set (reg:CC FLAGS_REG)
5575 (unspec:CC
5576 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5577 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5578 UNSPEC_ADD_CARRY))
5579 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5580 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5581 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5582 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5583 [(set_attr "type" "alu")
5584 (set_attr "mode" "<MODE>")])
5585
5586 (define_insn "addqi3_cc"
5587 [(set (reg:CC FLAGS_REG)
5588 (unspec:CC
5589 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5590 (match_operand:QI 2 "general_operand" "qn,qm")]
5591 UNSPEC_ADD_CARRY))
5592 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5593 (plus:QI (match_dup 1) (match_dup 2)))]
5594 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5595 "add{b}\t{%2, %0|%0, %2}"
5596 [(set_attr "type" "alu")
5597 (set_attr "mode" "QI")])
5598
5599 (define_insn "*add<mode>_1"
5600 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5601 (plus:SWI48
5602 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5603 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5604 (clobber (reg:CC FLAGS_REG))]
5605 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5606 {
5607 switch (get_attr_type (insn))
5608 {
5609 case TYPE_LEA:
5610 return "#";
5611
5612 case TYPE_INCDEC:
5613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5614 if (operands[2] == const1_rtx)
5615 return "inc{<imodesuffix>}\t%0";
5616 else
5617 {
5618 gcc_assert (operands[2] == constm1_rtx);
5619 return "dec{<imodesuffix>}\t%0";
5620 }
5621
5622 default:
5623 /* For most processors, ADD is faster than LEA. This alternative
5624 was added to use ADD as much as possible. */
5625 if (which_alternative == 2)
5626 {
5627 rtx tmp;
5628 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5629 }
5630
5631 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5632 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5633 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5634
5635 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5636 }
5637 }
5638 [(set (attr "type")
5639 (cond [(eq_attr "alternative" "3")
5640 (const_string "lea")
5641 (match_operand:SWI48 2 "incdec_operand")
5642 (const_string "incdec")
5643 ]
5644 (const_string "alu")))
5645 (set (attr "length_immediate")
5646 (if_then_else
5647 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5648 (const_string "1")
5649 (const_string "*")))
5650 (set_attr "mode" "<MODE>")])
5651
5652 ;; It may seem that nonimmediate operand is proper one for operand 1.
5653 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5654 ;; we take care in ix86_binary_operator_ok to not allow two memory
5655 ;; operands so proper swapping will be done in reload. This allow
5656 ;; patterns constructed from addsi_1 to match.
5657
5658 (define_insn "addsi_1_zext"
5659 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5660 (zero_extend:DI
5661 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5662 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5663 (clobber (reg:CC FLAGS_REG))]
5664 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5665 {
5666 switch (get_attr_type (insn))
5667 {
5668 case TYPE_LEA:
5669 return "#";
5670
5671 case TYPE_INCDEC:
5672 if (operands[2] == const1_rtx)
5673 return "inc{l}\t%k0";
5674 else
5675 {
5676 gcc_assert (operands[2] == constm1_rtx);
5677 return "dec{l}\t%k0";
5678 }
5679
5680 default:
5681 /* For most processors, ADD is faster than LEA. This alternative
5682 was added to use ADD as much as possible. */
5683 if (which_alternative == 1)
5684 {
5685 rtx tmp;
5686 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5687 }
5688
5689 if (x86_maybe_negate_const_int (&operands[2], SImode))
5690 return "sub{l}\t{%2, %k0|%k0, %2}";
5691
5692 return "add{l}\t{%2, %k0|%k0, %2}";
5693 }
5694 }
5695 [(set (attr "type")
5696 (cond [(eq_attr "alternative" "2")
5697 (const_string "lea")
5698 (match_operand:SI 2 "incdec_operand")
5699 (const_string "incdec")
5700 ]
5701 (const_string "alu")))
5702 (set (attr "length_immediate")
5703 (if_then_else
5704 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5705 (const_string "1")
5706 (const_string "*")))
5707 (set_attr "mode" "SI")])
5708
5709 (define_insn "*addhi_1"
5710 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5711 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5712 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5713 (clobber (reg:CC FLAGS_REG))]
5714 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5715 {
5716 switch (get_attr_type (insn))
5717 {
5718 case TYPE_LEA:
5719 return "#";
5720
5721 case TYPE_INCDEC:
5722 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5723 if (operands[2] == const1_rtx)
5724 return "inc{w}\t%0";
5725 else
5726 {
5727 gcc_assert (operands[2] == constm1_rtx);
5728 return "dec{w}\t%0";
5729 }
5730
5731 default:
5732 /* For most processors, ADD is faster than LEA. This alternative
5733 was added to use ADD as much as possible. */
5734 if (which_alternative == 2)
5735 {
5736 rtx tmp;
5737 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5738 }
5739
5740 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5741 if (x86_maybe_negate_const_int (&operands[2], HImode))
5742 return "sub{w}\t{%2, %0|%0, %2}";
5743
5744 return "add{w}\t{%2, %0|%0, %2}";
5745 }
5746 }
5747 [(set (attr "type")
5748 (cond [(eq_attr "alternative" "3")
5749 (const_string "lea")
5750 (match_operand:HI 2 "incdec_operand")
5751 (const_string "incdec")
5752 ]
5753 (const_string "alu")))
5754 (set (attr "length_immediate")
5755 (if_then_else
5756 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5757 (const_string "1")
5758 (const_string "*")))
5759 (set_attr "mode" "HI,HI,HI,SI")])
5760
5761 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5762 (define_insn "*addqi_1"
5763 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5764 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5765 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5766 (clobber (reg:CC FLAGS_REG))]
5767 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5768 {
5769 bool widen = (which_alternative == 3 || which_alternative == 4);
5770
5771 switch (get_attr_type (insn))
5772 {
5773 case TYPE_LEA:
5774 return "#";
5775
5776 case TYPE_INCDEC:
5777 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5778 if (operands[2] == const1_rtx)
5779 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5780 else
5781 {
5782 gcc_assert (operands[2] == constm1_rtx);
5783 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5784 }
5785
5786 default:
5787 /* For most processors, ADD is faster than LEA. These alternatives
5788 were added to use ADD as much as possible. */
5789 if (which_alternative == 2 || which_alternative == 4)
5790 {
5791 rtx tmp;
5792 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5793 }
5794
5795 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5796 if (x86_maybe_negate_const_int (&operands[2], QImode))
5797 {
5798 if (widen)
5799 return "sub{l}\t{%2, %k0|%k0, %2}";
5800 else
5801 return "sub{b}\t{%2, %0|%0, %2}";
5802 }
5803 if (widen)
5804 return "add{l}\t{%k2, %k0|%k0, %k2}";
5805 else
5806 return "add{b}\t{%2, %0|%0, %2}";
5807 }
5808 }
5809 [(set (attr "type")
5810 (cond [(eq_attr "alternative" "5")
5811 (const_string "lea")
5812 (match_operand:QI 2 "incdec_operand")
5813 (const_string "incdec")
5814 ]
5815 (const_string "alu")))
5816 (set (attr "length_immediate")
5817 (if_then_else
5818 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5819 (const_string "1")
5820 (const_string "*")))
5821 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5822
5823 (define_insn "*addqi_1_slp"
5824 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5825 (plus:QI (match_dup 0)
5826 (match_operand:QI 1 "general_operand" "qn,qm")))
5827 (clobber (reg:CC FLAGS_REG))]
5828 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5829 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5830 {
5831 switch (get_attr_type (insn))
5832 {
5833 case TYPE_INCDEC:
5834 if (operands[1] == const1_rtx)
5835 return "inc{b}\t%0";
5836 else
5837 {
5838 gcc_assert (operands[1] == constm1_rtx);
5839 return "dec{b}\t%0";
5840 }
5841
5842 default:
5843 if (x86_maybe_negate_const_int (&operands[1], QImode))
5844 return "sub{b}\t{%1, %0|%0, %1}";
5845
5846 return "add{b}\t{%1, %0|%0, %1}";
5847 }
5848 }
5849 [(set (attr "type")
5850 (if_then_else (match_operand:QI 1 "incdec_operand")
5851 (const_string "incdec")
5852 (const_string "alu1")))
5853 (set (attr "memory")
5854 (if_then_else (match_operand 1 "memory_operand")
5855 (const_string "load")
5856 (const_string "none")))
5857 (set_attr "mode" "QI")])
5858
5859 ;; Split non destructive adds if we cannot use lea.
5860 (define_split
5861 [(set (match_operand:SWI48 0 "register_operand")
5862 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5863 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5864 (clobber (reg:CC FLAGS_REG))]
5865 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5866 [(set (match_dup 0) (match_dup 1))
5867 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5868 (clobber (reg:CC FLAGS_REG))])])
5869
5870 ;; Convert add to the lea pattern to avoid flags dependency.
5871 (define_split
5872 [(set (match_operand:SWI 0 "register_operand")
5873 (plus:SWI (match_operand:SWI 1 "register_operand")
5874 (match_operand:SWI 2 "<nonmemory_operand>")))
5875 (clobber (reg:CC FLAGS_REG))]
5876 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5877 [(const_int 0)]
5878 {
5879 enum machine_mode mode = <MODE>mode;
5880 rtx pat;
5881
5882 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5883 {
5884 mode = SImode;
5885 operands[0] = gen_lowpart (mode, operands[0]);
5886 operands[1] = gen_lowpart (mode, operands[1]);
5887 operands[2] = gen_lowpart (mode, operands[2]);
5888 }
5889
5890 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5891
5892 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5893 DONE;
5894 })
5895
5896 ;; Split non destructive adds if we cannot use lea.
5897 (define_split
5898 [(set (match_operand:DI 0 "register_operand")
5899 (zero_extend:DI
5900 (plus:SI (match_operand:SI 1 "register_operand")
5901 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5902 (clobber (reg:CC FLAGS_REG))]
5903 "TARGET_64BIT
5904 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5905 [(set (match_dup 3) (match_dup 1))
5906 (parallel [(set (match_dup 0)
5907 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5908 (clobber (reg:CC FLAGS_REG))])]
5909 "operands[3] = gen_lowpart (SImode, operands[0]);")
5910
5911 ;; Convert add to the lea pattern to avoid flags dependency.
5912 (define_split
5913 [(set (match_operand:DI 0 "register_operand")
5914 (zero_extend:DI
5915 (plus:SI (match_operand:SI 1 "register_operand")
5916 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5917 (clobber (reg:CC FLAGS_REG))]
5918 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5919 [(set (match_dup 0)
5920 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5921
5922 (define_insn "*add<mode>_2"
5923 [(set (reg FLAGS_REG)
5924 (compare
5925 (plus:SWI
5926 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5927 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5928 (const_int 0)))
5929 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5930 (plus:SWI (match_dup 1) (match_dup 2)))]
5931 "ix86_match_ccmode (insn, CCGOCmode)
5932 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5933 {
5934 switch (get_attr_type (insn))
5935 {
5936 case TYPE_INCDEC:
5937 if (operands[2] == const1_rtx)
5938 return "inc{<imodesuffix>}\t%0";
5939 else
5940 {
5941 gcc_assert (operands[2] == constm1_rtx);
5942 return "dec{<imodesuffix>}\t%0";
5943 }
5944
5945 default:
5946 if (which_alternative == 2)
5947 {
5948 rtx tmp;
5949 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5950 }
5951
5952 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5953 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5954 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5955
5956 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5957 }
5958 }
5959 [(set (attr "type")
5960 (if_then_else (match_operand:SWI 2 "incdec_operand")
5961 (const_string "incdec")
5962 (const_string "alu")))
5963 (set (attr "length_immediate")
5964 (if_then_else
5965 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5966 (const_string "1")
5967 (const_string "*")))
5968 (set_attr "mode" "<MODE>")])
5969
5970 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5971 (define_insn "*addsi_2_zext"
5972 [(set (reg FLAGS_REG)
5973 (compare
5974 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5975 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5976 (const_int 0)))
5977 (set (match_operand:DI 0 "register_operand" "=r,r")
5978 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5979 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5980 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5981 {
5982 switch (get_attr_type (insn))
5983 {
5984 case TYPE_INCDEC:
5985 if (operands[2] == const1_rtx)
5986 return "inc{l}\t%k0";
5987 else
5988 {
5989 gcc_assert (operands[2] == constm1_rtx);
5990 return "dec{l}\t%k0";
5991 }
5992
5993 default:
5994 if (which_alternative == 1)
5995 {
5996 rtx tmp;
5997 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5998 }
5999
6000 if (x86_maybe_negate_const_int (&operands[2], SImode))
6001 return "sub{l}\t{%2, %k0|%k0, %2}";
6002
6003 return "add{l}\t{%2, %k0|%k0, %2}";
6004 }
6005 }
6006 [(set (attr "type")
6007 (if_then_else (match_operand:SI 2 "incdec_operand")
6008 (const_string "incdec")
6009 (const_string "alu")))
6010 (set (attr "length_immediate")
6011 (if_then_else
6012 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6013 (const_string "1")
6014 (const_string "*")))
6015 (set_attr "mode" "SI")])
6016
6017 (define_insn "*add<mode>_3"
6018 [(set (reg FLAGS_REG)
6019 (compare
6020 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6021 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6022 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6023 "ix86_match_ccmode (insn, CCZmode)
6024 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6025 {
6026 switch (get_attr_type (insn))
6027 {
6028 case TYPE_INCDEC:
6029 if (operands[2] == const1_rtx)
6030 return "inc{<imodesuffix>}\t%0";
6031 else
6032 {
6033 gcc_assert (operands[2] == constm1_rtx);
6034 return "dec{<imodesuffix>}\t%0";
6035 }
6036
6037 default:
6038 if (which_alternative == 1)
6039 {
6040 rtx tmp;
6041 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6042 }
6043
6044 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6045 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6046 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6047
6048 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6049 }
6050 }
6051 [(set (attr "type")
6052 (if_then_else (match_operand:SWI 2 "incdec_operand")
6053 (const_string "incdec")
6054 (const_string "alu")))
6055 (set (attr "length_immediate")
6056 (if_then_else
6057 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6058 (const_string "1")
6059 (const_string "*")))
6060 (set_attr "mode" "<MODE>")])
6061
6062 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6063 (define_insn "*addsi_3_zext"
6064 [(set (reg FLAGS_REG)
6065 (compare
6066 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6067 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6068 (set (match_operand:DI 0 "register_operand" "=r,r")
6069 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6070 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6071 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6072 {
6073 switch (get_attr_type (insn))
6074 {
6075 case TYPE_INCDEC:
6076 if (operands[2] == const1_rtx)
6077 return "inc{l}\t%k0";
6078 else
6079 {
6080 gcc_assert (operands[2] == constm1_rtx);
6081 return "dec{l}\t%k0";
6082 }
6083
6084 default:
6085 if (which_alternative == 1)
6086 {
6087 rtx tmp;
6088 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6089 }
6090
6091 if (x86_maybe_negate_const_int (&operands[2], SImode))
6092 return "sub{l}\t{%2, %k0|%k0, %2}";
6093
6094 return "add{l}\t{%2, %k0|%k0, %2}";
6095 }
6096 }
6097 [(set (attr "type")
6098 (if_then_else (match_operand:SI 2 "incdec_operand")
6099 (const_string "incdec")
6100 (const_string "alu")))
6101 (set (attr "length_immediate")
6102 (if_then_else
6103 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6104 (const_string "1")
6105 (const_string "*")))
6106 (set_attr "mode" "SI")])
6107
6108 ; For comparisons against 1, -1 and 128, we may generate better code
6109 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6110 ; is matched then. We can't accept general immediate, because for
6111 ; case of overflows, the result is messed up.
6112 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6113 ; only for comparisons not depending on it.
6114
6115 (define_insn "*adddi_4"
6116 [(set (reg FLAGS_REG)
6117 (compare
6118 (match_operand:DI 1 "nonimmediate_operand" "0")
6119 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6120 (clobber (match_scratch:DI 0 "=rm"))]
6121 "TARGET_64BIT
6122 && ix86_match_ccmode (insn, CCGCmode)"
6123 {
6124 switch (get_attr_type (insn))
6125 {
6126 case TYPE_INCDEC:
6127 if (operands[2] == constm1_rtx)
6128 return "inc{q}\t%0";
6129 else
6130 {
6131 gcc_assert (operands[2] == const1_rtx);
6132 return "dec{q}\t%0";
6133 }
6134
6135 default:
6136 if (x86_maybe_negate_const_int (&operands[2], DImode))
6137 return "add{q}\t{%2, %0|%0, %2}";
6138
6139 return "sub{q}\t{%2, %0|%0, %2}";
6140 }
6141 }
6142 [(set (attr "type")
6143 (if_then_else (match_operand:DI 2 "incdec_operand")
6144 (const_string "incdec")
6145 (const_string "alu")))
6146 (set (attr "length_immediate")
6147 (if_then_else
6148 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6149 (const_string "1")
6150 (const_string "*")))
6151 (set_attr "mode" "DI")])
6152
6153 ; For comparisons against 1, -1 and 128, we may generate better code
6154 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6155 ; is matched then. We can't accept general immediate, because for
6156 ; case of overflows, the result is messed up.
6157 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6158 ; only for comparisons not depending on it.
6159
6160 (define_insn "*add<mode>_4"
6161 [(set (reg FLAGS_REG)
6162 (compare
6163 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6164 (match_operand:SWI124 2 "const_int_operand" "n")))
6165 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6166 "ix86_match_ccmode (insn, CCGCmode)"
6167 {
6168 switch (get_attr_type (insn))
6169 {
6170 case TYPE_INCDEC:
6171 if (operands[2] == constm1_rtx)
6172 return "inc{<imodesuffix>}\t%0";
6173 else
6174 {
6175 gcc_assert (operands[2] == const1_rtx);
6176 return "dec{<imodesuffix>}\t%0";
6177 }
6178
6179 default:
6180 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6181 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6182
6183 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6184 }
6185 }
6186 [(set (attr "type")
6187 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6188 (const_string "incdec")
6189 (const_string "alu")))
6190 (set (attr "length_immediate")
6191 (if_then_else
6192 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6193 (const_string "1")
6194 (const_string "*")))
6195 (set_attr "mode" "<MODE>")])
6196
6197 (define_insn "*add<mode>_5"
6198 [(set (reg FLAGS_REG)
6199 (compare
6200 (plus:SWI
6201 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6202 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6203 (const_int 0)))
6204 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6205 "ix86_match_ccmode (insn, CCGOCmode)
6206 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6207 {
6208 switch (get_attr_type (insn))
6209 {
6210 case TYPE_INCDEC:
6211 if (operands[2] == const1_rtx)
6212 return "inc{<imodesuffix>}\t%0";
6213 else
6214 {
6215 gcc_assert (operands[2] == constm1_rtx);
6216 return "dec{<imodesuffix>}\t%0";
6217 }
6218
6219 default:
6220 if (which_alternative == 1)
6221 {
6222 rtx tmp;
6223 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6224 }
6225
6226 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6227 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6228 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6229
6230 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6231 }
6232 }
6233 [(set (attr "type")
6234 (if_then_else (match_operand:SWI 2 "incdec_operand")
6235 (const_string "incdec")
6236 (const_string "alu")))
6237 (set (attr "length_immediate")
6238 (if_then_else
6239 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6240 (const_string "1")
6241 (const_string "*")))
6242 (set_attr "mode" "<MODE>")])
6243
6244 (define_insn "*addqi_ext_1_rex64"
6245 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6246 (const_int 8)
6247 (const_int 8))
6248 (plus:SI
6249 (zero_extract:SI
6250 (match_operand 1 "ext_register_operand" "0")
6251 (const_int 8)
6252 (const_int 8))
6253 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6254 (clobber (reg:CC FLAGS_REG))]
6255 "TARGET_64BIT"
6256 {
6257 switch (get_attr_type (insn))
6258 {
6259 case TYPE_INCDEC:
6260 if (operands[2] == const1_rtx)
6261 return "inc{b}\t%h0";
6262 else
6263 {
6264 gcc_assert (operands[2] == constm1_rtx);
6265 return "dec{b}\t%h0";
6266 }
6267
6268 default:
6269 return "add{b}\t{%2, %h0|%h0, %2}";
6270 }
6271 }
6272 [(set (attr "type")
6273 (if_then_else (match_operand:QI 2 "incdec_operand")
6274 (const_string "incdec")
6275 (const_string "alu")))
6276 (set_attr "modrm" "1")
6277 (set_attr "mode" "QI")])
6278
6279 (define_insn "addqi_ext_1"
6280 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6281 (const_int 8)
6282 (const_int 8))
6283 (plus:SI
6284 (zero_extract:SI
6285 (match_operand 1 "ext_register_operand" "0")
6286 (const_int 8)
6287 (const_int 8))
6288 (match_operand:QI 2 "general_operand" "Qmn")))
6289 (clobber (reg:CC FLAGS_REG))]
6290 "!TARGET_64BIT"
6291 {
6292 switch (get_attr_type (insn))
6293 {
6294 case TYPE_INCDEC:
6295 if (operands[2] == const1_rtx)
6296 return "inc{b}\t%h0";
6297 else
6298 {
6299 gcc_assert (operands[2] == constm1_rtx);
6300 return "dec{b}\t%h0";
6301 }
6302
6303 default:
6304 return "add{b}\t{%2, %h0|%h0, %2}";
6305 }
6306 }
6307 [(set (attr "type")
6308 (if_then_else (match_operand:QI 2 "incdec_operand")
6309 (const_string "incdec")
6310 (const_string "alu")))
6311 (set_attr "modrm" "1")
6312 (set_attr "mode" "QI")])
6313
6314 (define_insn "*addqi_ext_2"
6315 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6316 (const_int 8)
6317 (const_int 8))
6318 (plus:SI
6319 (zero_extract:SI
6320 (match_operand 1 "ext_register_operand" "%0")
6321 (const_int 8)
6322 (const_int 8))
6323 (zero_extract:SI
6324 (match_operand 2 "ext_register_operand" "Q")
6325 (const_int 8)
6326 (const_int 8))))
6327 (clobber (reg:CC FLAGS_REG))]
6328 ""
6329 "add{b}\t{%h2, %h0|%h0, %h2}"
6330 [(set_attr "type" "alu")
6331 (set_attr "mode" "QI")])
6332
6333 ;; The lea patterns for modes less than 32 bits need to be matched by
6334 ;; several insns converted to real lea by splitters.
6335
6336 (define_insn_and_split "*lea_general_1"
6337 [(set (match_operand 0 "register_operand" "=r")
6338 (plus (plus (match_operand 1 "index_register_operand" "l")
6339 (match_operand 2 "register_operand" "r"))
6340 (match_operand 3 "immediate_operand" "i")))]
6341 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6342 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6343 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6344 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6345 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6346 || GET_MODE (operands[3]) == VOIDmode)"
6347 "#"
6348 "&& reload_completed"
6349 [(const_int 0)]
6350 {
6351 enum machine_mode mode = SImode;
6352 rtx pat;
6353
6354 operands[0] = gen_lowpart (mode, operands[0]);
6355 operands[1] = gen_lowpart (mode, operands[1]);
6356 operands[2] = gen_lowpart (mode, operands[2]);
6357 operands[3] = gen_lowpart (mode, operands[3]);
6358
6359 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6360 operands[3]);
6361
6362 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6363 DONE;
6364 }
6365 [(set_attr "type" "lea")
6366 (set_attr "mode" "SI")])
6367
6368 (define_insn_and_split "*lea_general_2"
6369 [(set (match_operand 0 "register_operand" "=r")
6370 (plus (mult (match_operand 1 "index_register_operand" "l")
6371 (match_operand 2 "const248_operand" "n"))
6372 (match_operand 3 "nonmemory_operand" "ri")))]
6373 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6374 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6375 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6376 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6377 || GET_MODE (operands[3]) == VOIDmode)"
6378 "#"
6379 "&& reload_completed"
6380 [(const_int 0)]
6381 {
6382 enum machine_mode mode = SImode;
6383 rtx pat;
6384
6385 operands[0] = gen_lowpart (mode, operands[0]);
6386 operands[1] = gen_lowpart (mode, operands[1]);
6387 operands[3] = gen_lowpart (mode, operands[3]);
6388
6389 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6390 operands[3]);
6391
6392 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6393 DONE;
6394 }
6395 [(set_attr "type" "lea")
6396 (set_attr "mode" "SI")])
6397
6398 (define_insn_and_split "*lea_general_3"
6399 [(set (match_operand 0 "register_operand" "=r")
6400 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6401 (match_operand 2 "const248_operand" "n"))
6402 (match_operand 3 "register_operand" "r"))
6403 (match_operand 4 "immediate_operand" "i")))]
6404 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6405 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6406 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6407 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6408 "#"
6409 "&& reload_completed"
6410 [(const_int 0)]
6411 {
6412 enum machine_mode mode = SImode;
6413 rtx pat;
6414
6415 operands[0] = gen_lowpart (mode, operands[0]);
6416 operands[1] = gen_lowpart (mode, operands[1]);
6417 operands[3] = gen_lowpart (mode, operands[3]);
6418 operands[4] = gen_lowpart (mode, operands[4]);
6419
6420 pat = gen_rtx_PLUS (mode,
6421 gen_rtx_PLUS (mode,
6422 gen_rtx_MULT (mode, operands[1],
6423 operands[2]),
6424 operands[3]),
6425 operands[4]);
6426
6427 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6428 DONE;
6429 }
6430 [(set_attr "type" "lea")
6431 (set_attr "mode" "SI")])
6432
6433 (define_insn_and_split "*lea_general_4"
6434 [(set (match_operand 0 "register_operand" "=r")
6435 (any_or (ashift
6436 (match_operand 1 "index_register_operand" "l")
6437 (match_operand 2 "const_int_operand" "n"))
6438 (match_operand 3 "const_int_operand" "n")))]
6439 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6440 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6441 || GET_MODE (operands[0]) == SImode
6442 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6443 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6444 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6445 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6446 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6447 "#"
6448 "&& reload_completed"
6449 [(const_int 0)]
6450 {
6451 enum machine_mode mode = GET_MODE (operands[0]);
6452 rtx pat;
6453
6454 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6455 {
6456 mode = SImode;
6457 operands[0] = gen_lowpart (mode, operands[0]);
6458 operands[1] = gen_lowpart (mode, operands[1]);
6459 }
6460
6461 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6462
6463 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6464 INTVAL (operands[3]));
6465
6466 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6467 DONE;
6468 }
6469 [(set_attr "type" "lea")
6470 (set (attr "mode")
6471 (if_then_else (match_operand:DI 0)
6472 (const_string "DI")
6473 (const_string "SI")))])
6474 \f
6475 ;; Subtract instructions
6476
6477 (define_expand "sub<mode>3"
6478 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6479 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6480 (match_operand:SDWIM 2 "<general_operand>")))]
6481 ""
6482 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6483
6484 (define_insn_and_split "*sub<dwi>3_doubleword"
6485 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6486 (minus:<DWI>
6487 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6488 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6489 (clobber (reg:CC FLAGS_REG))]
6490 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6491 "#"
6492 "reload_completed"
6493 [(parallel [(set (reg:CC FLAGS_REG)
6494 (compare:CC (match_dup 1) (match_dup 2)))
6495 (set (match_dup 0)
6496 (minus:DWIH (match_dup 1) (match_dup 2)))])
6497 (parallel [(set (match_dup 3)
6498 (minus:DWIH
6499 (match_dup 4)
6500 (plus:DWIH
6501 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6502 (match_dup 5))))
6503 (clobber (reg:CC FLAGS_REG))])]
6504 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6505
6506 (define_insn "*sub<mode>_1"
6507 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6508 (minus:SWI
6509 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6510 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6511 (clobber (reg:CC FLAGS_REG))]
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_1_zext"
6518 [(set (match_operand:DI 0 "register_operand" "=r")
6519 (zero_extend:DI
6520 (minus:SI (match_operand:SI 1 "register_operand" "0")
6521 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6522 (clobber (reg:CC FLAGS_REG))]
6523 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6524 "sub{l}\t{%2, %k0|%k0, %2}"
6525 [(set_attr "type" "alu")
6526 (set_attr "mode" "SI")])
6527
6528 (define_insn "*subqi_1_slp"
6529 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6530 (minus:QI (match_dup 0)
6531 (match_operand:QI 1 "general_operand" "qn,qm")))
6532 (clobber (reg:CC FLAGS_REG))]
6533 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6534 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6535 "sub{b}\t{%1, %0|%0, %1}"
6536 [(set_attr "type" "alu1")
6537 (set_attr "mode" "QI")])
6538
6539 (define_insn "*sub<mode>_2"
6540 [(set (reg FLAGS_REG)
6541 (compare
6542 (minus:SWI
6543 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6544 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6545 (const_int 0)))
6546 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6547 (minus:SWI (match_dup 1) (match_dup 2)))]
6548 "ix86_match_ccmode (insn, CCGOCmode)
6549 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6550 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "mode" "<MODE>")])
6553
6554 (define_insn "*subsi_2_zext"
6555 [(set (reg FLAGS_REG)
6556 (compare
6557 (minus:SI (match_operand:SI 1 "register_operand" "0")
6558 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6559 (const_int 0)))
6560 (set (match_operand:DI 0 "register_operand" "=r")
6561 (zero_extend:DI
6562 (minus:SI (match_dup 1)
6563 (match_dup 2))))]
6564 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6565 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6566 "sub{l}\t{%2, %k0|%k0, %2}"
6567 [(set_attr "type" "alu")
6568 (set_attr "mode" "SI")])
6569
6570 (define_insn "*sub<mode>_3"
6571 [(set (reg FLAGS_REG)
6572 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6573 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6574 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6575 (minus:SWI (match_dup 1) (match_dup 2)))]
6576 "ix86_match_ccmode (insn, CCmode)
6577 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6578 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6579 [(set_attr "type" "alu")
6580 (set_attr "mode" "<MODE>")])
6581
6582 (define_insn "*subsi_3_zext"
6583 [(set (reg FLAGS_REG)
6584 (compare (match_operand:SI 1 "register_operand" "0")
6585 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6586 (set (match_operand:DI 0 "register_operand" "=r")
6587 (zero_extend:DI
6588 (minus:SI (match_dup 1)
6589 (match_dup 2))))]
6590 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6591 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6592 "sub{l}\t{%2, %1|%1, %2}"
6593 [(set_attr "type" "alu")
6594 (set_attr "mode" "SI")])
6595 \f
6596 ;; Add with carry and subtract with borrow
6597
6598 (define_expand "<plusminus_insn><mode>3_carry"
6599 [(parallel
6600 [(set (match_operand:SWI 0 "nonimmediate_operand")
6601 (plusminus:SWI
6602 (match_operand:SWI 1 "nonimmediate_operand")
6603 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6604 [(match_operand 3 "flags_reg_operand")
6605 (const_int 0)])
6606 (match_operand:SWI 2 "<general_operand>"))))
6607 (clobber (reg:CC FLAGS_REG))])]
6608 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6609
6610 (define_insn "*<plusminus_insn><mode>3_carry"
6611 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6612 (plusminus:SWI
6613 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6614 (plus:SWI
6615 (match_operator 3 "ix86_carry_flag_operator"
6616 [(reg FLAGS_REG) (const_int 0)])
6617 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6618 (clobber (reg:CC FLAGS_REG))]
6619 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6620 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6621 [(set_attr "type" "alu")
6622 (set_attr "use_carry" "1")
6623 (set_attr "pent_pair" "pu")
6624 (set_attr "mode" "<MODE>")])
6625
6626 (define_insn "*addsi3_carry_zext"
6627 [(set (match_operand:DI 0 "register_operand" "=r")
6628 (zero_extend:DI
6629 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6630 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6631 [(reg FLAGS_REG) (const_int 0)])
6632 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6633 (clobber (reg:CC FLAGS_REG))]
6634 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6635 "adc{l}\t{%2, %k0|%k0, %2}"
6636 [(set_attr "type" "alu")
6637 (set_attr "use_carry" "1")
6638 (set_attr "pent_pair" "pu")
6639 (set_attr "mode" "SI")])
6640
6641 (define_insn "*subsi3_carry_zext"
6642 [(set (match_operand:DI 0 "register_operand" "=r")
6643 (zero_extend:DI
6644 (minus:SI (match_operand:SI 1 "register_operand" "0")
6645 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6646 [(reg FLAGS_REG) (const_int 0)])
6647 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6648 (clobber (reg:CC FLAGS_REG))]
6649 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650 "sbb{l}\t{%2, %k0|%k0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "pent_pair" "pu")
6653 (set_attr "mode" "SI")])
6654 \f
6655 ;; ADCX instruction
6656
6657 (define_insn "adcx<mode>3"
6658 [(set (reg:CCC FLAGS_REG)
6659 (compare:CCC
6660 (plus:SWI48
6661 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6662 (plus:SWI48
6663 (match_operator 4 "ix86_carry_flag_operator"
6664 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6665 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6666 (const_int 0)))
6667 (set (match_operand:SWI48 0 "register_operand" "=r")
6668 (plus:SWI48 (match_dup 1)
6669 (plus:SWI48 (match_op_dup 4
6670 [(match_dup 3) (const_int 0)])
6671 (match_dup 2))))]
6672 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6673 "adcx\t{%2, %0|%0, %2}"
6674 [(set_attr "type" "alu")
6675 (set_attr "use_carry" "1")
6676 (set_attr "mode" "<MODE>")])
6677 \f
6678 ;; Overflow setting add and subtract instructions
6679
6680 (define_insn "*add<mode>3_cconly_overflow"
6681 [(set (reg:CCC FLAGS_REG)
6682 (compare:CCC
6683 (plus:SWI
6684 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6685 (match_operand:SWI 2 "<general_operand>" "<g>"))
6686 (match_dup 1)))
6687 (clobber (match_scratch:SWI 0 "=<r>"))]
6688 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6689 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6690 [(set_attr "type" "alu")
6691 (set_attr "mode" "<MODE>")])
6692
6693 (define_insn "*sub<mode>3_cconly_overflow"
6694 [(set (reg:CCC FLAGS_REG)
6695 (compare:CCC
6696 (minus:SWI
6697 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6698 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6699 (match_dup 0)))]
6700 ""
6701 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6702 [(set_attr "type" "icmp")
6703 (set_attr "mode" "<MODE>")])
6704
6705 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6706 [(set (reg:CCC FLAGS_REG)
6707 (compare:CCC
6708 (plusminus:SWI
6709 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6710 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6711 (match_dup 1)))
6712 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6713 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6714 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6715 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6716 [(set_attr "type" "alu")
6717 (set_attr "mode" "<MODE>")])
6718
6719 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6720 [(set (reg:CCC FLAGS_REG)
6721 (compare:CCC
6722 (plusminus:SI
6723 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6724 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6725 (match_dup 1)))
6726 (set (match_operand:DI 0 "register_operand" "=r")
6727 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6728 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6729 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6730 [(set_attr "type" "alu")
6731 (set_attr "mode" "SI")])
6732
6733 ;; The patterns that match these are at the end of this file.
6734
6735 (define_expand "<plusminus_insn>xf3"
6736 [(set (match_operand:XF 0 "register_operand")
6737 (plusminus:XF
6738 (match_operand:XF 1 "register_operand")
6739 (match_operand:XF 2 "register_operand")))]
6740 "TARGET_80387")
6741
6742 (define_expand "<plusminus_insn><mode>3"
6743 [(set (match_operand:MODEF 0 "register_operand")
6744 (plusminus:MODEF
6745 (match_operand:MODEF 1 "register_operand")
6746 (match_operand:MODEF 2 "nonimmediate_operand")))]
6747 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6748 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6749 \f
6750 ;; Multiply instructions
6751
6752 (define_expand "mul<mode>3"
6753 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6754 (mult:SWIM248
6755 (match_operand:SWIM248 1 "register_operand")
6756 (match_operand:SWIM248 2 "<general_operand>")))
6757 (clobber (reg:CC FLAGS_REG))])])
6758
6759 (define_expand "mulqi3"
6760 [(parallel [(set (match_operand:QI 0 "register_operand")
6761 (mult:QI
6762 (match_operand:QI 1 "register_operand")
6763 (match_operand:QI 2 "nonimmediate_operand")))
6764 (clobber (reg:CC FLAGS_REG))])]
6765 "TARGET_QIMODE_MATH")
6766
6767 ;; On AMDFAM10
6768 ;; IMUL reg32/64, reg32/64, imm8 Direct
6769 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6770 ;; IMUL reg32/64, reg32/64, imm32 Direct
6771 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6772 ;; IMUL reg32/64, reg32/64 Direct
6773 ;; IMUL reg32/64, mem32/64 Direct
6774 ;;
6775 ;; On BDVER1, all above IMULs use DirectPath
6776
6777 (define_insn "*mul<mode>3_1"
6778 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6779 (mult:SWI48
6780 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6781 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6782 (clobber (reg:CC FLAGS_REG))]
6783 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6784 "@
6785 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6786 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6787 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6788 [(set_attr "type" "imul")
6789 (set_attr "prefix_0f" "0,0,1")
6790 (set (attr "athlon_decode")
6791 (cond [(eq_attr "cpu" "athlon")
6792 (const_string "vector")
6793 (eq_attr "alternative" "1")
6794 (const_string "vector")
6795 (and (eq_attr "alternative" "2")
6796 (match_operand 1 "memory_operand"))
6797 (const_string "vector")]
6798 (const_string "direct")))
6799 (set (attr "amdfam10_decode")
6800 (cond [(and (eq_attr "alternative" "0,1")
6801 (match_operand 1 "memory_operand"))
6802 (const_string "vector")]
6803 (const_string "direct")))
6804 (set_attr "bdver1_decode" "direct")
6805 (set_attr "mode" "<MODE>")])
6806
6807 (define_insn "*mulsi3_1_zext"
6808 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6809 (zero_extend:DI
6810 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6811 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6812 (clobber (reg:CC FLAGS_REG))]
6813 "TARGET_64BIT
6814 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6815 "@
6816 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6817 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6818 imul{l}\t{%2, %k0|%k0, %2}"
6819 [(set_attr "type" "imul")
6820 (set_attr "prefix_0f" "0,0,1")
6821 (set (attr "athlon_decode")
6822 (cond [(eq_attr "cpu" "athlon")
6823 (const_string "vector")
6824 (eq_attr "alternative" "1")
6825 (const_string "vector")
6826 (and (eq_attr "alternative" "2")
6827 (match_operand 1 "memory_operand"))
6828 (const_string "vector")]
6829 (const_string "direct")))
6830 (set (attr "amdfam10_decode")
6831 (cond [(and (eq_attr "alternative" "0,1")
6832 (match_operand 1 "memory_operand"))
6833 (const_string "vector")]
6834 (const_string "direct")))
6835 (set_attr "bdver1_decode" "direct")
6836 (set_attr "mode" "SI")])
6837
6838 ;; On AMDFAM10
6839 ;; IMUL reg16, reg16, imm8 VectorPath
6840 ;; IMUL reg16, mem16, imm8 VectorPath
6841 ;; IMUL reg16, reg16, imm16 VectorPath
6842 ;; IMUL reg16, mem16, imm16 VectorPath
6843 ;; IMUL reg16, reg16 Direct
6844 ;; IMUL reg16, mem16 Direct
6845 ;;
6846 ;; On BDVER1, all HI MULs use DoublePath
6847
6848 (define_insn "*mulhi3_1"
6849 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6850 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6851 (match_operand:HI 2 "general_operand" "K,n,mr")))
6852 (clobber (reg:CC FLAGS_REG))]
6853 "TARGET_HIMODE_MATH
6854 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6855 "@
6856 imul{w}\t{%2, %1, %0|%0, %1, %2}
6857 imul{w}\t{%2, %1, %0|%0, %1, %2}
6858 imul{w}\t{%2, %0|%0, %2}"
6859 [(set_attr "type" "imul")
6860 (set_attr "prefix_0f" "0,0,1")
6861 (set (attr "athlon_decode")
6862 (cond [(eq_attr "cpu" "athlon")
6863 (const_string "vector")
6864 (eq_attr "alternative" "1,2")
6865 (const_string "vector")]
6866 (const_string "direct")))
6867 (set (attr "amdfam10_decode")
6868 (cond [(eq_attr "alternative" "0,1")
6869 (const_string "vector")]
6870 (const_string "direct")))
6871 (set_attr "bdver1_decode" "double")
6872 (set_attr "mode" "HI")])
6873
6874 ;;On AMDFAM10 and BDVER1
6875 ;; MUL reg8 Direct
6876 ;; MUL mem8 Direct
6877
6878 (define_insn "*mulqi3_1"
6879 [(set (match_operand:QI 0 "register_operand" "=a")
6880 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6881 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6882 (clobber (reg:CC FLAGS_REG))]
6883 "TARGET_QIMODE_MATH
6884 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6885 "mul{b}\t%2"
6886 [(set_attr "type" "imul")
6887 (set_attr "length_immediate" "0")
6888 (set (attr "athlon_decode")
6889 (if_then_else (eq_attr "cpu" "athlon")
6890 (const_string "vector")
6891 (const_string "direct")))
6892 (set_attr "amdfam10_decode" "direct")
6893 (set_attr "bdver1_decode" "direct")
6894 (set_attr "mode" "QI")])
6895
6896 (define_expand "<u>mul<mode><dwi>3"
6897 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6898 (mult:<DWI>
6899 (any_extend:<DWI>
6900 (match_operand:DWIH 1 "nonimmediate_operand"))
6901 (any_extend:<DWI>
6902 (match_operand:DWIH 2 "register_operand"))))
6903 (clobber (reg:CC FLAGS_REG))])])
6904
6905 (define_expand "<u>mulqihi3"
6906 [(parallel [(set (match_operand:HI 0 "register_operand")
6907 (mult:HI
6908 (any_extend:HI
6909 (match_operand:QI 1 "nonimmediate_operand"))
6910 (any_extend:HI
6911 (match_operand:QI 2 "register_operand"))))
6912 (clobber (reg:CC FLAGS_REG))])]
6913 "TARGET_QIMODE_MATH")
6914
6915 (define_insn "*bmi2_umulditi3_1"
6916 [(set (match_operand:DI 0 "register_operand" "=r")
6917 (mult:DI
6918 (match_operand:DI 2 "nonimmediate_operand" "%d")
6919 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6920 (set (match_operand:DI 1 "register_operand" "=r")
6921 (truncate:DI
6922 (lshiftrt:TI
6923 (mult:TI (zero_extend:TI (match_dup 2))
6924 (zero_extend:TI (match_dup 3)))
6925 (const_int 64))))]
6926 "TARGET_64BIT && TARGET_BMI2
6927 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6928 "mulx\t{%3, %0, %1|%1, %0, %3}"
6929 [(set_attr "type" "imulx")
6930 (set_attr "prefix" "vex")
6931 (set_attr "mode" "DI")])
6932
6933 (define_insn "*bmi2_umulsidi3_1"
6934 [(set (match_operand:SI 0 "register_operand" "=r")
6935 (mult:SI
6936 (match_operand:SI 2 "nonimmediate_operand" "%d")
6937 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6938 (set (match_operand:SI 1 "register_operand" "=r")
6939 (truncate:SI
6940 (lshiftrt:DI
6941 (mult:DI (zero_extend:DI (match_dup 2))
6942 (zero_extend:DI (match_dup 3)))
6943 (const_int 32))))]
6944 "!TARGET_64BIT && TARGET_BMI2
6945 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6946 "mulx\t{%3, %0, %1|%1, %0, %3}"
6947 [(set_attr "type" "imulx")
6948 (set_attr "prefix" "vex")
6949 (set_attr "mode" "SI")])
6950
6951 (define_insn "*umul<mode><dwi>3_1"
6952 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6953 (mult:<DWI>
6954 (zero_extend:<DWI>
6955 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6956 (zero_extend:<DWI>
6957 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6958 (clobber (reg:CC FLAGS_REG))]
6959 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6960 "@
6961 #
6962 mul{<imodesuffix>}\t%2"
6963 [(set_attr "isa" "bmi2,*")
6964 (set_attr "type" "imulx,imul")
6965 (set_attr "length_immediate" "*,0")
6966 (set (attr "athlon_decode")
6967 (cond [(eq_attr "alternative" "1")
6968 (if_then_else (eq_attr "cpu" "athlon")
6969 (const_string "vector")
6970 (const_string "double"))]
6971 (const_string "*")))
6972 (set_attr "amdfam10_decode" "*,double")
6973 (set_attr "bdver1_decode" "*,direct")
6974 (set_attr "prefix" "vex,orig")
6975 (set_attr "mode" "<MODE>")])
6976
6977 ;; Convert mul to the mulx pattern to avoid flags dependency.
6978 (define_split
6979 [(set (match_operand:<DWI> 0 "register_operand")
6980 (mult:<DWI>
6981 (zero_extend:<DWI>
6982 (match_operand:DWIH 1 "register_operand"))
6983 (zero_extend:<DWI>
6984 (match_operand:DWIH 2 "nonimmediate_operand"))))
6985 (clobber (reg:CC FLAGS_REG))]
6986 "TARGET_BMI2 && reload_completed
6987 && true_regnum (operands[1]) == DX_REG"
6988 [(parallel [(set (match_dup 3)
6989 (mult:DWIH (match_dup 1) (match_dup 2)))
6990 (set (match_dup 4)
6991 (truncate:DWIH
6992 (lshiftrt:<DWI>
6993 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6994 (zero_extend:<DWI> (match_dup 2)))
6995 (match_dup 5))))])]
6996 {
6997 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6998
6999 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
7000 })
7001
7002 (define_insn "*mul<mode><dwi>3_1"
7003 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7004 (mult:<DWI>
7005 (sign_extend:<DWI>
7006 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7007 (sign_extend:<DWI>
7008 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7009 (clobber (reg:CC FLAGS_REG))]
7010 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7011 "imul{<imodesuffix>}\t%2"
7012 [(set_attr "type" "imul")
7013 (set_attr "length_immediate" "0")
7014 (set (attr "athlon_decode")
7015 (if_then_else (eq_attr "cpu" "athlon")
7016 (const_string "vector")
7017 (const_string "double")))
7018 (set_attr "amdfam10_decode" "double")
7019 (set_attr "bdver1_decode" "direct")
7020 (set_attr "mode" "<MODE>")])
7021
7022 (define_insn "*<u>mulqihi3_1"
7023 [(set (match_operand:HI 0 "register_operand" "=a")
7024 (mult:HI
7025 (any_extend:HI
7026 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7027 (any_extend:HI
7028 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7029 (clobber (reg:CC FLAGS_REG))]
7030 "TARGET_QIMODE_MATH
7031 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7032 "<sgnprefix>mul{b}\t%2"
7033 [(set_attr "type" "imul")
7034 (set_attr "length_immediate" "0")
7035 (set (attr "athlon_decode")
7036 (if_then_else (eq_attr "cpu" "athlon")
7037 (const_string "vector")
7038 (const_string "direct")))
7039 (set_attr "amdfam10_decode" "direct")
7040 (set_attr "bdver1_decode" "direct")
7041 (set_attr "mode" "QI")])
7042
7043 (define_expand "<s>mul<mode>3_highpart"
7044 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7045 (truncate:SWI48
7046 (lshiftrt:<DWI>
7047 (mult:<DWI>
7048 (any_extend:<DWI>
7049 (match_operand:SWI48 1 "nonimmediate_operand"))
7050 (any_extend:<DWI>
7051 (match_operand:SWI48 2 "register_operand")))
7052 (match_dup 4))))
7053 (clobber (match_scratch:SWI48 3))
7054 (clobber (reg:CC FLAGS_REG))])]
7055 ""
7056 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7057
7058 (define_insn "*<s>muldi3_highpart_1"
7059 [(set (match_operand:DI 0 "register_operand" "=d")
7060 (truncate:DI
7061 (lshiftrt:TI
7062 (mult:TI
7063 (any_extend:TI
7064 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7065 (any_extend:TI
7066 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7067 (const_int 64))))
7068 (clobber (match_scratch:DI 3 "=1"))
7069 (clobber (reg:CC FLAGS_REG))]
7070 "TARGET_64BIT
7071 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7072 "<sgnprefix>mul{q}\t%2"
7073 [(set_attr "type" "imul")
7074 (set_attr "length_immediate" "0")
7075 (set (attr "athlon_decode")
7076 (if_then_else (eq_attr "cpu" "athlon")
7077 (const_string "vector")
7078 (const_string "double")))
7079 (set_attr "amdfam10_decode" "double")
7080 (set_attr "bdver1_decode" "direct")
7081 (set_attr "mode" "DI")])
7082
7083 (define_insn "*<s>mulsi3_highpart_1"
7084 [(set (match_operand:SI 0 "register_operand" "=d")
7085 (truncate:SI
7086 (lshiftrt:DI
7087 (mult:DI
7088 (any_extend:DI
7089 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7090 (any_extend:DI
7091 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7092 (const_int 32))))
7093 (clobber (match_scratch:SI 3 "=1"))
7094 (clobber (reg:CC FLAGS_REG))]
7095 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7096 "<sgnprefix>mul{l}\t%2"
7097 [(set_attr "type" "imul")
7098 (set_attr "length_immediate" "0")
7099 (set (attr "athlon_decode")
7100 (if_then_else (eq_attr "cpu" "athlon")
7101 (const_string "vector")
7102 (const_string "double")))
7103 (set_attr "amdfam10_decode" "double")
7104 (set_attr "bdver1_decode" "direct")
7105 (set_attr "mode" "SI")])
7106
7107 (define_insn "*<s>mulsi3_highpart_zext"
7108 [(set (match_operand:DI 0 "register_operand" "=d")
7109 (zero_extend:DI (truncate:SI
7110 (lshiftrt:DI
7111 (mult:DI (any_extend:DI
7112 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7113 (any_extend:DI
7114 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7115 (const_int 32)))))
7116 (clobber (match_scratch:SI 3 "=1"))
7117 (clobber (reg:CC FLAGS_REG))]
7118 "TARGET_64BIT
7119 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7120 "<sgnprefix>mul{l}\t%2"
7121 [(set_attr "type" "imul")
7122 (set_attr "length_immediate" "0")
7123 (set (attr "athlon_decode")
7124 (if_then_else (eq_attr "cpu" "athlon")
7125 (const_string "vector")
7126 (const_string "double")))
7127 (set_attr "amdfam10_decode" "double")
7128 (set_attr "bdver1_decode" "direct")
7129 (set_attr "mode" "SI")])
7130
7131 ;; The patterns that match these are at the end of this file.
7132
7133 (define_expand "mulxf3"
7134 [(set (match_operand:XF 0 "register_operand")
7135 (mult:XF (match_operand:XF 1 "register_operand")
7136 (match_operand:XF 2 "register_operand")))]
7137 "TARGET_80387")
7138
7139 (define_expand "mul<mode>3"
7140 [(set (match_operand:MODEF 0 "register_operand")
7141 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7142 (match_operand:MODEF 2 "nonimmediate_operand")))]
7143 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7144 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7145 \f
7146 ;; Divide instructions
7147
7148 ;; The patterns that match these are at the end of this file.
7149
7150 (define_expand "divxf3"
7151 [(set (match_operand:XF 0 "register_operand")
7152 (div:XF (match_operand:XF 1 "register_operand")
7153 (match_operand:XF 2 "register_operand")))]
7154 "TARGET_80387")
7155
7156 (define_expand "divdf3"
7157 [(set (match_operand:DF 0 "register_operand")
7158 (div:DF (match_operand:DF 1 "register_operand")
7159 (match_operand:DF 2 "nonimmediate_operand")))]
7160 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7161 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7162
7163 (define_expand "divsf3"
7164 [(set (match_operand:SF 0 "register_operand")
7165 (div:SF (match_operand:SF 1 "register_operand")
7166 (match_operand:SF 2 "nonimmediate_operand")))]
7167 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7168 || TARGET_SSE_MATH"
7169 {
7170 if (TARGET_SSE_MATH
7171 && TARGET_RECIP_DIV
7172 && optimize_insn_for_speed_p ()
7173 && flag_finite_math_only && !flag_trapping_math
7174 && flag_unsafe_math_optimizations)
7175 {
7176 ix86_emit_swdivsf (operands[0], operands[1],
7177 operands[2], SFmode);
7178 DONE;
7179 }
7180 })
7181 \f
7182 ;; Divmod instructions.
7183
7184 (define_expand "divmod<mode>4"
7185 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7186 (div:SWIM248
7187 (match_operand:SWIM248 1 "register_operand")
7188 (match_operand:SWIM248 2 "nonimmediate_operand")))
7189 (set (match_operand:SWIM248 3 "register_operand")
7190 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7191 (clobber (reg:CC FLAGS_REG))])])
7192
7193 ;; Split with 8bit unsigned divide:
7194 ;; if (dividend an divisor are in [0-255])
7195 ;; use 8bit unsigned integer divide
7196 ;; else
7197 ;; use original integer divide
7198 (define_split
7199 [(set (match_operand:SWI48 0 "register_operand")
7200 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7201 (match_operand:SWI48 3 "nonimmediate_operand")))
7202 (set (match_operand:SWI48 1 "register_operand")
7203 (mod:SWI48 (match_dup 2) (match_dup 3)))
7204 (clobber (reg:CC FLAGS_REG))]
7205 "TARGET_USE_8BIT_IDIV
7206 && TARGET_QIMODE_MATH
7207 && can_create_pseudo_p ()
7208 && !optimize_insn_for_size_p ()"
7209 [(const_int 0)]
7210 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7211
7212 (define_insn_and_split "divmod<mode>4_1"
7213 [(set (match_operand:SWI48 0 "register_operand" "=a")
7214 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7215 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7216 (set (match_operand:SWI48 1 "register_operand" "=&d")
7217 (mod:SWI48 (match_dup 2) (match_dup 3)))
7218 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7219 (clobber (reg:CC FLAGS_REG))]
7220 ""
7221 "#"
7222 "reload_completed"
7223 [(parallel [(set (match_dup 1)
7224 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7225 (clobber (reg:CC FLAGS_REG))])
7226 (parallel [(set (match_dup 0)
7227 (div:SWI48 (match_dup 2) (match_dup 3)))
7228 (set (match_dup 1)
7229 (mod:SWI48 (match_dup 2) (match_dup 3)))
7230 (use (match_dup 1))
7231 (clobber (reg:CC FLAGS_REG))])]
7232 {
7233 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7234
7235 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7236 operands[4] = operands[2];
7237 else
7238 {
7239 /* Avoid use of cltd in favor of a mov+shift. */
7240 emit_move_insn (operands[1], operands[2]);
7241 operands[4] = operands[1];
7242 }
7243 }
7244 [(set_attr "type" "multi")
7245 (set_attr "mode" "<MODE>")])
7246
7247 (define_insn_and_split "*divmod<mode>4"
7248 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7249 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7250 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7251 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7252 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7253 (clobber (reg:CC FLAGS_REG))]
7254 ""
7255 "#"
7256 "reload_completed"
7257 [(parallel [(set (match_dup 1)
7258 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7259 (clobber (reg:CC FLAGS_REG))])
7260 (parallel [(set (match_dup 0)
7261 (div:SWIM248 (match_dup 2) (match_dup 3)))
7262 (set (match_dup 1)
7263 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7264 (use (match_dup 1))
7265 (clobber (reg:CC FLAGS_REG))])]
7266 {
7267 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7268
7269 if (<MODE>mode != HImode
7270 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7271 operands[4] = operands[2];
7272 else
7273 {
7274 /* Avoid use of cltd in favor of a mov+shift. */
7275 emit_move_insn (operands[1], operands[2]);
7276 operands[4] = operands[1];
7277 }
7278 }
7279 [(set_attr "type" "multi")
7280 (set_attr "mode" "<MODE>")])
7281
7282 (define_insn "*divmod<mode>4_noext"
7283 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7284 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7285 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7286 (set (match_operand:SWIM248 1 "register_operand" "=d")
7287 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7288 (use (match_operand:SWIM248 4 "register_operand" "1"))
7289 (clobber (reg:CC FLAGS_REG))]
7290 ""
7291 "idiv{<imodesuffix>}\t%3"
7292 [(set_attr "type" "idiv")
7293 (set_attr "mode" "<MODE>")])
7294
7295 (define_expand "divmodqi4"
7296 [(parallel [(set (match_operand:QI 0 "register_operand")
7297 (div:QI
7298 (match_operand:QI 1 "register_operand")
7299 (match_operand:QI 2 "nonimmediate_operand")))
7300 (set (match_operand:QI 3 "register_operand")
7301 (mod:QI (match_dup 1) (match_dup 2)))
7302 (clobber (reg:CC FLAGS_REG))])]
7303 "TARGET_QIMODE_MATH"
7304 {
7305 rtx div, mod, insn;
7306 rtx tmp0, tmp1;
7307
7308 tmp0 = gen_reg_rtx (HImode);
7309 tmp1 = gen_reg_rtx (HImode);
7310
7311 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7312 in AX. */
7313 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7314 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7315
7316 /* Extract remainder from AH. */
7317 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7318 insn = emit_move_insn (operands[3], tmp1);
7319
7320 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7321 set_unique_reg_note (insn, REG_EQUAL, mod);
7322
7323 /* Extract quotient from AL. */
7324 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7325
7326 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7327 set_unique_reg_note (insn, REG_EQUAL, div);
7328
7329 DONE;
7330 })
7331
7332 ;; Divide AX by r/m8, with result stored in
7333 ;; AL <- Quotient
7334 ;; AH <- Remainder
7335 ;; Change div/mod to HImode and extend the second argument to HImode
7336 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7337 ;; combine may fail.
7338 (define_insn "divmodhiqi3"
7339 [(set (match_operand:HI 0 "register_operand" "=a")
7340 (ior:HI
7341 (ashift:HI
7342 (zero_extend:HI
7343 (truncate:QI
7344 (mod:HI (match_operand:HI 1 "register_operand" "0")
7345 (sign_extend:HI
7346 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7347 (const_int 8))
7348 (zero_extend:HI
7349 (truncate:QI
7350 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7351 (clobber (reg:CC FLAGS_REG))]
7352 "TARGET_QIMODE_MATH"
7353 "idiv{b}\t%2"
7354 [(set_attr "type" "idiv")
7355 (set_attr "mode" "QI")])
7356
7357 (define_expand "udivmod<mode>4"
7358 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7359 (udiv:SWIM248
7360 (match_operand:SWIM248 1 "register_operand")
7361 (match_operand:SWIM248 2 "nonimmediate_operand")))
7362 (set (match_operand:SWIM248 3 "register_operand")
7363 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7364 (clobber (reg:CC FLAGS_REG))])])
7365
7366 ;; Split with 8bit unsigned divide:
7367 ;; if (dividend an divisor are in [0-255])
7368 ;; use 8bit unsigned integer divide
7369 ;; else
7370 ;; use original integer divide
7371 (define_split
7372 [(set (match_operand:SWI48 0 "register_operand")
7373 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7374 (match_operand:SWI48 3 "nonimmediate_operand")))
7375 (set (match_operand:SWI48 1 "register_operand")
7376 (umod:SWI48 (match_dup 2) (match_dup 3)))
7377 (clobber (reg:CC FLAGS_REG))]
7378 "TARGET_USE_8BIT_IDIV
7379 && TARGET_QIMODE_MATH
7380 && can_create_pseudo_p ()
7381 && !optimize_insn_for_size_p ()"
7382 [(const_int 0)]
7383 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7384
7385 (define_insn_and_split "udivmod<mode>4_1"
7386 [(set (match_operand:SWI48 0 "register_operand" "=a")
7387 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7388 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7389 (set (match_operand:SWI48 1 "register_operand" "=&d")
7390 (umod:SWI48 (match_dup 2) (match_dup 3)))
7391 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7392 (clobber (reg:CC FLAGS_REG))]
7393 ""
7394 "#"
7395 "reload_completed"
7396 [(set (match_dup 1) (const_int 0))
7397 (parallel [(set (match_dup 0)
7398 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7399 (set (match_dup 1)
7400 (umod:SWI48 (match_dup 2) (match_dup 3)))
7401 (use (match_dup 1))
7402 (clobber (reg:CC FLAGS_REG))])]
7403 ""
7404 [(set_attr "type" "multi")
7405 (set_attr "mode" "<MODE>")])
7406
7407 (define_insn_and_split "*udivmod<mode>4"
7408 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7409 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7410 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7411 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7412 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7413 (clobber (reg:CC FLAGS_REG))]
7414 ""
7415 "#"
7416 "reload_completed"
7417 [(set (match_dup 1) (const_int 0))
7418 (parallel [(set (match_dup 0)
7419 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7420 (set (match_dup 1)
7421 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7422 (use (match_dup 1))
7423 (clobber (reg:CC FLAGS_REG))])]
7424 ""
7425 [(set_attr "type" "multi")
7426 (set_attr "mode" "<MODE>")])
7427
7428 (define_insn "*udivmod<mode>4_noext"
7429 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7430 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7431 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7432 (set (match_operand:SWIM248 1 "register_operand" "=d")
7433 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7434 (use (match_operand:SWIM248 4 "register_operand" "1"))
7435 (clobber (reg:CC FLAGS_REG))]
7436 ""
7437 "div{<imodesuffix>}\t%3"
7438 [(set_attr "type" "idiv")
7439 (set_attr "mode" "<MODE>")])
7440
7441 (define_expand "udivmodqi4"
7442 [(parallel [(set (match_operand:QI 0 "register_operand")
7443 (udiv:QI
7444 (match_operand:QI 1 "register_operand")
7445 (match_operand:QI 2 "nonimmediate_operand")))
7446 (set (match_operand:QI 3 "register_operand")
7447 (umod:QI (match_dup 1) (match_dup 2)))
7448 (clobber (reg:CC FLAGS_REG))])]
7449 "TARGET_QIMODE_MATH"
7450 {
7451 rtx div, mod, insn;
7452 rtx tmp0, tmp1;
7453
7454 tmp0 = gen_reg_rtx (HImode);
7455 tmp1 = gen_reg_rtx (HImode);
7456
7457 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7458 in AX. */
7459 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7460 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7461
7462 /* Extract remainder from AH. */
7463 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7464 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7465 insn = emit_move_insn (operands[3], tmp1);
7466
7467 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7468 set_unique_reg_note (insn, REG_EQUAL, mod);
7469
7470 /* Extract quotient from AL. */
7471 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7472
7473 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7474 set_unique_reg_note (insn, REG_EQUAL, div);
7475
7476 DONE;
7477 })
7478
7479 (define_insn "udivmodhiqi3"
7480 [(set (match_operand:HI 0 "register_operand" "=a")
7481 (ior:HI
7482 (ashift:HI
7483 (zero_extend:HI
7484 (truncate:QI
7485 (mod:HI (match_operand:HI 1 "register_operand" "0")
7486 (zero_extend:HI
7487 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7488 (const_int 8))
7489 (zero_extend:HI
7490 (truncate:QI
7491 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7492 (clobber (reg:CC FLAGS_REG))]
7493 "TARGET_QIMODE_MATH"
7494 "div{b}\t%2"
7495 [(set_attr "type" "idiv")
7496 (set_attr "mode" "QI")])
7497
7498 ;; We cannot use div/idiv for double division, because it causes
7499 ;; "division by zero" on the overflow and that's not what we expect
7500 ;; from truncate. Because true (non truncating) double division is
7501 ;; never generated, we can't create this insn anyway.
7502 ;
7503 ;(define_insn ""
7504 ; [(set (match_operand:SI 0 "register_operand" "=a")
7505 ; (truncate:SI
7506 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7507 ; (zero_extend:DI
7508 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7509 ; (set (match_operand:SI 3 "register_operand" "=d")
7510 ; (truncate:SI
7511 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7512 ; (clobber (reg:CC FLAGS_REG))]
7513 ; ""
7514 ; "div{l}\t{%2, %0|%0, %2}"
7515 ; [(set_attr "type" "idiv")])
7516 \f
7517 ;;- Logical AND instructions
7518
7519 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7520 ;; Note that this excludes ah.
7521
7522 (define_expand "testsi_ccno_1"
7523 [(set (reg:CCNO FLAGS_REG)
7524 (compare:CCNO
7525 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7526 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7527 (const_int 0)))])
7528
7529 (define_expand "testqi_ccz_1"
7530 [(set (reg:CCZ FLAGS_REG)
7531 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7532 (match_operand:QI 1 "nonmemory_operand"))
7533 (const_int 0)))])
7534
7535 (define_expand "testdi_ccno_1"
7536 [(set (reg:CCNO FLAGS_REG)
7537 (compare:CCNO
7538 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7539 (match_operand:DI 1 "x86_64_szext_general_operand"))
7540 (const_int 0)))]
7541 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7542
7543 (define_insn "*testdi_1"
7544 [(set (reg FLAGS_REG)
7545 (compare
7546 (and:DI
7547 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7548 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7549 (const_int 0)))]
7550 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7551 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7552 "@
7553 test{l}\t{%k1, %k0|%k0, %k1}
7554 test{l}\t{%k1, %k0|%k0, %k1}
7555 test{q}\t{%1, %0|%0, %1}
7556 test{q}\t{%1, %0|%0, %1}
7557 test{q}\t{%1, %0|%0, %1}"
7558 [(set_attr "type" "test")
7559 (set_attr "modrm" "0,1,0,1,1")
7560 (set_attr "mode" "SI,SI,DI,DI,DI")])
7561
7562 (define_insn "*testqi_1_maybe_si"
7563 [(set (reg FLAGS_REG)
7564 (compare
7565 (and:QI
7566 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7567 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7568 (const_int 0)))]
7569 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7570 && ix86_match_ccmode (insn,
7571 CONST_INT_P (operands[1])
7572 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7573 {
7574 if (which_alternative == 3)
7575 {
7576 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7577 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7578 return "test{l}\t{%1, %k0|%k0, %1}";
7579 }
7580 return "test{b}\t{%1, %0|%0, %1}";
7581 }
7582 [(set_attr "type" "test")
7583 (set_attr "modrm" "0,1,1,1")
7584 (set_attr "mode" "QI,QI,QI,SI")
7585 (set_attr "pent_pair" "uv,np,uv,np")])
7586
7587 (define_insn "*test<mode>_1"
7588 [(set (reg FLAGS_REG)
7589 (compare
7590 (and:SWI124
7591 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7592 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7593 (const_int 0)))]
7594 "ix86_match_ccmode (insn, CCNOmode)
7595 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7596 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7597 [(set_attr "type" "test")
7598 (set_attr "modrm" "0,1,1")
7599 (set_attr "mode" "<MODE>")
7600 (set_attr "pent_pair" "uv,np,uv")])
7601
7602 (define_expand "testqi_ext_ccno_0"
7603 [(set (reg:CCNO FLAGS_REG)
7604 (compare:CCNO
7605 (and:SI
7606 (zero_extract:SI
7607 (match_operand 0 "ext_register_operand")
7608 (const_int 8)
7609 (const_int 8))
7610 (match_operand 1 "const_int_operand"))
7611 (const_int 0)))])
7612
7613 (define_insn "*testqi_ext_0"
7614 [(set (reg FLAGS_REG)
7615 (compare
7616 (and:SI
7617 (zero_extract:SI
7618 (match_operand 0 "ext_register_operand" "Q")
7619 (const_int 8)
7620 (const_int 8))
7621 (match_operand 1 "const_int_operand" "n"))
7622 (const_int 0)))]
7623 "ix86_match_ccmode (insn, CCNOmode)"
7624 "test{b}\t{%1, %h0|%h0, %1}"
7625 [(set_attr "type" "test")
7626 (set_attr "mode" "QI")
7627 (set_attr "length_immediate" "1")
7628 (set_attr "modrm" "1")
7629 (set_attr "pent_pair" "np")])
7630
7631 (define_insn "*testqi_ext_1_rex64"
7632 [(set (reg FLAGS_REG)
7633 (compare
7634 (and:SI
7635 (zero_extract:SI
7636 (match_operand 0 "ext_register_operand" "Q")
7637 (const_int 8)
7638 (const_int 8))
7639 (zero_extend:SI
7640 (match_operand:QI 1 "register_operand" "Q")))
7641 (const_int 0)))]
7642 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7643 "test{b}\t{%1, %h0|%h0, %1}"
7644 [(set_attr "type" "test")
7645 (set_attr "mode" "QI")])
7646
7647 (define_insn "*testqi_ext_1"
7648 [(set (reg FLAGS_REG)
7649 (compare
7650 (and:SI
7651 (zero_extract:SI
7652 (match_operand 0 "ext_register_operand" "Q")
7653 (const_int 8)
7654 (const_int 8))
7655 (zero_extend:SI
7656 (match_operand:QI 1 "general_operand" "Qm")))
7657 (const_int 0)))]
7658 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7659 "test{b}\t{%1, %h0|%h0, %1}"
7660 [(set_attr "type" "test")
7661 (set_attr "mode" "QI")])
7662
7663 (define_insn "*testqi_ext_2"
7664 [(set (reg FLAGS_REG)
7665 (compare
7666 (and:SI
7667 (zero_extract:SI
7668 (match_operand 0 "ext_register_operand" "Q")
7669 (const_int 8)
7670 (const_int 8))
7671 (zero_extract:SI
7672 (match_operand 1 "ext_register_operand" "Q")
7673 (const_int 8)
7674 (const_int 8)))
7675 (const_int 0)))]
7676 "ix86_match_ccmode (insn, CCNOmode)"
7677 "test{b}\t{%h1, %h0|%h0, %h1}"
7678 [(set_attr "type" "test")
7679 (set_attr "mode" "QI")])
7680
7681 (define_insn "*testqi_ext_3_rex64"
7682 [(set (reg FLAGS_REG)
7683 (compare (zero_extract:DI
7684 (match_operand 0 "nonimmediate_operand" "rm")
7685 (match_operand:DI 1 "const_int_operand")
7686 (match_operand:DI 2 "const_int_operand"))
7687 (const_int 0)))]
7688 "TARGET_64BIT
7689 && ix86_match_ccmode (insn, CCNOmode)
7690 && INTVAL (operands[1]) > 0
7691 && INTVAL (operands[2]) >= 0
7692 /* Ensure that resulting mask is zero or sign extended operand. */
7693 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7694 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7695 && INTVAL (operands[1]) > 32))
7696 && (GET_MODE (operands[0]) == SImode
7697 || GET_MODE (operands[0]) == DImode
7698 || GET_MODE (operands[0]) == HImode
7699 || GET_MODE (operands[0]) == QImode)"
7700 "#")
7701
7702 ;; Combine likes to form bit extractions for some tests. Humor it.
7703 (define_insn "*testqi_ext_3"
7704 [(set (reg FLAGS_REG)
7705 (compare (zero_extract:SI
7706 (match_operand 0 "nonimmediate_operand" "rm")
7707 (match_operand:SI 1 "const_int_operand")
7708 (match_operand:SI 2 "const_int_operand"))
7709 (const_int 0)))]
7710 "ix86_match_ccmode (insn, CCNOmode)
7711 && INTVAL (operands[1]) > 0
7712 && INTVAL (operands[2]) >= 0
7713 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7714 && (GET_MODE (operands[0]) == SImode
7715 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7716 || GET_MODE (operands[0]) == HImode
7717 || GET_MODE (operands[0]) == QImode)"
7718 "#")
7719
7720 (define_split
7721 [(set (match_operand 0 "flags_reg_operand")
7722 (match_operator 1 "compare_operator"
7723 [(zero_extract
7724 (match_operand 2 "nonimmediate_operand")
7725 (match_operand 3 "const_int_operand")
7726 (match_operand 4 "const_int_operand"))
7727 (const_int 0)]))]
7728 "ix86_match_ccmode (insn, CCNOmode)"
7729 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7730 {
7731 rtx val = operands[2];
7732 HOST_WIDE_INT len = INTVAL (operands[3]);
7733 HOST_WIDE_INT pos = INTVAL (operands[4]);
7734 HOST_WIDE_INT mask;
7735 enum machine_mode mode, submode;
7736
7737 mode = GET_MODE (val);
7738 if (MEM_P (val))
7739 {
7740 /* ??? Combine likes to put non-volatile mem extractions in QImode
7741 no matter the size of the test. So find a mode that works. */
7742 if (! MEM_VOLATILE_P (val))
7743 {
7744 mode = smallest_mode_for_size (pos + len, MODE_INT);
7745 val = adjust_address (val, mode, 0);
7746 }
7747 }
7748 else if (GET_CODE (val) == SUBREG
7749 && (submode = GET_MODE (SUBREG_REG (val)),
7750 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7751 && pos + len <= GET_MODE_BITSIZE (submode)
7752 && GET_MODE_CLASS (submode) == MODE_INT)
7753 {
7754 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7755 mode = submode;
7756 val = SUBREG_REG (val);
7757 }
7758 else if (mode == HImode && pos + len <= 8)
7759 {
7760 /* Small HImode tests can be converted to QImode. */
7761 mode = QImode;
7762 val = gen_lowpart (QImode, val);
7763 }
7764
7765 if (len == HOST_BITS_PER_WIDE_INT)
7766 mask = -1;
7767 else
7768 mask = ((HOST_WIDE_INT)1 << len) - 1;
7769 mask <<= pos;
7770
7771 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7772 })
7773
7774 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7775 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7776 ;; this is relatively important trick.
7777 ;; Do the conversion only post-reload to avoid limiting of the register class
7778 ;; to QI regs.
7779 (define_split
7780 [(set (match_operand 0 "flags_reg_operand")
7781 (match_operator 1 "compare_operator"
7782 [(and (match_operand 2 "register_operand")
7783 (match_operand 3 "const_int_operand"))
7784 (const_int 0)]))]
7785 "reload_completed
7786 && QI_REG_P (operands[2])
7787 && GET_MODE (operands[2]) != QImode
7788 && ((ix86_match_ccmode (insn, CCZmode)
7789 && !(INTVAL (operands[3]) & ~(255 << 8)))
7790 || (ix86_match_ccmode (insn, CCNOmode)
7791 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7792 [(set (match_dup 0)
7793 (match_op_dup 1
7794 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7795 (match_dup 3))
7796 (const_int 0)]))]
7797 {
7798 operands[2] = gen_lowpart (SImode, operands[2]);
7799 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7800 })
7801
7802 (define_split
7803 [(set (match_operand 0 "flags_reg_operand")
7804 (match_operator 1 "compare_operator"
7805 [(and (match_operand 2 "nonimmediate_operand")
7806 (match_operand 3 "const_int_operand"))
7807 (const_int 0)]))]
7808 "reload_completed
7809 && GET_MODE (operands[2]) != QImode
7810 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7811 && ((ix86_match_ccmode (insn, CCZmode)
7812 && !(INTVAL (operands[3]) & ~255))
7813 || (ix86_match_ccmode (insn, CCNOmode)
7814 && !(INTVAL (operands[3]) & ~127)))"
7815 [(set (match_dup 0)
7816 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7817 (const_int 0)]))]
7818 {
7819 operands[2] = gen_lowpart (QImode, operands[2]);
7820 operands[3] = gen_lowpart (QImode, operands[3]);
7821 })
7822
7823 ;; %%% This used to optimize known byte-wide and operations to memory,
7824 ;; and sometimes to QImode registers. If this is considered useful,
7825 ;; it should be done with splitters.
7826
7827 (define_expand "and<mode>3"
7828 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7829 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7830 (match_operand:SWIM 2 "<general_szext_operand>")))]
7831 ""
7832 {
7833 enum machine_mode mode = <MODE>mode;
7834 rtx (*insn) (rtx, rtx);
7835
7836 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7837 {
7838 HOST_WIDE_INT ival = INTVAL (operands[2]);
7839
7840 if (ival == (HOST_WIDE_INT) 0xffffffff)
7841 mode = SImode;
7842 else if (ival == 0xffff)
7843 mode = HImode;
7844 else if (ival == 0xff)
7845 mode = QImode;
7846 }
7847
7848 if (mode == <MODE>mode)
7849 {
7850 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7851 DONE;
7852 }
7853
7854 if (<MODE>mode == DImode)
7855 insn = (mode == SImode)
7856 ? gen_zero_extendsidi2
7857 : (mode == HImode)
7858 ? gen_zero_extendhidi2
7859 : gen_zero_extendqidi2;
7860 else if (<MODE>mode == SImode)
7861 insn = (mode == HImode)
7862 ? gen_zero_extendhisi2
7863 : gen_zero_extendqisi2;
7864 else if (<MODE>mode == HImode)
7865 insn = gen_zero_extendqihi2;
7866 else
7867 gcc_unreachable ();
7868
7869 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7870 DONE;
7871 })
7872
7873 (define_insn "*anddi_1"
7874 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7875 (and:DI
7876 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7877 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7878 (clobber (reg:CC FLAGS_REG))]
7879 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7880 {
7881 switch (get_attr_type (insn))
7882 {
7883 case TYPE_IMOVX:
7884 return "#";
7885
7886 default:
7887 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7888 if (get_attr_mode (insn) == MODE_SI)
7889 return "and{l}\t{%k2, %k0|%k0, %k2}";
7890 else
7891 return "and{q}\t{%2, %0|%0, %2}";
7892 }
7893 }
7894 [(set_attr "type" "alu,alu,alu,imovx")
7895 (set_attr "length_immediate" "*,*,*,0")
7896 (set (attr "prefix_rex")
7897 (if_then_else
7898 (and (eq_attr "type" "imovx")
7899 (and (match_test "INTVAL (operands[2]) == 0xff")
7900 (match_operand 1 "ext_QIreg_operand")))
7901 (const_string "1")
7902 (const_string "*")))
7903 (set_attr "mode" "SI,DI,DI,SI")])
7904
7905 (define_insn "*andsi_1"
7906 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7907 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7908 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7909 (clobber (reg:CC FLAGS_REG))]
7910 "ix86_binary_operator_ok (AND, SImode, operands)"
7911 {
7912 switch (get_attr_type (insn))
7913 {
7914 case TYPE_IMOVX:
7915 return "#";
7916
7917 default:
7918 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7919 return "and{l}\t{%2, %0|%0, %2}";
7920 }
7921 }
7922 [(set_attr "type" "alu,alu,imovx")
7923 (set (attr "prefix_rex")
7924 (if_then_else
7925 (and (eq_attr "type" "imovx")
7926 (and (match_test "INTVAL (operands[2]) == 0xff")
7927 (match_operand 1 "ext_QIreg_operand")))
7928 (const_string "1")
7929 (const_string "*")))
7930 (set_attr "length_immediate" "*,*,0")
7931 (set_attr "mode" "SI")])
7932
7933 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7934 (define_insn "*andsi_1_zext"
7935 [(set (match_operand:DI 0 "register_operand" "=r")
7936 (zero_extend:DI
7937 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7938 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7939 (clobber (reg:CC FLAGS_REG))]
7940 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7941 "and{l}\t{%2, %k0|%k0, %2}"
7942 [(set_attr "type" "alu")
7943 (set_attr "mode" "SI")])
7944
7945 (define_insn "*andhi_1"
7946 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7947 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7948 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7949 (clobber (reg:CC FLAGS_REG))]
7950 "ix86_binary_operator_ok (AND, HImode, operands)"
7951 {
7952 switch (get_attr_type (insn))
7953 {
7954 case TYPE_IMOVX:
7955 return "#";
7956
7957 default:
7958 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7959 return "and{w}\t{%2, %0|%0, %2}";
7960 }
7961 }
7962 [(set_attr "type" "alu,alu,imovx")
7963 (set_attr "length_immediate" "*,*,0")
7964 (set (attr "prefix_rex")
7965 (if_then_else
7966 (and (eq_attr "type" "imovx")
7967 (match_operand 1 "ext_QIreg_operand"))
7968 (const_string "1")
7969 (const_string "*")))
7970 (set_attr "mode" "HI,HI,SI")])
7971
7972 ;; %%% Potential partial reg stall on alternative 2. What to do?
7973 (define_insn "*andqi_1"
7974 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7975 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7976 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7977 (clobber (reg:CC FLAGS_REG))]
7978 "ix86_binary_operator_ok (AND, QImode, operands)"
7979 "@
7980 and{b}\t{%2, %0|%0, %2}
7981 and{b}\t{%2, %0|%0, %2}
7982 and{l}\t{%k2, %k0|%k0, %k2}"
7983 [(set_attr "type" "alu")
7984 (set_attr "mode" "QI,QI,SI")])
7985
7986 (define_insn "*andqi_1_slp"
7987 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7988 (and:QI (match_dup 0)
7989 (match_operand:QI 1 "general_operand" "qn,qmn")))
7990 (clobber (reg:CC FLAGS_REG))]
7991 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7992 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7993 "and{b}\t{%1, %0|%0, %1}"
7994 [(set_attr "type" "alu1")
7995 (set_attr "mode" "QI")])
7996
7997 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7998 (define_split
7999 [(set (match_operand:DI 0 "register_operand")
8000 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8001 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8002 (clobber (reg:CC FLAGS_REG))]
8003 "TARGET_64BIT"
8004 [(parallel [(set (match_dup 0)
8005 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8006 (clobber (reg:CC FLAGS_REG))])]
8007 "operands[2] = gen_lowpart (SImode, operands[2]);")
8008
8009 (define_split
8010 [(set (match_operand:SWI248 0 "register_operand")
8011 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8012 (match_operand:SWI248 2 "const_int_operand")))
8013 (clobber (reg:CC FLAGS_REG))]
8014 "reload_completed
8015 && true_regnum (operands[0]) != true_regnum (operands[1])"
8016 [(const_int 0)]
8017 {
8018 HOST_WIDE_INT ival = INTVAL (operands[2]);
8019 enum machine_mode mode;
8020 rtx (*insn) (rtx, rtx);
8021
8022 if (ival == (HOST_WIDE_INT) 0xffffffff)
8023 mode = SImode;
8024 else if (ival == 0xffff)
8025 mode = HImode;
8026 else
8027 {
8028 gcc_assert (ival == 0xff);
8029 mode = QImode;
8030 }
8031
8032 if (<MODE>mode == DImode)
8033 insn = (mode == SImode)
8034 ? gen_zero_extendsidi2
8035 : (mode == HImode)
8036 ? gen_zero_extendhidi2
8037 : gen_zero_extendqidi2;
8038 else
8039 {
8040 if (<MODE>mode != SImode)
8041 /* Zero extend to SImode to avoid partial register stalls. */
8042 operands[0] = gen_lowpart (SImode, operands[0]);
8043
8044 insn = (mode == HImode)
8045 ? gen_zero_extendhisi2
8046 : gen_zero_extendqisi2;
8047 }
8048 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8049 DONE;
8050 })
8051
8052 (define_split
8053 [(set (match_operand 0 "register_operand")
8054 (and (match_dup 0)
8055 (const_int -65536)))
8056 (clobber (reg:CC FLAGS_REG))]
8057 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8058 || optimize_function_for_size_p (cfun)"
8059 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8060 "operands[1] = gen_lowpart (HImode, operands[0]);")
8061
8062 (define_split
8063 [(set (match_operand 0 "ext_register_operand")
8064 (and (match_dup 0)
8065 (const_int -256)))
8066 (clobber (reg:CC FLAGS_REG))]
8067 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8068 && reload_completed"
8069 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8070 "operands[1] = gen_lowpart (QImode, operands[0]);")
8071
8072 (define_split
8073 [(set (match_operand 0 "ext_register_operand")
8074 (and (match_dup 0)
8075 (const_int -65281)))
8076 (clobber (reg:CC FLAGS_REG))]
8077 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8078 && reload_completed"
8079 [(parallel [(set (zero_extract:SI (match_dup 0)
8080 (const_int 8)
8081 (const_int 8))
8082 (xor:SI
8083 (zero_extract:SI (match_dup 0)
8084 (const_int 8)
8085 (const_int 8))
8086 (zero_extract:SI (match_dup 0)
8087 (const_int 8)
8088 (const_int 8))))
8089 (clobber (reg:CC FLAGS_REG))])]
8090 "operands[0] = gen_lowpart (SImode, operands[0]);")
8091
8092 (define_insn "*anddi_2"
8093 [(set (reg FLAGS_REG)
8094 (compare
8095 (and:DI
8096 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8097 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8098 (const_int 0)))
8099 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8100 (and:DI (match_dup 1) (match_dup 2)))]
8101 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8102 && ix86_binary_operator_ok (AND, DImode, operands)"
8103 "@
8104 and{l}\t{%k2, %k0|%k0, %k2}
8105 and{q}\t{%2, %0|%0, %2}
8106 and{q}\t{%2, %0|%0, %2}"
8107 [(set_attr "type" "alu")
8108 (set_attr "mode" "SI,DI,DI")])
8109
8110 (define_insn "*andqi_2_maybe_si"
8111 [(set (reg FLAGS_REG)
8112 (compare (and:QI
8113 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8114 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8115 (const_int 0)))
8116 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8117 (and:QI (match_dup 1) (match_dup 2)))]
8118 "ix86_binary_operator_ok (AND, QImode, operands)
8119 && ix86_match_ccmode (insn,
8120 CONST_INT_P (operands[2])
8121 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8122 {
8123 if (which_alternative == 2)
8124 {
8125 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8126 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8127 return "and{l}\t{%2, %k0|%k0, %2}";
8128 }
8129 return "and{b}\t{%2, %0|%0, %2}";
8130 }
8131 [(set_attr "type" "alu")
8132 (set_attr "mode" "QI,QI,SI")])
8133
8134 (define_insn "*and<mode>_2"
8135 [(set (reg FLAGS_REG)
8136 (compare (and:SWI124
8137 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8138 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8139 (const_int 0)))
8140 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8141 (and:SWI124 (match_dup 1) (match_dup 2)))]
8142 "ix86_match_ccmode (insn, CCNOmode)
8143 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8144 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8145 [(set_attr "type" "alu")
8146 (set_attr "mode" "<MODE>")])
8147
8148 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8149 (define_insn "*andsi_2_zext"
8150 [(set (reg FLAGS_REG)
8151 (compare (and:SI
8152 (match_operand:SI 1 "nonimmediate_operand" "%0")
8153 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8154 (const_int 0)))
8155 (set (match_operand:DI 0 "register_operand" "=r")
8156 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8157 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8158 && ix86_binary_operator_ok (AND, SImode, operands)"
8159 "and{l}\t{%2, %k0|%k0, %2}"
8160 [(set_attr "type" "alu")
8161 (set_attr "mode" "SI")])
8162
8163 (define_insn "*andqi_2_slp"
8164 [(set (reg FLAGS_REG)
8165 (compare (and:QI
8166 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8167 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8168 (const_int 0)))
8169 (set (strict_low_part (match_dup 0))
8170 (and:QI (match_dup 0) (match_dup 1)))]
8171 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8172 && ix86_match_ccmode (insn, CCNOmode)
8173 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8174 "and{b}\t{%1, %0|%0, %1}"
8175 [(set_attr "type" "alu1")
8176 (set_attr "mode" "QI")])
8177
8178 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8179 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8180 ;; for a QImode operand, which of course failed.
8181 (define_insn "andqi_ext_0"
8182 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8183 (const_int 8)
8184 (const_int 8))
8185 (and:SI
8186 (zero_extract:SI
8187 (match_operand 1 "ext_register_operand" "0")
8188 (const_int 8)
8189 (const_int 8))
8190 (match_operand 2 "const_int_operand" "n")))
8191 (clobber (reg:CC FLAGS_REG))]
8192 ""
8193 "and{b}\t{%2, %h0|%h0, %2}"
8194 [(set_attr "type" "alu")
8195 (set_attr "length_immediate" "1")
8196 (set_attr "modrm" "1")
8197 (set_attr "mode" "QI")])
8198
8199 ;; Generated by peephole translating test to and. This shows up
8200 ;; often in fp comparisons.
8201 (define_insn "*andqi_ext_0_cc"
8202 [(set (reg FLAGS_REG)
8203 (compare
8204 (and:SI
8205 (zero_extract:SI
8206 (match_operand 1 "ext_register_operand" "0")
8207 (const_int 8)
8208 (const_int 8))
8209 (match_operand 2 "const_int_operand" "n"))
8210 (const_int 0)))
8211 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8212 (const_int 8)
8213 (const_int 8))
8214 (and:SI
8215 (zero_extract:SI
8216 (match_dup 1)
8217 (const_int 8)
8218 (const_int 8))
8219 (match_dup 2)))]
8220 "ix86_match_ccmode (insn, CCNOmode)"
8221 "and{b}\t{%2, %h0|%h0, %2}"
8222 [(set_attr "type" "alu")
8223 (set_attr "length_immediate" "1")
8224 (set_attr "modrm" "1")
8225 (set_attr "mode" "QI")])
8226
8227 (define_insn "*andqi_ext_1_rex64"
8228 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8229 (const_int 8)
8230 (const_int 8))
8231 (and:SI
8232 (zero_extract:SI
8233 (match_operand 1 "ext_register_operand" "0")
8234 (const_int 8)
8235 (const_int 8))
8236 (zero_extend:SI
8237 (match_operand 2 "ext_register_operand" "Q"))))
8238 (clobber (reg:CC FLAGS_REG))]
8239 "TARGET_64BIT"
8240 "and{b}\t{%2, %h0|%h0, %2}"
8241 [(set_attr "type" "alu")
8242 (set_attr "length_immediate" "0")
8243 (set_attr "mode" "QI")])
8244
8245 (define_insn "*andqi_ext_1"
8246 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8247 (const_int 8)
8248 (const_int 8))
8249 (and:SI
8250 (zero_extract:SI
8251 (match_operand 1 "ext_register_operand" "0")
8252 (const_int 8)
8253 (const_int 8))
8254 (zero_extend:SI
8255 (match_operand:QI 2 "general_operand" "Qm"))))
8256 (clobber (reg:CC FLAGS_REG))]
8257 "!TARGET_64BIT"
8258 "and{b}\t{%2, %h0|%h0, %2}"
8259 [(set_attr "type" "alu")
8260 (set_attr "length_immediate" "0")
8261 (set_attr "mode" "QI")])
8262
8263 (define_insn "*andqi_ext_2"
8264 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8265 (const_int 8)
8266 (const_int 8))
8267 (and:SI
8268 (zero_extract:SI
8269 (match_operand 1 "ext_register_operand" "%0")
8270 (const_int 8)
8271 (const_int 8))
8272 (zero_extract:SI
8273 (match_operand 2 "ext_register_operand" "Q")
8274 (const_int 8)
8275 (const_int 8))))
8276 (clobber (reg:CC FLAGS_REG))]
8277 ""
8278 "and{b}\t{%h2, %h0|%h0, %h2}"
8279 [(set_attr "type" "alu")
8280 (set_attr "length_immediate" "0")
8281 (set_attr "mode" "QI")])
8282
8283 ;; Convert wide AND instructions with immediate operand to shorter QImode
8284 ;; equivalents when possible.
8285 ;; Don't do the splitting with memory operands, since it introduces risk
8286 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8287 ;; for size, but that can (should?) be handled by generic code instead.
8288 (define_split
8289 [(set (match_operand 0 "register_operand")
8290 (and (match_operand 1 "register_operand")
8291 (match_operand 2 "const_int_operand")))
8292 (clobber (reg:CC FLAGS_REG))]
8293 "reload_completed
8294 && QI_REG_P (operands[0])
8295 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8296 && !(~INTVAL (operands[2]) & ~(255 << 8))
8297 && GET_MODE (operands[0]) != QImode"
8298 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8299 (and:SI (zero_extract:SI (match_dup 1)
8300 (const_int 8) (const_int 8))
8301 (match_dup 2)))
8302 (clobber (reg:CC FLAGS_REG))])]
8303 {
8304 operands[0] = gen_lowpart (SImode, operands[0]);
8305 operands[1] = gen_lowpart (SImode, operands[1]);
8306 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8307 })
8308
8309 ;; Since AND can be encoded with sign extended immediate, this is only
8310 ;; profitable when 7th bit is not set.
8311 (define_split
8312 [(set (match_operand 0 "register_operand")
8313 (and (match_operand 1 "general_operand")
8314 (match_operand 2 "const_int_operand")))
8315 (clobber (reg:CC FLAGS_REG))]
8316 "reload_completed
8317 && ANY_QI_REG_P (operands[0])
8318 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8319 && !(~INTVAL (operands[2]) & ~255)
8320 && !(INTVAL (operands[2]) & 128)
8321 && GET_MODE (operands[0]) != QImode"
8322 [(parallel [(set (strict_low_part (match_dup 0))
8323 (and:QI (match_dup 1)
8324 (match_dup 2)))
8325 (clobber (reg:CC FLAGS_REG))])]
8326 {
8327 operands[0] = gen_lowpart (QImode, operands[0]);
8328 operands[1] = gen_lowpart (QImode, operands[1]);
8329 operands[2] = gen_lowpart (QImode, operands[2]);
8330 })
8331 \f
8332 ;; Logical inclusive and exclusive OR instructions
8333
8334 ;; %%% This used to optimize known byte-wide and operations to memory.
8335 ;; If this is considered useful, it should be done with splitters.
8336
8337 (define_expand "<code><mode>3"
8338 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8339 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8340 (match_operand:SWIM 2 "<general_operand>")))]
8341 ""
8342 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8343
8344 (define_insn "*<code><mode>_1"
8345 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8346 (any_or:SWI248
8347 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8348 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8349 (clobber (reg:CC FLAGS_REG))]
8350 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8351 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8352 [(set_attr "type" "alu")
8353 (set_attr "mode" "<MODE>")])
8354
8355 ;; %%% Potential partial reg stall on alternative 2. What to do?
8356 (define_insn "*<code>qi_1"
8357 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8358 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8359 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8360 (clobber (reg:CC FLAGS_REG))]
8361 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8362 "@
8363 <logic>{b}\t{%2, %0|%0, %2}
8364 <logic>{b}\t{%2, %0|%0, %2}
8365 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8366 [(set_attr "type" "alu")
8367 (set_attr "mode" "QI,QI,SI")])
8368
8369 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8370 (define_insn "*<code>si_1_zext"
8371 [(set (match_operand:DI 0 "register_operand" "=r")
8372 (zero_extend:DI
8373 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8374 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8375 (clobber (reg:CC FLAGS_REG))]
8376 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8377 "<logic>{l}\t{%2, %k0|%k0, %2}"
8378 [(set_attr "type" "alu")
8379 (set_attr "mode" "SI")])
8380
8381 (define_insn "*<code>si_1_zext_imm"
8382 [(set (match_operand:DI 0 "register_operand" "=r")
8383 (any_or:DI
8384 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8385 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8386 (clobber (reg:CC FLAGS_REG))]
8387 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8388 "<logic>{l}\t{%2, %k0|%k0, %2}"
8389 [(set_attr "type" "alu")
8390 (set_attr "mode" "SI")])
8391
8392 (define_insn "*<code>qi_1_slp"
8393 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8394 (any_or:QI (match_dup 0)
8395 (match_operand:QI 1 "general_operand" "qmn,qn")))
8396 (clobber (reg:CC FLAGS_REG))]
8397 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8398 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8399 "<logic>{b}\t{%1, %0|%0, %1}"
8400 [(set_attr "type" "alu1")
8401 (set_attr "mode" "QI")])
8402
8403 (define_insn "*<code><mode>_2"
8404 [(set (reg FLAGS_REG)
8405 (compare (any_or:SWI
8406 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8407 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8408 (const_int 0)))
8409 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8410 (any_or:SWI (match_dup 1) (match_dup 2)))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8413 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "<MODE>")])
8416
8417 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8418 ;; ??? Special case for immediate operand is missing - it is tricky.
8419 (define_insn "*<code>si_2_zext"
8420 [(set (reg FLAGS_REG)
8421 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8422 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8423 (const_int 0)))
8424 (set (match_operand:DI 0 "register_operand" "=r")
8425 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8426 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8427 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8428 "<logic>{l}\t{%2, %k0|%k0, %2}"
8429 [(set_attr "type" "alu")
8430 (set_attr "mode" "SI")])
8431
8432 (define_insn "*<code>si_2_zext_imm"
8433 [(set (reg FLAGS_REG)
8434 (compare (any_or:SI
8435 (match_operand:SI 1 "nonimmediate_operand" "%0")
8436 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8437 (const_int 0)))
8438 (set (match_operand:DI 0 "register_operand" "=r")
8439 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8440 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8441 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8442 "<logic>{l}\t{%2, %k0|%k0, %2}"
8443 [(set_attr "type" "alu")
8444 (set_attr "mode" "SI")])
8445
8446 (define_insn "*<code>qi_2_slp"
8447 [(set (reg FLAGS_REG)
8448 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8449 (match_operand:QI 1 "general_operand" "qmn,qn"))
8450 (const_int 0)))
8451 (set (strict_low_part (match_dup 0))
8452 (any_or:QI (match_dup 0) (match_dup 1)))]
8453 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8454 && ix86_match_ccmode (insn, CCNOmode)
8455 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8456 "<logic>{b}\t{%1, %0|%0, %1}"
8457 [(set_attr "type" "alu1")
8458 (set_attr "mode" "QI")])
8459
8460 (define_insn "*<code><mode>_3"
8461 [(set (reg FLAGS_REG)
8462 (compare (any_or:SWI
8463 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8464 (match_operand:SWI 2 "<general_operand>" "<g>"))
8465 (const_int 0)))
8466 (clobber (match_scratch:SWI 0 "=<r>"))]
8467 "ix86_match_ccmode (insn, CCNOmode)
8468 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8469 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8470 [(set_attr "type" "alu")
8471 (set_attr "mode" "<MODE>")])
8472
8473 (define_insn "*<code>qi_ext_0"
8474 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8475 (const_int 8)
8476 (const_int 8))
8477 (any_or:SI
8478 (zero_extract:SI
8479 (match_operand 1 "ext_register_operand" "0")
8480 (const_int 8)
8481 (const_int 8))
8482 (match_operand 2 "const_int_operand" "n")))
8483 (clobber (reg:CC FLAGS_REG))]
8484 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8485 "<logic>{b}\t{%2, %h0|%h0, %2}"
8486 [(set_attr "type" "alu")
8487 (set_attr "length_immediate" "1")
8488 (set_attr "modrm" "1")
8489 (set_attr "mode" "QI")])
8490
8491 (define_insn "*<code>qi_ext_1_rex64"
8492 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8493 (const_int 8)
8494 (const_int 8))
8495 (any_or:SI
8496 (zero_extract:SI
8497 (match_operand 1 "ext_register_operand" "0")
8498 (const_int 8)
8499 (const_int 8))
8500 (zero_extend:SI
8501 (match_operand 2 "ext_register_operand" "Q"))))
8502 (clobber (reg:CC FLAGS_REG))]
8503 "TARGET_64BIT
8504 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8505 "<logic>{b}\t{%2, %h0|%h0, %2}"
8506 [(set_attr "type" "alu")
8507 (set_attr "length_immediate" "0")
8508 (set_attr "mode" "QI")])
8509
8510 (define_insn "*<code>qi_ext_1"
8511 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8512 (const_int 8)
8513 (const_int 8))
8514 (any_or:SI
8515 (zero_extract:SI
8516 (match_operand 1 "ext_register_operand" "0")
8517 (const_int 8)
8518 (const_int 8))
8519 (zero_extend:SI
8520 (match_operand:QI 2 "general_operand" "Qm"))))
8521 (clobber (reg:CC FLAGS_REG))]
8522 "!TARGET_64BIT
8523 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8524 "<logic>{b}\t{%2, %h0|%h0, %2}"
8525 [(set_attr "type" "alu")
8526 (set_attr "length_immediate" "0")
8527 (set_attr "mode" "QI")])
8528
8529 (define_insn "*<code>qi_ext_2"
8530 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8531 (const_int 8)
8532 (const_int 8))
8533 (any_or:SI
8534 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8535 (const_int 8)
8536 (const_int 8))
8537 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8538 (const_int 8)
8539 (const_int 8))))
8540 (clobber (reg:CC FLAGS_REG))]
8541 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8542 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8543 [(set_attr "type" "alu")
8544 (set_attr "length_immediate" "0")
8545 (set_attr "mode" "QI")])
8546
8547 (define_split
8548 [(set (match_operand 0 "register_operand")
8549 (any_or (match_operand 1 "register_operand")
8550 (match_operand 2 "const_int_operand")))
8551 (clobber (reg:CC FLAGS_REG))]
8552 "reload_completed
8553 && QI_REG_P (operands[0])
8554 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8555 && !(INTVAL (operands[2]) & ~(255 << 8))
8556 && GET_MODE (operands[0]) != QImode"
8557 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8558 (any_or:SI (zero_extract:SI (match_dup 1)
8559 (const_int 8) (const_int 8))
8560 (match_dup 2)))
8561 (clobber (reg:CC FLAGS_REG))])]
8562 {
8563 operands[0] = gen_lowpart (SImode, operands[0]);
8564 operands[1] = gen_lowpart (SImode, operands[1]);
8565 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8566 })
8567
8568 ;; Since OR can be encoded with sign extended immediate, this is only
8569 ;; profitable when 7th bit is set.
8570 (define_split
8571 [(set (match_operand 0 "register_operand")
8572 (any_or (match_operand 1 "general_operand")
8573 (match_operand 2 "const_int_operand")))
8574 (clobber (reg:CC FLAGS_REG))]
8575 "reload_completed
8576 && ANY_QI_REG_P (operands[0])
8577 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8578 && !(INTVAL (operands[2]) & ~255)
8579 && (INTVAL (operands[2]) & 128)
8580 && GET_MODE (operands[0]) != QImode"
8581 [(parallel [(set (strict_low_part (match_dup 0))
8582 (any_or:QI (match_dup 1)
8583 (match_dup 2)))
8584 (clobber (reg:CC FLAGS_REG))])]
8585 {
8586 operands[0] = gen_lowpart (QImode, operands[0]);
8587 operands[1] = gen_lowpart (QImode, operands[1]);
8588 operands[2] = gen_lowpart (QImode, operands[2]);
8589 })
8590
8591 (define_expand "xorqi_cc_ext_1"
8592 [(parallel [
8593 (set (reg:CCNO FLAGS_REG)
8594 (compare:CCNO
8595 (xor:SI
8596 (zero_extract:SI
8597 (match_operand 1 "ext_register_operand")
8598 (const_int 8)
8599 (const_int 8))
8600 (match_operand:QI 2 "general_operand"))
8601 (const_int 0)))
8602 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8603 (const_int 8)
8604 (const_int 8))
8605 (xor:SI
8606 (zero_extract:SI
8607 (match_dup 1)
8608 (const_int 8)
8609 (const_int 8))
8610 (match_dup 2)))])])
8611
8612 (define_insn "*xorqi_cc_ext_1_rex64"
8613 [(set (reg FLAGS_REG)
8614 (compare
8615 (xor:SI
8616 (zero_extract:SI
8617 (match_operand 1 "ext_register_operand" "0")
8618 (const_int 8)
8619 (const_int 8))
8620 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8621 (const_int 0)))
8622 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8623 (const_int 8)
8624 (const_int 8))
8625 (xor:SI
8626 (zero_extract:SI
8627 (match_dup 1)
8628 (const_int 8)
8629 (const_int 8))
8630 (match_dup 2)))]
8631 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8632 "xor{b}\t{%2, %h0|%h0, %2}"
8633 [(set_attr "type" "alu")
8634 (set_attr "modrm" "1")
8635 (set_attr "mode" "QI")])
8636
8637 (define_insn "*xorqi_cc_ext_1"
8638 [(set (reg FLAGS_REG)
8639 (compare
8640 (xor:SI
8641 (zero_extract:SI
8642 (match_operand 1 "ext_register_operand" "0")
8643 (const_int 8)
8644 (const_int 8))
8645 (match_operand:QI 2 "general_operand" "qmn"))
8646 (const_int 0)))
8647 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8648 (const_int 8)
8649 (const_int 8))
8650 (xor:SI
8651 (zero_extract:SI
8652 (match_dup 1)
8653 (const_int 8)
8654 (const_int 8))
8655 (match_dup 2)))]
8656 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8657 "xor{b}\t{%2, %h0|%h0, %2}"
8658 [(set_attr "type" "alu")
8659 (set_attr "modrm" "1")
8660 (set_attr "mode" "QI")])
8661 \f
8662 ;; Negation instructions
8663
8664 (define_expand "neg<mode>2"
8665 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8666 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8667 ""
8668 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8669
8670 (define_insn_and_split "*neg<dwi>2_doubleword"
8671 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8672 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8673 (clobber (reg:CC FLAGS_REG))]
8674 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8675 "#"
8676 "reload_completed"
8677 [(parallel
8678 [(set (reg:CCZ FLAGS_REG)
8679 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8680 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8681 (parallel
8682 [(set (match_dup 2)
8683 (plus:DWIH (match_dup 3)
8684 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8685 (const_int 0))))
8686 (clobber (reg:CC FLAGS_REG))])
8687 (parallel
8688 [(set (match_dup 2)
8689 (neg:DWIH (match_dup 2)))
8690 (clobber (reg:CC FLAGS_REG))])]
8691 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8692
8693 (define_insn "*neg<mode>2_1"
8694 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8695 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8698 "neg{<imodesuffix>}\t%0"
8699 [(set_attr "type" "negnot")
8700 (set_attr "mode" "<MODE>")])
8701
8702 ;; Combine is quite creative about this pattern.
8703 (define_insn "*negsi2_1_zext"
8704 [(set (match_operand:DI 0 "register_operand" "=r")
8705 (lshiftrt:DI
8706 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8707 (const_int 32)))
8708 (const_int 32)))
8709 (clobber (reg:CC FLAGS_REG))]
8710 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8711 "neg{l}\t%k0"
8712 [(set_attr "type" "negnot")
8713 (set_attr "mode" "SI")])
8714
8715 ;; The problem with neg is that it does not perform (compare x 0),
8716 ;; it really performs (compare 0 x), which leaves us with the zero
8717 ;; flag being the only useful item.
8718
8719 (define_insn "*neg<mode>2_cmpz"
8720 [(set (reg:CCZ FLAGS_REG)
8721 (compare:CCZ
8722 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8723 (const_int 0)))
8724 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8725 (neg:SWI (match_dup 1)))]
8726 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8727 "neg{<imodesuffix>}\t%0"
8728 [(set_attr "type" "negnot")
8729 (set_attr "mode" "<MODE>")])
8730
8731 (define_insn "*negsi2_cmpz_zext"
8732 [(set (reg:CCZ FLAGS_REG)
8733 (compare:CCZ
8734 (lshiftrt:DI
8735 (neg:DI (ashift:DI
8736 (match_operand:DI 1 "register_operand" "0")
8737 (const_int 32)))
8738 (const_int 32))
8739 (const_int 0)))
8740 (set (match_operand:DI 0 "register_operand" "=r")
8741 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8742 (const_int 32)))
8743 (const_int 32)))]
8744 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8745 "neg{l}\t%k0"
8746 [(set_attr "type" "negnot")
8747 (set_attr "mode" "SI")])
8748
8749 ;; Changing of sign for FP values is doable using integer unit too.
8750
8751 (define_expand "<code><mode>2"
8752 [(set (match_operand:X87MODEF 0 "register_operand")
8753 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8754 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8755 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8756
8757 (define_insn "*absneg<mode>2_mixed"
8758 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8759 (match_operator:MODEF 3 "absneg_operator"
8760 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8761 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8762 (clobber (reg:CC FLAGS_REG))]
8763 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8764 "#")
8765
8766 (define_insn "*absneg<mode>2_sse"
8767 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8768 (match_operator:MODEF 3 "absneg_operator"
8769 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8770 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8771 (clobber (reg:CC FLAGS_REG))]
8772 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8773 "#")
8774
8775 (define_insn "*absneg<mode>2_i387"
8776 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8777 (match_operator:X87MODEF 3 "absneg_operator"
8778 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8779 (use (match_operand 2))
8780 (clobber (reg:CC FLAGS_REG))]
8781 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8782 "#")
8783
8784 (define_expand "<code>tf2"
8785 [(set (match_operand:TF 0 "register_operand")
8786 (absneg:TF (match_operand:TF 1 "register_operand")))]
8787 "TARGET_SSE"
8788 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8789
8790 (define_insn "*absnegtf2_sse"
8791 [(set (match_operand:TF 0 "register_operand" "=x,x")
8792 (match_operator:TF 3 "absneg_operator"
8793 [(match_operand:TF 1 "register_operand" "0,x")]))
8794 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8795 (clobber (reg:CC FLAGS_REG))]
8796 "TARGET_SSE"
8797 "#")
8798
8799 ;; Splitters for fp abs and neg.
8800
8801 (define_split
8802 [(set (match_operand 0 "fp_register_operand")
8803 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8804 (use (match_operand 2))
8805 (clobber (reg:CC FLAGS_REG))]
8806 "reload_completed"
8807 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8808
8809 (define_split
8810 [(set (match_operand 0 "register_operand")
8811 (match_operator 3 "absneg_operator"
8812 [(match_operand 1 "register_operand")]))
8813 (use (match_operand 2 "nonimmediate_operand"))
8814 (clobber (reg:CC FLAGS_REG))]
8815 "reload_completed && SSE_REG_P (operands[0])"
8816 [(set (match_dup 0) (match_dup 3))]
8817 {
8818 enum machine_mode mode = GET_MODE (operands[0]);
8819 enum machine_mode vmode = GET_MODE (operands[2]);
8820 rtx tmp;
8821
8822 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8823 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8824 if (operands_match_p (operands[0], operands[2]))
8825 {
8826 tmp = operands[1];
8827 operands[1] = operands[2];
8828 operands[2] = tmp;
8829 }
8830 if (GET_CODE (operands[3]) == ABS)
8831 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8832 else
8833 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8834 operands[3] = tmp;
8835 })
8836
8837 (define_split
8838 [(set (match_operand:SF 0 "register_operand")
8839 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8840 (use (match_operand:V4SF 2))
8841 (clobber (reg:CC FLAGS_REG))]
8842 "reload_completed"
8843 [(parallel [(set (match_dup 0) (match_dup 1))
8844 (clobber (reg:CC FLAGS_REG))])]
8845 {
8846 rtx tmp;
8847 operands[0] = gen_lowpart (SImode, operands[0]);
8848 if (GET_CODE (operands[1]) == ABS)
8849 {
8850 tmp = gen_int_mode (0x7fffffff, SImode);
8851 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8852 }
8853 else
8854 {
8855 tmp = gen_int_mode (0x80000000, SImode);
8856 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8857 }
8858 operands[1] = tmp;
8859 })
8860
8861 (define_split
8862 [(set (match_operand:DF 0 "register_operand")
8863 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8864 (use (match_operand 2))
8865 (clobber (reg:CC FLAGS_REG))]
8866 "reload_completed"
8867 [(parallel [(set (match_dup 0) (match_dup 1))
8868 (clobber (reg:CC FLAGS_REG))])]
8869 {
8870 rtx tmp;
8871 if (TARGET_64BIT)
8872 {
8873 tmp = gen_lowpart (DImode, operands[0]);
8874 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8875 operands[0] = tmp;
8876
8877 if (GET_CODE (operands[1]) == ABS)
8878 tmp = const0_rtx;
8879 else
8880 tmp = gen_rtx_NOT (DImode, tmp);
8881 }
8882 else
8883 {
8884 operands[0] = gen_highpart (SImode, operands[0]);
8885 if (GET_CODE (operands[1]) == ABS)
8886 {
8887 tmp = gen_int_mode (0x7fffffff, SImode);
8888 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8889 }
8890 else
8891 {
8892 tmp = gen_int_mode (0x80000000, SImode);
8893 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8894 }
8895 }
8896 operands[1] = tmp;
8897 })
8898
8899 (define_split
8900 [(set (match_operand:XF 0 "register_operand")
8901 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8902 (use (match_operand 2))
8903 (clobber (reg:CC FLAGS_REG))]
8904 "reload_completed"
8905 [(parallel [(set (match_dup 0) (match_dup 1))
8906 (clobber (reg:CC FLAGS_REG))])]
8907 {
8908 rtx tmp;
8909 operands[0] = gen_rtx_REG (SImode,
8910 true_regnum (operands[0])
8911 + (TARGET_64BIT ? 1 : 2));
8912 if (GET_CODE (operands[1]) == ABS)
8913 {
8914 tmp = GEN_INT (0x7fff);
8915 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8916 }
8917 else
8918 {
8919 tmp = GEN_INT (0x8000);
8920 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8921 }
8922 operands[1] = tmp;
8923 })
8924
8925 ;; Conditionalize these after reload. If they match before reload, we
8926 ;; lose the clobber and ability to use integer instructions.
8927
8928 (define_insn "*<code><mode>2_1"
8929 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8930 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8931 "TARGET_80387
8932 && (reload_completed
8933 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8934 "f<absneg_mnemonic>"
8935 [(set_attr "type" "fsgn")
8936 (set_attr "mode" "<MODE>")])
8937
8938 (define_insn "*<code>extendsfdf2"
8939 [(set (match_operand:DF 0 "register_operand" "=f")
8940 (absneg:DF (float_extend:DF
8941 (match_operand:SF 1 "register_operand" "0"))))]
8942 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8943 "f<absneg_mnemonic>"
8944 [(set_attr "type" "fsgn")
8945 (set_attr "mode" "DF")])
8946
8947 (define_insn "*<code>extendsfxf2"
8948 [(set (match_operand:XF 0 "register_operand" "=f")
8949 (absneg:XF (float_extend:XF
8950 (match_operand:SF 1 "register_operand" "0"))))]
8951 "TARGET_80387"
8952 "f<absneg_mnemonic>"
8953 [(set_attr "type" "fsgn")
8954 (set_attr "mode" "XF")])
8955
8956 (define_insn "*<code>extenddfxf2"
8957 [(set (match_operand:XF 0 "register_operand" "=f")
8958 (absneg:XF (float_extend:XF
8959 (match_operand:DF 1 "register_operand" "0"))))]
8960 "TARGET_80387"
8961 "f<absneg_mnemonic>"
8962 [(set_attr "type" "fsgn")
8963 (set_attr "mode" "XF")])
8964
8965 ;; Copysign instructions
8966
8967 (define_mode_iterator CSGNMODE [SF DF TF])
8968 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8969
8970 (define_expand "copysign<mode>3"
8971 [(match_operand:CSGNMODE 0 "register_operand")
8972 (match_operand:CSGNMODE 1 "nonmemory_operand")
8973 (match_operand:CSGNMODE 2 "register_operand")]
8974 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8975 || (TARGET_SSE && (<MODE>mode == TFmode))"
8976 "ix86_expand_copysign (operands); DONE;")
8977
8978 (define_insn_and_split "copysign<mode>3_const"
8979 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8980 (unspec:CSGNMODE
8981 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8982 (match_operand:CSGNMODE 2 "register_operand" "0")
8983 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8984 UNSPEC_COPYSIGN))]
8985 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8986 || (TARGET_SSE && (<MODE>mode == TFmode))"
8987 "#"
8988 "&& reload_completed"
8989 [(const_int 0)]
8990 "ix86_split_copysign_const (operands); DONE;")
8991
8992 (define_insn "copysign<mode>3_var"
8993 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8994 (unspec:CSGNMODE
8995 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8996 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8997 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8998 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8999 UNSPEC_COPYSIGN))
9000 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9001 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9002 || (TARGET_SSE && (<MODE>mode == TFmode))"
9003 "#")
9004
9005 (define_split
9006 [(set (match_operand:CSGNMODE 0 "register_operand")
9007 (unspec:CSGNMODE
9008 [(match_operand:CSGNMODE 2 "register_operand")
9009 (match_operand:CSGNMODE 3 "register_operand")
9010 (match_operand:<CSGNVMODE> 4)
9011 (match_operand:<CSGNVMODE> 5)]
9012 UNSPEC_COPYSIGN))
9013 (clobber (match_scratch:<CSGNVMODE> 1))]
9014 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9015 || (TARGET_SSE && (<MODE>mode == TFmode)))
9016 && reload_completed"
9017 [(const_int 0)]
9018 "ix86_split_copysign_var (operands); DONE;")
9019 \f
9020 ;; One complement instructions
9021
9022 (define_expand "one_cmpl<mode>2"
9023 [(set (match_operand:SWIM 0 "nonimmediate_operand")
9024 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9025 ""
9026 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9027
9028 (define_insn "*one_cmpl<mode>2_1"
9029 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9030 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9031 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9032 "not{<imodesuffix>}\t%0"
9033 [(set_attr "type" "negnot")
9034 (set_attr "mode" "<MODE>")])
9035
9036 ;; %%% Potential partial reg stall on alternative 1. What to do?
9037 (define_insn "*one_cmplqi2_1"
9038 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9039 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9040 "ix86_unary_operator_ok (NOT, QImode, operands)"
9041 "@
9042 not{b}\t%0
9043 not{l}\t%k0"
9044 [(set_attr "type" "negnot")
9045 (set_attr "mode" "QI,SI")])
9046
9047 ;; ??? Currently never generated - xor is used instead.
9048 (define_insn "*one_cmplsi2_1_zext"
9049 [(set (match_operand:DI 0 "register_operand" "=r")
9050 (zero_extend:DI
9051 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9052 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9053 "not{l}\t%k0"
9054 [(set_attr "type" "negnot")
9055 (set_attr "mode" "SI")])
9056
9057 (define_insn "*one_cmpl<mode>2_2"
9058 [(set (reg FLAGS_REG)
9059 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9060 (const_int 0)))
9061 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9062 (not:SWI (match_dup 1)))]
9063 "ix86_match_ccmode (insn, CCNOmode)
9064 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9065 "#"
9066 [(set_attr "type" "alu1")
9067 (set_attr "mode" "<MODE>")])
9068
9069 (define_split
9070 [(set (match_operand 0 "flags_reg_operand")
9071 (match_operator 2 "compare_operator"
9072 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9073 (const_int 0)]))
9074 (set (match_operand:SWI 1 "nonimmediate_operand")
9075 (not:SWI (match_dup 3)))]
9076 "ix86_match_ccmode (insn, CCNOmode)"
9077 [(parallel [(set (match_dup 0)
9078 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9079 (const_int 0)]))
9080 (set (match_dup 1)
9081 (xor:SWI (match_dup 3) (const_int -1)))])])
9082
9083 ;; ??? Currently never generated - xor is used instead.
9084 (define_insn "*one_cmplsi2_2_zext"
9085 [(set (reg FLAGS_REG)
9086 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9087 (const_int 0)))
9088 (set (match_operand:DI 0 "register_operand" "=r")
9089 (zero_extend:DI (not:SI (match_dup 1))))]
9090 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9091 && ix86_unary_operator_ok (NOT, SImode, operands)"
9092 "#"
9093 [(set_attr "type" "alu1")
9094 (set_attr "mode" "SI")])
9095
9096 (define_split
9097 [(set (match_operand 0 "flags_reg_operand")
9098 (match_operator 2 "compare_operator"
9099 [(not:SI (match_operand:SI 3 "register_operand"))
9100 (const_int 0)]))
9101 (set (match_operand:DI 1 "register_operand")
9102 (zero_extend:DI (not:SI (match_dup 3))))]
9103 "ix86_match_ccmode (insn, CCNOmode)"
9104 [(parallel [(set (match_dup 0)
9105 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9106 (const_int 0)]))
9107 (set (match_dup 1)
9108 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9109 \f
9110 ;; Shift instructions
9111
9112 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9113 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9114 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9115 ;; from the assembler input.
9116 ;;
9117 ;; This instruction shifts the target reg/mem as usual, but instead of
9118 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9119 ;; is a left shift double, bits are taken from the high order bits of
9120 ;; reg, else if the insn is a shift right double, bits are taken from the
9121 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9122 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9123 ;;
9124 ;; Since sh[lr]d does not change the `reg' operand, that is done
9125 ;; separately, making all shifts emit pairs of shift double and normal
9126 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9127 ;; support a 63 bit shift, each shift where the count is in a reg expands
9128 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9129 ;;
9130 ;; If the shift count is a constant, we need never emit more than one
9131 ;; shift pair, instead using moves and sign extension for counts greater
9132 ;; than 31.
9133
9134 (define_expand "ashl<mode>3"
9135 [(set (match_operand:SDWIM 0 "<shift_operand>")
9136 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9137 (match_operand:QI 2 "nonmemory_operand")))]
9138 ""
9139 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9140
9141 (define_insn "*ashl<mode>3_doubleword"
9142 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9143 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9144 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9145 (clobber (reg:CC FLAGS_REG))]
9146 ""
9147 "#"
9148 [(set_attr "type" "multi")])
9149
9150 (define_split
9151 [(set (match_operand:DWI 0 "register_operand")
9152 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9153 (match_operand:QI 2 "nonmemory_operand")))
9154 (clobber (reg:CC FLAGS_REG))]
9155 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9156 [(const_int 0)]
9157 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9158
9159 ;; By default we don't ask for a scratch register, because when DWImode
9160 ;; values are manipulated, registers are already at a premium. But if
9161 ;; we have one handy, we won't turn it away.
9162
9163 (define_peephole2
9164 [(match_scratch:DWIH 3 "r")
9165 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9166 (ashift:<DWI>
9167 (match_operand:<DWI> 1 "nonmemory_operand")
9168 (match_operand:QI 2 "nonmemory_operand")))
9169 (clobber (reg:CC FLAGS_REG))])
9170 (match_dup 3)]
9171 "TARGET_CMOVE"
9172 [(const_int 0)]
9173 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9174
9175 (define_insn "x86_64_shld"
9176 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9177 (ior:DI (ashift:DI (match_dup 0)
9178 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9179 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9180 (minus:QI (const_int 64) (match_dup 2)))))
9181 (clobber (reg:CC FLAGS_REG))]
9182 "TARGET_64BIT"
9183 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9184 [(set_attr "type" "ishift")
9185 (set_attr "prefix_0f" "1")
9186 (set_attr "mode" "DI")
9187 (set_attr "athlon_decode" "vector")
9188 (set_attr "amdfam10_decode" "vector")
9189 (set_attr "bdver1_decode" "vector")])
9190
9191 (define_insn "x86_shld"
9192 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9193 (ior:SI (ashift:SI (match_dup 0)
9194 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9195 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9196 (minus:QI (const_int 32) (match_dup 2)))))
9197 (clobber (reg:CC FLAGS_REG))]
9198 ""
9199 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9200 [(set_attr "type" "ishift")
9201 (set_attr "prefix_0f" "1")
9202 (set_attr "mode" "SI")
9203 (set_attr "pent_pair" "np")
9204 (set_attr "athlon_decode" "vector")
9205 (set_attr "amdfam10_decode" "vector")
9206 (set_attr "bdver1_decode" "vector")])
9207
9208 (define_expand "x86_shift<mode>_adj_1"
9209 [(set (reg:CCZ FLAGS_REG)
9210 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9211 (match_dup 4))
9212 (const_int 0)))
9213 (set (match_operand:SWI48 0 "register_operand")
9214 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9215 (match_operand:SWI48 1 "register_operand")
9216 (match_dup 0)))
9217 (set (match_dup 1)
9218 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9219 (match_operand:SWI48 3 "register_operand")
9220 (match_dup 1)))]
9221 "TARGET_CMOVE"
9222 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9223
9224 (define_expand "x86_shift<mode>_adj_2"
9225 [(use (match_operand:SWI48 0 "register_operand"))
9226 (use (match_operand:SWI48 1 "register_operand"))
9227 (use (match_operand:QI 2 "register_operand"))]
9228 ""
9229 {
9230 rtx label = gen_label_rtx ();
9231 rtx tmp;
9232
9233 emit_insn (gen_testqi_ccz_1 (operands[2],
9234 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9235
9236 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9237 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9238 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9239 gen_rtx_LABEL_REF (VOIDmode, label),
9240 pc_rtx);
9241 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9242 JUMP_LABEL (tmp) = label;
9243
9244 emit_move_insn (operands[0], operands[1]);
9245 ix86_expand_clear (operands[1]);
9246
9247 emit_label (label);
9248 LABEL_NUSES (label) = 1;
9249
9250 DONE;
9251 })
9252
9253 ;; Avoid useless masking of count operand.
9254 (define_insn_and_split "*ashl<mode>3_mask"
9255 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9256 (ashift:SWI48
9257 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9258 (subreg:QI
9259 (and:SI
9260 (match_operand:SI 2 "nonimmediate_operand" "c")
9261 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9262 (clobber (reg:CC FLAGS_REG))]
9263 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9264 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9265 == GET_MODE_BITSIZE (<MODE>mode)-1"
9266 "#"
9267 "&& 1"
9268 [(parallel [(set (match_dup 0)
9269 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9270 (clobber (reg:CC FLAGS_REG))])]
9271 {
9272 if (can_create_pseudo_p ())
9273 operands [2] = force_reg (SImode, operands[2]);
9274
9275 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9276 }
9277 [(set_attr "type" "ishift")
9278 (set_attr "mode" "<MODE>")])
9279
9280 (define_insn "*bmi2_ashl<mode>3_1"
9281 [(set (match_operand:SWI48 0 "register_operand" "=r")
9282 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9283 (match_operand:SWI48 2 "register_operand" "r")))]
9284 "TARGET_BMI2"
9285 "shlx\t{%2, %1, %0|%0, %1, %2}"
9286 [(set_attr "type" "ishiftx")
9287 (set_attr "mode" "<MODE>")])
9288
9289 (define_insn "*ashl<mode>3_1"
9290 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9291 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9292 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9293 (clobber (reg:CC FLAGS_REG))]
9294 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9295 {
9296 switch (get_attr_type (insn))
9297 {
9298 case TYPE_LEA:
9299 case TYPE_ISHIFTX:
9300 return "#";
9301
9302 case TYPE_ALU:
9303 gcc_assert (operands[2] == const1_rtx);
9304 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9305 return "add{<imodesuffix>}\t%0, %0";
9306
9307 default:
9308 if (operands[2] == const1_rtx
9309 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9310 return "sal{<imodesuffix>}\t%0";
9311 else
9312 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9313 }
9314 }
9315 [(set_attr "isa" "*,*,bmi2")
9316 (set (attr "type")
9317 (cond [(eq_attr "alternative" "1")
9318 (const_string "lea")
9319 (eq_attr "alternative" "2")
9320 (const_string "ishiftx")
9321 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9322 (match_operand 0 "register_operand"))
9323 (match_operand 2 "const1_operand"))
9324 (const_string "alu")
9325 ]
9326 (const_string "ishift")))
9327 (set (attr "length_immediate")
9328 (if_then_else
9329 (ior (eq_attr "type" "alu")
9330 (and (eq_attr "type" "ishift")
9331 (and (match_operand 2 "const1_operand")
9332 (ior (match_test "TARGET_SHIFT1")
9333 (match_test "optimize_function_for_size_p (cfun)")))))
9334 (const_string "0")
9335 (const_string "*")))
9336 (set_attr "mode" "<MODE>")])
9337
9338 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9339 (define_split
9340 [(set (match_operand:SWI48 0 "register_operand")
9341 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9342 (match_operand:QI 2 "register_operand")))
9343 (clobber (reg:CC FLAGS_REG))]
9344 "TARGET_BMI2 && reload_completed"
9345 [(set (match_dup 0)
9346 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9347 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9348
9349 (define_insn "*bmi2_ashlsi3_1_zext"
9350 [(set (match_operand:DI 0 "register_operand" "=r")
9351 (zero_extend:DI
9352 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9353 (match_operand:SI 2 "register_operand" "r"))))]
9354 "TARGET_64BIT && TARGET_BMI2"
9355 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9356 [(set_attr "type" "ishiftx")
9357 (set_attr "mode" "SI")])
9358
9359 (define_insn "*ashlsi3_1_zext"
9360 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9361 (zero_extend:DI
9362 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9363 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9364 (clobber (reg:CC FLAGS_REG))]
9365 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9366 {
9367 switch (get_attr_type (insn))
9368 {
9369 case TYPE_LEA:
9370 case TYPE_ISHIFTX:
9371 return "#";
9372
9373 case TYPE_ALU:
9374 gcc_assert (operands[2] == const1_rtx);
9375 return "add{l}\t%k0, %k0";
9376
9377 default:
9378 if (operands[2] == const1_rtx
9379 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9380 return "sal{l}\t%k0";
9381 else
9382 return "sal{l}\t{%2, %k0|%k0, %2}";
9383 }
9384 }
9385 [(set_attr "isa" "*,*,bmi2")
9386 (set (attr "type")
9387 (cond [(eq_attr "alternative" "1")
9388 (const_string "lea")
9389 (eq_attr "alternative" "2")
9390 (const_string "ishiftx")
9391 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9392 (match_operand 2 "const1_operand"))
9393 (const_string "alu")
9394 ]
9395 (const_string "ishift")))
9396 (set (attr "length_immediate")
9397 (if_then_else
9398 (ior (eq_attr "type" "alu")
9399 (and (eq_attr "type" "ishift")
9400 (and (match_operand 2 "const1_operand")
9401 (ior (match_test "TARGET_SHIFT1")
9402 (match_test "optimize_function_for_size_p (cfun)")))))
9403 (const_string "0")
9404 (const_string "*")))
9405 (set_attr "mode" "SI")])
9406
9407 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9408 (define_split
9409 [(set (match_operand:DI 0 "register_operand")
9410 (zero_extend:DI
9411 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9412 (match_operand:QI 2 "register_operand"))))
9413 (clobber (reg:CC FLAGS_REG))]
9414 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9415 [(set (match_dup 0)
9416 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9417 "operands[2] = gen_lowpart (SImode, operands[2]);")
9418
9419 (define_insn "*ashlhi3_1"
9420 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9421 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9422 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9423 (clobber (reg:CC FLAGS_REG))]
9424 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9425 {
9426 switch (get_attr_type (insn))
9427 {
9428 case TYPE_LEA:
9429 return "#";
9430
9431 case TYPE_ALU:
9432 gcc_assert (operands[2] == const1_rtx);
9433 return "add{w}\t%0, %0";
9434
9435 default:
9436 if (operands[2] == const1_rtx
9437 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9438 return "sal{w}\t%0";
9439 else
9440 return "sal{w}\t{%2, %0|%0, %2}";
9441 }
9442 }
9443 [(set (attr "type")
9444 (cond [(eq_attr "alternative" "1")
9445 (const_string "lea")
9446 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9447 (match_operand 0 "register_operand"))
9448 (match_operand 2 "const1_operand"))
9449 (const_string "alu")
9450 ]
9451 (const_string "ishift")))
9452 (set (attr "length_immediate")
9453 (if_then_else
9454 (ior (eq_attr "type" "alu")
9455 (and (eq_attr "type" "ishift")
9456 (and (match_operand 2 "const1_operand")
9457 (ior (match_test "TARGET_SHIFT1")
9458 (match_test "optimize_function_for_size_p (cfun)")))))
9459 (const_string "0")
9460 (const_string "*")))
9461 (set_attr "mode" "HI,SI")])
9462
9463 ;; %%% Potential partial reg stall on alternative 1. What to do?
9464 (define_insn "*ashlqi3_1"
9465 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9466 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9467 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9468 (clobber (reg:CC FLAGS_REG))]
9469 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9470 {
9471 switch (get_attr_type (insn))
9472 {
9473 case TYPE_LEA:
9474 return "#";
9475
9476 case TYPE_ALU:
9477 gcc_assert (operands[2] == const1_rtx);
9478 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9479 return "add{l}\t%k0, %k0";
9480 else
9481 return "add{b}\t%0, %0";
9482
9483 default:
9484 if (operands[2] == const1_rtx
9485 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9486 {
9487 if (get_attr_mode (insn) == MODE_SI)
9488 return "sal{l}\t%k0";
9489 else
9490 return "sal{b}\t%0";
9491 }
9492 else
9493 {
9494 if (get_attr_mode (insn) == MODE_SI)
9495 return "sal{l}\t{%2, %k0|%k0, %2}";
9496 else
9497 return "sal{b}\t{%2, %0|%0, %2}";
9498 }
9499 }
9500 }
9501 [(set (attr "type")
9502 (cond [(eq_attr "alternative" "2")
9503 (const_string "lea")
9504 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9505 (match_operand 0 "register_operand"))
9506 (match_operand 2 "const1_operand"))
9507 (const_string "alu")
9508 ]
9509 (const_string "ishift")))
9510 (set (attr "length_immediate")
9511 (if_then_else
9512 (ior (eq_attr "type" "alu")
9513 (and (eq_attr "type" "ishift")
9514 (and (match_operand 2 "const1_operand")
9515 (ior (match_test "TARGET_SHIFT1")
9516 (match_test "optimize_function_for_size_p (cfun)")))))
9517 (const_string "0")
9518 (const_string "*")))
9519 (set_attr "mode" "QI,SI,SI")])
9520
9521 (define_insn "*ashlqi3_1_slp"
9522 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9523 (ashift:QI (match_dup 0)
9524 (match_operand:QI 1 "nonmemory_operand" "cI")))
9525 (clobber (reg:CC FLAGS_REG))]
9526 "(optimize_function_for_size_p (cfun)
9527 || !TARGET_PARTIAL_FLAG_REG_STALL
9528 || (operands[1] == const1_rtx
9529 && (TARGET_SHIFT1
9530 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9531 {
9532 switch (get_attr_type (insn))
9533 {
9534 case TYPE_ALU:
9535 gcc_assert (operands[1] == const1_rtx);
9536 return "add{b}\t%0, %0";
9537
9538 default:
9539 if (operands[1] == const1_rtx
9540 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9541 return "sal{b}\t%0";
9542 else
9543 return "sal{b}\t{%1, %0|%0, %1}";
9544 }
9545 }
9546 [(set (attr "type")
9547 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9548 (match_operand 0 "register_operand"))
9549 (match_operand 1 "const1_operand"))
9550 (const_string "alu")
9551 ]
9552 (const_string "ishift1")))
9553 (set (attr "length_immediate")
9554 (if_then_else
9555 (ior (eq_attr "type" "alu")
9556 (and (eq_attr "type" "ishift1")
9557 (and (match_operand 1 "const1_operand")
9558 (ior (match_test "TARGET_SHIFT1")
9559 (match_test "optimize_function_for_size_p (cfun)")))))
9560 (const_string "0")
9561 (const_string "*")))
9562 (set_attr "mode" "QI")])
9563
9564 ;; Convert ashift to the lea pattern to avoid flags dependency.
9565 (define_split
9566 [(set (match_operand 0 "register_operand")
9567 (ashift (match_operand 1 "index_register_operand")
9568 (match_operand:QI 2 "const_int_operand")))
9569 (clobber (reg:CC FLAGS_REG))]
9570 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9571 && reload_completed
9572 && true_regnum (operands[0]) != true_regnum (operands[1])"
9573 [(const_int 0)]
9574 {
9575 enum machine_mode mode = GET_MODE (operands[0]);
9576 rtx pat;
9577
9578 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9579 {
9580 mode = SImode;
9581 operands[0] = gen_lowpart (mode, operands[0]);
9582 operands[1] = gen_lowpart (mode, operands[1]);
9583 }
9584
9585 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9586
9587 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9588
9589 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9590 DONE;
9591 })
9592
9593 ;; Convert ashift to the lea pattern to avoid flags dependency.
9594 (define_split
9595 [(set (match_operand:DI 0 "register_operand")
9596 (zero_extend:DI
9597 (ashift:SI (match_operand:SI 1 "index_register_operand")
9598 (match_operand:QI 2 "const_int_operand"))))
9599 (clobber (reg:CC FLAGS_REG))]
9600 "TARGET_64BIT && reload_completed
9601 && true_regnum (operands[0]) != true_regnum (operands[1])"
9602 [(set (match_dup 0)
9603 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9604 {
9605 operands[1] = gen_lowpart (SImode, operands[1]);
9606 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9607 })
9608
9609 ;; This pattern can't accept a variable shift count, since shifts by
9610 ;; zero don't affect the flags. We assume that shifts by constant
9611 ;; zero are optimized away.
9612 (define_insn "*ashl<mode>3_cmp"
9613 [(set (reg FLAGS_REG)
9614 (compare
9615 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9616 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9617 (const_int 0)))
9618 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9619 (ashift:SWI (match_dup 1) (match_dup 2)))]
9620 "(optimize_function_for_size_p (cfun)
9621 || !TARGET_PARTIAL_FLAG_REG_STALL
9622 || (operands[2] == const1_rtx
9623 && (TARGET_SHIFT1
9624 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9625 && ix86_match_ccmode (insn, CCGOCmode)
9626 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9627 {
9628 switch (get_attr_type (insn))
9629 {
9630 case TYPE_ALU:
9631 gcc_assert (operands[2] == const1_rtx);
9632 return "add{<imodesuffix>}\t%0, %0";
9633
9634 default:
9635 if (operands[2] == const1_rtx
9636 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9637 return "sal{<imodesuffix>}\t%0";
9638 else
9639 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9640 }
9641 }
9642 [(set (attr "type")
9643 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9644 (match_operand 0 "register_operand"))
9645 (match_operand 2 "const1_operand"))
9646 (const_string "alu")
9647 ]
9648 (const_string "ishift")))
9649 (set (attr "length_immediate")
9650 (if_then_else
9651 (ior (eq_attr "type" "alu")
9652 (and (eq_attr "type" "ishift")
9653 (and (match_operand 2 "const1_operand")
9654 (ior (match_test "TARGET_SHIFT1")
9655 (match_test "optimize_function_for_size_p (cfun)")))))
9656 (const_string "0")
9657 (const_string "*")))
9658 (set_attr "mode" "<MODE>")])
9659
9660 (define_insn "*ashlsi3_cmp_zext"
9661 [(set (reg FLAGS_REG)
9662 (compare
9663 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9664 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9665 (const_int 0)))
9666 (set (match_operand:DI 0 "register_operand" "=r")
9667 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9668 "TARGET_64BIT
9669 && (optimize_function_for_size_p (cfun)
9670 || !TARGET_PARTIAL_FLAG_REG_STALL
9671 || (operands[2] == const1_rtx
9672 && (TARGET_SHIFT1
9673 || TARGET_DOUBLE_WITH_ADD)))
9674 && ix86_match_ccmode (insn, CCGOCmode)
9675 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9676 {
9677 switch (get_attr_type (insn))
9678 {
9679 case TYPE_ALU:
9680 gcc_assert (operands[2] == const1_rtx);
9681 return "add{l}\t%k0, %k0";
9682
9683 default:
9684 if (operands[2] == const1_rtx
9685 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9686 return "sal{l}\t%k0";
9687 else
9688 return "sal{l}\t{%2, %k0|%k0, %2}";
9689 }
9690 }
9691 [(set (attr "type")
9692 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9693 (match_operand 2 "const1_operand"))
9694 (const_string "alu")
9695 ]
9696 (const_string "ishift")))
9697 (set (attr "length_immediate")
9698 (if_then_else
9699 (ior (eq_attr "type" "alu")
9700 (and (eq_attr "type" "ishift")
9701 (and (match_operand 2 "const1_operand")
9702 (ior (match_test "TARGET_SHIFT1")
9703 (match_test "optimize_function_for_size_p (cfun)")))))
9704 (const_string "0")
9705 (const_string "*")))
9706 (set_attr "mode" "SI")])
9707
9708 (define_insn "*ashl<mode>3_cconly"
9709 [(set (reg FLAGS_REG)
9710 (compare
9711 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9712 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9713 (const_int 0)))
9714 (clobber (match_scratch:SWI 0 "=<r>"))]
9715 "(optimize_function_for_size_p (cfun)
9716 || !TARGET_PARTIAL_FLAG_REG_STALL
9717 || (operands[2] == const1_rtx
9718 && (TARGET_SHIFT1
9719 || TARGET_DOUBLE_WITH_ADD)))
9720 && ix86_match_ccmode (insn, CCGOCmode)"
9721 {
9722 switch (get_attr_type (insn))
9723 {
9724 case TYPE_ALU:
9725 gcc_assert (operands[2] == const1_rtx);
9726 return "add{<imodesuffix>}\t%0, %0";
9727
9728 default:
9729 if (operands[2] == const1_rtx
9730 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9731 return "sal{<imodesuffix>}\t%0";
9732 else
9733 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9734 }
9735 }
9736 [(set (attr "type")
9737 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9738 (match_operand 0 "register_operand"))
9739 (match_operand 2 "const1_operand"))
9740 (const_string "alu")
9741 ]
9742 (const_string "ishift")))
9743 (set (attr "length_immediate")
9744 (if_then_else
9745 (ior (eq_attr "type" "alu")
9746 (and (eq_attr "type" "ishift")
9747 (and (match_operand 2 "const1_operand")
9748 (ior (match_test "TARGET_SHIFT1")
9749 (match_test "optimize_function_for_size_p (cfun)")))))
9750 (const_string "0")
9751 (const_string "*")))
9752 (set_attr "mode" "<MODE>")])
9753
9754 ;; See comment above `ashl<mode>3' about how this works.
9755
9756 (define_expand "<shift_insn><mode>3"
9757 [(set (match_operand:SDWIM 0 "<shift_operand>")
9758 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9759 (match_operand:QI 2 "nonmemory_operand")))]
9760 ""
9761 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9762
9763 ;; Avoid useless masking of count operand.
9764 (define_insn_and_split "*<shift_insn><mode>3_mask"
9765 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9766 (any_shiftrt:SWI48
9767 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9768 (subreg:QI
9769 (and:SI
9770 (match_operand:SI 2 "nonimmediate_operand" "c")
9771 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9772 (clobber (reg:CC FLAGS_REG))]
9773 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9774 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9775 == GET_MODE_BITSIZE (<MODE>mode)-1"
9776 "#"
9777 "&& 1"
9778 [(parallel [(set (match_dup 0)
9779 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9780 (clobber (reg:CC FLAGS_REG))])]
9781 {
9782 if (can_create_pseudo_p ())
9783 operands [2] = force_reg (SImode, operands[2]);
9784
9785 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9786 }
9787 [(set_attr "type" "ishift")
9788 (set_attr "mode" "<MODE>")])
9789
9790 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9791 [(set (match_operand:DWI 0 "register_operand" "=r")
9792 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9793 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9794 (clobber (reg:CC FLAGS_REG))]
9795 ""
9796 "#"
9797 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9798 [(const_int 0)]
9799 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9800 [(set_attr "type" "multi")])
9801
9802 ;; By default we don't ask for a scratch register, because when DWImode
9803 ;; values are manipulated, registers are already at a premium. But if
9804 ;; we have one handy, we won't turn it away.
9805
9806 (define_peephole2
9807 [(match_scratch:DWIH 3 "r")
9808 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9809 (any_shiftrt:<DWI>
9810 (match_operand:<DWI> 1 "register_operand")
9811 (match_operand:QI 2 "nonmemory_operand")))
9812 (clobber (reg:CC FLAGS_REG))])
9813 (match_dup 3)]
9814 "TARGET_CMOVE"
9815 [(const_int 0)]
9816 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9817
9818 (define_insn "x86_64_shrd"
9819 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9820 (ior:DI (ashiftrt:DI (match_dup 0)
9821 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9822 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9823 (minus:QI (const_int 64) (match_dup 2)))))
9824 (clobber (reg:CC FLAGS_REG))]
9825 "TARGET_64BIT"
9826 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9827 [(set_attr "type" "ishift")
9828 (set_attr "prefix_0f" "1")
9829 (set_attr "mode" "DI")
9830 (set_attr "athlon_decode" "vector")
9831 (set_attr "amdfam10_decode" "vector")
9832 (set_attr "bdver1_decode" "vector")])
9833
9834 (define_insn "x86_shrd"
9835 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9836 (ior:SI (ashiftrt:SI (match_dup 0)
9837 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9838 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9839 (minus:QI (const_int 32) (match_dup 2)))))
9840 (clobber (reg:CC FLAGS_REG))]
9841 ""
9842 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9843 [(set_attr "type" "ishift")
9844 (set_attr "prefix_0f" "1")
9845 (set_attr "mode" "SI")
9846 (set_attr "pent_pair" "np")
9847 (set_attr "athlon_decode" "vector")
9848 (set_attr "amdfam10_decode" "vector")
9849 (set_attr "bdver1_decode" "vector")])
9850
9851 (define_insn "ashrdi3_cvt"
9852 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9853 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9854 (match_operand:QI 2 "const_int_operand")))
9855 (clobber (reg:CC FLAGS_REG))]
9856 "TARGET_64BIT && INTVAL (operands[2]) == 63
9857 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9858 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9859 "@
9860 {cqto|cqo}
9861 sar{q}\t{%2, %0|%0, %2}"
9862 [(set_attr "type" "imovx,ishift")
9863 (set_attr "prefix_0f" "0,*")
9864 (set_attr "length_immediate" "0,*")
9865 (set_attr "modrm" "0,1")
9866 (set_attr "mode" "DI")])
9867
9868 (define_insn "ashrsi3_cvt"
9869 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9870 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9871 (match_operand:QI 2 "const_int_operand")))
9872 (clobber (reg:CC FLAGS_REG))]
9873 "INTVAL (operands[2]) == 31
9874 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9875 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9876 "@
9877 {cltd|cdq}
9878 sar{l}\t{%2, %0|%0, %2}"
9879 [(set_attr "type" "imovx,ishift")
9880 (set_attr "prefix_0f" "0,*")
9881 (set_attr "length_immediate" "0,*")
9882 (set_attr "modrm" "0,1")
9883 (set_attr "mode" "SI")])
9884
9885 (define_insn "*ashrsi3_cvt_zext"
9886 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9887 (zero_extend:DI
9888 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9889 (match_operand:QI 2 "const_int_operand"))))
9890 (clobber (reg:CC FLAGS_REG))]
9891 "TARGET_64BIT && INTVAL (operands[2]) == 31
9892 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9893 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9894 "@
9895 {cltd|cdq}
9896 sar{l}\t{%2, %k0|%k0, %2}"
9897 [(set_attr "type" "imovx,ishift")
9898 (set_attr "prefix_0f" "0,*")
9899 (set_attr "length_immediate" "0,*")
9900 (set_attr "modrm" "0,1")
9901 (set_attr "mode" "SI")])
9902
9903 (define_expand "x86_shift<mode>_adj_3"
9904 [(use (match_operand:SWI48 0 "register_operand"))
9905 (use (match_operand:SWI48 1 "register_operand"))
9906 (use (match_operand:QI 2 "register_operand"))]
9907 ""
9908 {
9909 rtx label = gen_label_rtx ();
9910 rtx tmp;
9911
9912 emit_insn (gen_testqi_ccz_1 (operands[2],
9913 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9914
9915 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9916 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9917 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9918 gen_rtx_LABEL_REF (VOIDmode, label),
9919 pc_rtx);
9920 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9921 JUMP_LABEL (tmp) = label;
9922
9923 emit_move_insn (operands[0], operands[1]);
9924 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9925 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9926 emit_label (label);
9927 LABEL_NUSES (label) = 1;
9928
9929 DONE;
9930 })
9931
9932 (define_insn "*bmi2_<shift_insn><mode>3_1"
9933 [(set (match_operand:SWI48 0 "register_operand" "=r")
9934 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9935 (match_operand:SWI48 2 "register_operand" "r")))]
9936 "TARGET_BMI2"
9937 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9938 [(set_attr "type" "ishiftx")
9939 (set_attr "mode" "<MODE>")])
9940
9941 (define_insn "*<shift_insn><mode>3_1"
9942 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9943 (any_shiftrt:SWI48
9944 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9945 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9946 (clobber (reg:CC FLAGS_REG))]
9947 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9948 {
9949 switch (get_attr_type (insn))
9950 {
9951 case TYPE_ISHIFTX:
9952 return "#";
9953
9954 default:
9955 if (operands[2] == const1_rtx
9956 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9957 return "<shift>{<imodesuffix>}\t%0";
9958 else
9959 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9960 }
9961 }
9962 [(set_attr "isa" "*,bmi2")
9963 (set_attr "type" "ishift,ishiftx")
9964 (set (attr "length_immediate")
9965 (if_then_else
9966 (and (match_operand 2 "const1_operand")
9967 (ior (match_test "TARGET_SHIFT1")
9968 (match_test "optimize_function_for_size_p (cfun)")))
9969 (const_string "0")
9970 (const_string "*")))
9971 (set_attr "mode" "<MODE>")])
9972
9973 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9974 (define_split
9975 [(set (match_operand:SWI48 0 "register_operand")
9976 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9977 (match_operand:QI 2 "register_operand")))
9978 (clobber (reg:CC FLAGS_REG))]
9979 "TARGET_BMI2 && reload_completed"
9980 [(set (match_dup 0)
9981 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9982 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9983
9984 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9985 [(set (match_operand:DI 0 "register_operand" "=r")
9986 (zero_extend:DI
9987 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9988 (match_operand:SI 2 "register_operand" "r"))))]
9989 "TARGET_64BIT && TARGET_BMI2"
9990 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9991 [(set_attr "type" "ishiftx")
9992 (set_attr "mode" "SI")])
9993
9994 (define_insn "*<shift_insn>si3_1_zext"
9995 [(set (match_operand:DI 0 "register_operand" "=r,r")
9996 (zero_extend:DI
9997 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9998 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9999 (clobber (reg:CC FLAGS_REG))]
10000 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10001 {
10002 switch (get_attr_type (insn))
10003 {
10004 case TYPE_ISHIFTX:
10005 return "#";
10006
10007 default:
10008 if (operands[2] == const1_rtx
10009 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10010 return "<shift>{l}\t%k0";
10011 else
10012 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10013 }
10014 }
10015 [(set_attr "isa" "*,bmi2")
10016 (set_attr "type" "ishift,ishiftx")
10017 (set (attr "length_immediate")
10018 (if_then_else
10019 (and (match_operand 2 "const1_operand")
10020 (ior (match_test "TARGET_SHIFT1")
10021 (match_test "optimize_function_for_size_p (cfun)")))
10022 (const_string "0")
10023 (const_string "*")))
10024 (set_attr "mode" "SI")])
10025
10026 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10027 (define_split
10028 [(set (match_operand:DI 0 "register_operand")
10029 (zero_extend:DI
10030 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10031 (match_operand:QI 2 "register_operand"))))
10032 (clobber (reg:CC FLAGS_REG))]
10033 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10034 [(set (match_dup 0)
10035 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10036 "operands[2] = gen_lowpart (SImode, operands[2]);")
10037
10038 (define_insn "*<shift_insn><mode>3_1"
10039 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10040 (any_shiftrt:SWI12
10041 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10042 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10043 (clobber (reg:CC FLAGS_REG))]
10044 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10045 {
10046 if (operands[2] == const1_rtx
10047 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10048 return "<shift>{<imodesuffix>}\t%0";
10049 else
10050 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10051 }
10052 [(set_attr "type" "ishift")
10053 (set (attr "length_immediate")
10054 (if_then_else
10055 (and (match_operand 2 "const1_operand")
10056 (ior (match_test "TARGET_SHIFT1")
10057 (match_test "optimize_function_for_size_p (cfun)")))
10058 (const_string "0")
10059 (const_string "*")))
10060 (set_attr "mode" "<MODE>")])
10061
10062 (define_insn "*<shift_insn>qi3_1_slp"
10063 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10064 (any_shiftrt:QI (match_dup 0)
10065 (match_operand:QI 1 "nonmemory_operand" "cI")))
10066 (clobber (reg:CC FLAGS_REG))]
10067 "(optimize_function_for_size_p (cfun)
10068 || !TARGET_PARTIAL_REG_STALL
10069 || (operands[1] == const1_rtx
10070 && TARGET_SHIFT1))"
10071 {
10072 if (operands[1] == const1_rtx
10073 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10074 return "<shift>{b}\t%0";
10075 else
10076 return "<shift>{b}\t{%1, %0|%0, %1}";
10077 }
10078 [(set_attr "type" "ishift1")
10079 (set (attr "length_immediate")
10080 (if_then_else
10081 (and (match_operand 1 "const1_operand")
10082 (ior (match_test "TARGET_SHIFT1")
10083 (match_test "optimize_function_for_size_p (cfun)")))
10084 (const_string "0")
10085 (const_string "*")))
10086 (set_attr "mode" "QI")])
10087
10088 ;; This pattern can't accept a variable shift count, since shifts by
10089 ;; zero don't affect the flags. We assume that shifts by constant
10090 ;; zero are optimized away.
10091 (define_insn "*<shift_insn><mode>3_cmp"
10092 [(set (reg FLAGS_REG)
10093 (compare
10094 (any_shiftrt:SWI
10095 (match_operand:SWI 1 "nonimmediate_operand" "0")
10096 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10097 (const_int 0)))
10098 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10099 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10100 "(optimize_function_for_size_p (cfun)
10101 || !TARGET_PARTIAL_FLAG_REG_STALL
10102 || (operands[2] == const1_rtx
10103 && TARGET_SHIFT1))
10104 && ix86_match_ccmode (insn, CCGOCmode)
10105 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10106 {
10107 if (operands[2] == const1_rtx
10108 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10109 return "<shift>{<imodesuffix>}\t%0";
10110 else
10111 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10112 }
10113 [(set_attr "type" "ishift")
10114 (set (attr "length_immediate")
10115 (if_then_else
10116 (and (match_operand 2 "const1_operand")
10117 (ior (match_test "TARGET_SHIFT1")
10118 (match_test "optimize_function_for_size_p (cfun)")))
10119 (const_string "0")
10120 (const_string "*")))
10121 (set_attr "mode" "<MODE>")])
10122
10123 (define_insn "*<shift_insn>si3_cmp_zext"
10124 [(set (reg FLAGS_REG)
10125 (compare
10126 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10127 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10128 (const_int 0)))
10129 (set (match_operand:DI 0 "register_operand" "=r")
10130 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10131 "TARGET_64BIT
10132 && (optimize_function_for_size_p (cfun)
10133 || !TARGET_PARTIAL_FLAG_REG_STALL
10134 || (operands[2] == const1_rtx
10135 && TARGET_SHIFT1))
10136 && ix86_match_ccmode (insn, CCGOCmode)
10137 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10138 {
10139 if (operands[2] == const1_rtx
10140 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10141 return "<shift>{l}\t%k0";
10142 else
10143 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10144 }
10145 [(set_attr "type" "ishift")
10146 (set (attr "length_immediate")
10147 (if_then_else
10148 (and (match_operand 2 "const1_operand")
10149 (ior (match_test "TARGET_SHIFT1")
10150 (match_test "optimize_function_for_size_p (cfun)")))
10151 (const_string "0")
10152 (const_string "*")))
10153 (set_attr "mode" "SI")])
10154
10155 (define_insn "*<shift_insn><mode>3_cconly"
10156 [(set (reg FLAGS_REG)
10157 (compare
10158 (any_shiftrt:SWI
10159 (match_operand:SWI 1 "register_operand" "0")
10160 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10161 (const_int 0)))
10162 (clobber (match_scratch:SWI 0 "=<r>"))]
10163 "(optimize_function_for_size_p (cfun)
10164 || !TARGET_PARTIAL_FLAG_REG_STALL
10165 || (operands[2] == const1_rtx
10166 && TARGET_SHIFT1))
10167 && ix86_match_ccmode (insn, CCGOCmode)"
10168 {
10169 if (operands[2] == const1_rtx
10170 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10171 return "<shift>{<imodesuffix>}\t%0";
10172 else
10173 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10174 }
10175 [(set_attr "type" "ishift")
10176 (set (attr "length_immediate")
10177 (if_then_else
10178 (and (match_operand 2 "const1_operand")
10179 (ior (match_test "TARGET_SHIFT1")
10180 (match_test "optimize_function_for_size_p (cfun)")))
10181 (const_string "0")
10182 (const_string "*")))
10183 (set_attr "mode" "<MODE>")])
10184 \f
10185 ;; Rotate instructions
10186
10187 (define_expand "<rotate_insn>ti3"
10188 [(set (match_operand:TI 0 "register_operand")
10189 (any_rotate:TI (match_operand:TI 1 "register_operand")
10190 (match_operand:QI 2 "nonmemory_operand")))]
10191 "TARGET_64BIT"
10192 {
10193 if (const_1_to_63_operand (operands[2], VOIDmode))
10194 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10195 (operands[0], operands[1], operands[2]));
10196 else
10197 FAIL;
10198
10199 DONE;
10200 })
10201
10202 (define_expand "<rotate_insn>di3"
10203 [(set (match_operand:DI 0 "shiftdi_operand")
10204 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10205 (match_operand:QI 2 "nonmemory_operand")))]
10206 ""
10207 {
10208 if (TARGET_64BIT)
10209 ix86_expand_binary_operator (<CODE>, DImode, operands);
10210 else if (const_1_to_31_operand (operands[2], VOIDmode))
10211 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10212 (operands[0], operands[1], operands[2]));
10213 else
10214 FAIL;
10215
10216 DONE;
10217 })
10218
10219 (define_expand "<rotate_insn><mode>3"
10220 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10221 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10222 (match_operand:QI 2 "nonmemory_operand")))]
10223 ""
10224 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10225
10226 ;; Avoid useless masking of count operand.
10227 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10228 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10229 (any_rotate:SWI48
10230 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10231 (subreg:QI
10232 (and:SI
10233 (match_operand:SI 2 "nonimmediate_operand" "c")
10234 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10235 (clobber (reg:CC FLAGS_REG))]
10236 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10237 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10238 == GET_MODE_BITSIZE (<MODE>mode)-1"
10239 "#"
10240 "&& 1"
10241 [(parallel [(set (match_dup 0)
10242 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10243 (clobber (reg:CC FLAGS_REG))])]
10244 {
10245 if (can_create_pseudo_p ())
10246 operands [2] = force_reg (SImode, operands[2]);
10247
10248 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10249 }
10250 [(set_attr "type" "rotate")
10251 (set_attr "mode" "<MODE>")])
10252
10253 ;; Implement rotation using two double-precision
10254 ;; shift instructions and a scratch register.
10255
10256 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10257 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10258 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10259 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10260 (clobber (reg:CC FLAGS_REG))
10261 (clobber (match_scratch:DWIH 3 "=&r"))]
10262 ""
10263 "#"
10264 "reload_completed"
10265 [(set (match_dup 3) (match_dup 4))
10266 (parallel
10267 [(set (match_dup 4)
10268 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10269 (lshiftrt:DWIH (match_dup 5)
10270 (minus:QI (match_dup 6) (match_dup 2)))))
10271 (clobber (reg:CC FLAGS_REG))])
10272 (parallel
10273 [(set (match_dup 5)
10274 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10275 (lshiftrt:DWIH (match_dup 3)
10276 (minus:QI (match_dup 6) (match_dup 2)))))
10277 (clobber (reg:CC FLAGS_REG))])]
10278 {
10279 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10280
10281 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10282 })
10283
10284 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10285 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10286 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10287 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10288 (clobber (reg:CC FLAGS_REG))
10289 (clobber (match_scratch:DWIH 3 "=&r"))]
10290 ""
10291 "#"
10292 "reload_completed"
10293 [(set (match_dup 3) (match_dup 4))
10294 (parallel
10295 [(set (match_dup 4)
10296 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10297 (ashift:DWIH (match_dup 5)
10298 (minus:QI (match_dup 6) (match_dup 2)))))
10299 (clobber (reg:CC FLAGS_REG))])
10300 (parallel
10301 [(set (match_dup 5)
10302 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10303 (ashift:DWIH (match_dup 3)
10304 (minus:QI (match_dup 6) (match_dup 2)))))
10305 (clobber (reg:CC FLAGS_REG))])]
10306 {
10307 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10308
10309 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10310 })
10311
10312 (define_insn "*bmi2_rorx<mode>3_1"
10313 [(set (match_operand:SWI48 0 "register_operand" "=r")
10314 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10315 (match_operand:QI 2 "immediate_operand" "<S>")))]
10316 "TARGET_BMI2"
10317 "rorx\t{%2, %1, %0|%0, %1, %2}"
10318 [(set_attr "type" "rotatex")
10319 (set_attr "mode" "<MODE>")])
10320
10321 (define_insn "*<rotate_insn><mode>3_1"
10322 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10323 (any_rotate:SWI48
10324 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10325 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10326 (clobber (reg:CC FLAGS_REG))]
10327 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10328 {
10329 switch (get_attr_type (insn))
10330 {
10331 case TYPE_ROTATEX:
10332 return "#";
10333
10334 default:
10335 if (operands[2] == const1_rtx
10336 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10337 return "<rotate>{<imodesuffix>}\t%0";
10338 else
10339 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10340 }
10341 }
10342 [(set_attr "isa" "*,bmi2")
10343 (set_attr "type" "rotate,rotatex")
10344 (set (attr "length_immediate")
10345 (if_then_else
10346 (and (eq_attr "type" "rotate")
10347 (and (match_operand 2 "const1_operand")
10348 (ior (match_test "TARGET_SHIFT1")
10349 (match_test "optimize_function_for_size_p (cfun)"))))
10350 (const_string "0")
10351 (const_string "*")))
10352 (set_attr "mode" "<MODE>")])
10353
10354 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10355 (define_split
10356 [(set (match_operand:SWI48 0 "register_operand")
10357 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10358 (match_operand:QI 2 "immediate_operand")))
10359 (clobber (reg:CC FLAGS_REG))]
10360 "TARGET_BMI2 && reload_completed"
10361 [(set (match_dup 0)
10362 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10363 {
10364 operands[2]
10365 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10366 })
10367
10368 (define_split
10369 [(set (match_operand:SWI48 0 "register_operand")
10370 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10371 (match_operand:QI 2 "immediate_operand")))
10372 (clobber (reg:CC FLAGS_REG))]
10373 "TARGET_BMI2 && reload_completed"
10374 [(set (match_dup 0)
10375 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10376
10377 (define_insn "*bmi2_rorxsi3_1_zext"
10378 [(set (match_operand:DI 0 "register_operand" "=r")
10379 (zero_extend:DI
10380 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10381 (match_operand:QI 2 "immediate_operand" "I"))))]
10382 "TARGET_64BIT && TARGET_BMI2"
10383 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10384 [(set_attr "type" "rotatex")
10385 (set_attr "mode" "SI")])
10386
10387 (define_insn "*<rotate_insn>si3_1_zext"
10388 [(set (match_operand:DI 0 "register_operand" "=r,r")
10389 (zero_extend:DI
10390 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10391 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10392 (clobber (reg:CC FLAGS_REG))]
10393 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10394 {
10395 switch (get_attr_type (insn))
10396 {
10397 case TYPE_ROTATEX:
10398 return "#";
10399
10400 default:
10401 if (operands[2] == const1_rtx
10402 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10403 return "<rotate>{l}\t%k0";
10404 else
10405 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10406 }
10407 }
10408 [(set_attr "isa" "*,bmi2")
10409 (set_attr "type" "rotate,rotatex")
10410 (set (attr "length_immediate")
10411 (if_then_else
10412 (and (eq_attr "type" "rotate")
10413 (and (match_operand 2 "const1_operand")
10414 (ior (match_test "TARGET_SHIFT1")
10415 (match_test "optimize_function_for_size_p (cfun)"))))
10416 (const_string "0")
10417 (const_string "*")))
10418 (set_attr "mode" "SI")])
10419
10420 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10421 (define_split
10422 [(set (match_operand:DI 0 "register_operand")
10423 (zero_extend:DI
10424 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10425 (match_operand:QI 2 "immediate_operand"))))
10426 (clobber (reg:CC FLAGS_REG))]
10427 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10428 [(set (match_dup 0)
10429 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10430 {
10431 operands[2]
10432 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10433 })
10434
10435 (define_split
10436 [(set (match_operand:DI 0 "register_operand")
10437 (zero_extend:DI
10438 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10439 (match_operand:QI 2 "immediate_operand"))))
10440 (clobber (reg:CC FLAGS_REG))]
10441 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10442 [(set (match_dup 0)
10443 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10444
10445 (define_insn "*<rotate_insn><mode>3_1"
10446 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10447 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10448 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10449 (clobber (reg:CC FLAGS_REG))]
10450 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10451 {
10452 if (operands[2] == const1_rtx
10453 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10454 return "<rotate>{<imodesuffix>}\t%0";
10455 else
10456 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10457 }
10458 [(set_attr "type" "rotate")
10459 (set (attr "length_immediate")
10460 (if_then_else
10461 (and (match_operand 2 "const1_operand")
10462 (ior (match_test "TARGET_SHIFT1")
10463 (match_test "optimize_function_for_size_p (cfun)")))
10464 (const_string "0")
10465 (const_string "*")))
10466 (set_attr "mode" "<MODE>")])
10467
10468 (define_insn "*<rotate_insn>qi3_1_slp"
10469 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10470 (any_rotate:QI (match_dup 0)
10471 (match_operand:QI 1 "nonmemory_operand" "cI")))
10472 (clobber (reg:CC FLAGS_REG))]
10473 "(optimize_function_for_size_p (cfun)
10474 || !TARGET_PARTIAL_REG_STALL
10475 || (operands[1] == const1_rtx
10476 && TARGET_SHIFT1))"
10477 {
10478 if (operands[1] == const1_rtx
10479 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10480 return "<rotate>{b}\t%0";
10481 else
10482 return "<rotate>{b}\t{%1, %0|%0, %1}";
10483 }
10484 [(set_attr "type" "rotate1")
10485 (set (attr "length_immediate")
10486 (if_then_else
10487 (and (match_operand 1 "const1_operand")
10488 (ior (match_test "TARGET_SHIFT1")
10489 (match_test "optimize_function_for_size_p (cfun)")))
10490 (const_string "0")
10491 (const_string "*")))
10492 (set_attr "mode" "QI")])
10493
10494 (define_split
10495 [(set (match_operand:HI 0 "register_operand")
10496 (any_rotate:HI (match_dup 0) (const_int 8)))
10497 (clobber (reg:CC FLAGS_REG))]
10498 "reload_completed
10499 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10500 [(parallel [(set (strict_low_part (match_dup 0))
10501 (bswap:HI (match_dup 0)))
10502 (clobber (reg:CC FLAGS_REG))])])
10503 \f
10504 ;; Bit set / bit test instructions
10505
10506 (define_expand "extv"
10507 [(set (match_operand:SI 0 "register_operand")
10508 (sign_extract:SI (match_operand:SI 1 "register_operand")
10509 (match_operand:SI 2 "const8_operand")
10510 (match_operand:SI 3 "const8_operand")))]
10511 ""
10512 {
10513 /* Handle extractions from %ah et al. */
10514 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10515 FAIL;
10516
10517 /* From mips.md: extract_bit_field doesn't verify that our source
10518 matches the predicate, so check it again here. */
10519 if (! ext_register_operand (operands[1], VOIDmode))
10520 FAIL;
10521 })
10522
10523 (define_expand "extzv"
10524 [(set (match_operand:SI 0 "register_operand")
10525 (zero_extract:SI (match_operand 1 "ext_register_operand")
10526 (match_operand:SI 2 "const8_operand")
10527 (match_operand:SI 3 "const8_operand")))]
10528 ""
10529 {
10530 /* Handle extractions from %ah et al. */
10531 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10532 FAIL;
10533
10534 /* From mips.md: extract_bit_field doesn't verify that our source
10535 matches the predicate, so check it again here. */
10536 if (! ext_register_operand (operands[1], VOIDmode))
10537 FAIL;
10538 })
10539
10540 (define_expand "insv"
10541 [(set (zero_extract (match_operand 0 "register_operand")
10542 (match_operand 1 "const_int_operand")
10543 (match_operand 2 "const_int_operand"))
10544 (match_operand 3 "register_operand"))]
10545 ""
10546 {
10547 rtx (*gen_mov_insv_1) (rtx, rtx);
10548
10549 if (ix86_expand_pinsr (operands))
10550 DONE;
10551
10552 /* Handle insertions to %ah et al. */
10553 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10554 FAIL;
10555
10556 /* From mips.md: insert_bit_field doesn't verify that our source
10557 matches the predicate, so check it again here. */
10558 if (! ext_register_operand (operands[0], VOIDmode))
10559 FAIL;
10560
10561 gen_mov_insv_1 = (TARGET_64BIT
10562 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10563
10564 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10565 DONE;
10566 })
10567
10568 ;; %%% bts, btr, btc, bt.
10569 ;; In general these instructions are *slow* when applied to memory,
10570 ;; since they enforce atomic operation. When applied to registers,
10571 ;; it depends on the cpu implementation. They're never faster than
10572 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10573 ;; no point. But in 64-bit, we can't hold the relevant immediates
10574 ;; within the instruction itself, so operating on bits in the high
10575 ;; 32-bits of a register becomes easier.
10576 ;;
10577 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10578 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10579 ;; negdf respectively, so they can never be disabled entirely.
10580
10581 (define_insn "*btsq"
10582 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10583 (const_int 1)
10584 (match_operand:DI 1 "const_0_to_63_operand"))
10585 (const_int 1))
10586 (clobber (reg:CC FLAGS_REG))]
10587 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10588 "bts{q}\t{%1, %0|%0, %1}"
10589 [(set_attr "type" "alu1")
10590 (set_attr "prefix_0f" "1")
10591 (set_attr "mode" "DI")])
10592
10593 (define_insn "*btrq"
10594 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
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 || reload_completed)"
10600 "btr{q}\t{%1, %0|%0, %1}"
10601 [(set_attr "type" "alu1")
10602 (set_attr "prefix_0f" "1")
10603 (set_attr "mode" "DI")])
10604
10605 (define_insn "*btcq"
10606 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10607 (const_int 1)
10608 (match_operand:DI 1 "const_0_to_63_operand"))
10609 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10610 (clobber (reg:CC FLAGS_REG))]
10611 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10612 "btc{q}\t{%1, %0|%0, %1}"
10613 [(set_attr "type" "alu1")
10614 (set_attr "prefix_0f" "1")
10615 (set_attr "mode" "DI")])
10616
10617 ;; Allow Nocona to avoid these instructions if a register is available.
10618
10619 (define_peephole2
10620 [(match_scratch:DI 2 "r")
10621 (parallel [(set (zero_extract:DI
10622 (match_operand:DI 0 "register_operand")
10623 (const_int 1)
10624 (match_operand:DI 1 "const_0_to_63_operand"))
10625 (const_int 1))
10626 (clobber (reg:CC FLAGS_REG))])]
10627 "TARGET_64BIT && !TARGET_USE_BT"
10628 [(const_int 0)]
10629 {
10630 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10631 rtx op1;
10632
10633 if (HOST_BITS_PER_WIDE_INT >= 64)
10634 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10635 else if (i < HOST_BITS_PER_WIDE_INT)
10636 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10637 else
10638 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10639
10640 op1 = immed_double_const (lo, hi, DImode);
10641 if (i >= 31)
10642 {
10643 emit_move_insn (operands[2], op1);
10644 op1 = operands[2];
10645 }
10646
10647 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10648 DONE;
10649 })
10650
10651 (define_peephole2
10652 [(match_scratch:DI 2 "r")
10653 (parallel [(set (zero_extract:DI
10654 (match_operand:DI 0 "register_operand")
10655 (const_int 1)
10656 (match_operand:DI 1 "const_0_to_63_operand"))
10657 (const_int 0))
10658 (clobber (reg:CC FLAGS_REG))])]
10659 "TARGET_64BIT && !TARGET_USE_BT"
10660 [(const_int 0)]
10661 {
10662 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10663 rtx op1;
10664
10665 if (HOST_BITS_PER_WIDE_INT >= 64)
10666 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10667 else if (i < HOST_BITS_PER_WIDE_INT)
10668 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10669 else
10670 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10671
10672 op1 = immed_double_const (~lo, ~hi, DImode);
10673 if (i >= 32)
10674 {
10675 emit_move_insn (operands[2], op1);
10676 op1 = operands[2];
10677 }
10678
10679 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10680 DONE;
10681 })
10682
10683 (define_peephole2
10684 [(match_scratch:DI 2 "r")
10685 (parallel [(set (zero_extract:DI
10686 (match_operand:DI 0 "register_operand")
10687 (const_int 1)
10688 (match_operand:DI 1 "const_0_to_63_operand"))
10689 (not:DI (zero_extract:DI
10690 (match_dup 0) (const_int 1) (match_dup 1))))
10691 (clobber (reg:CC FLAGS_REG))])]
10692 "TARGET_64BIT && !TARGET_USE_BT"
10693 [(const_int 0)]
10694 {
10695 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10696 rtx op1;
10697
10698 if (HOST_BITS_PER_WIDE_INT >= 64)
10699 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10700 else if (i < HOST_BITS_PER_WIDE_INT)
10701 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10702 else
10703 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10704
10705 op1 = immed_double_const (lo, hi, DImode);
10706 if (i >= 31)
10707 {
10708 emit_move_insn (operands[2], op1);
10709 op1 = operands[2];
10710 }
10711
10712 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10713 DONE;
10714 })
10715
10716 (define_insn "*bt<mode>"
10717 [(set (reg:CCC FLAGS_REG)
10718 (compare:CCC
10719 (zero_extract:SWI48
10720 (match_operand:SWI48 0 "register_operand" "r")
10721 (const_int 1)
10722 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10723 (const_int 0)))]
10724 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10725 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10726 [(set_attr "type" "alu1")
10727 (set_attr "prefix_0f" "1")
10728 (set_attr "mode" "<MODE>")])
10729 \f
10730 ;; Store-flag instructions.
10731
10732 ;; For all sCOND expanders, also expand the compare or test insn that
10733 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10734
10735 (define_insn_and_split "*setcc_di_1"
10736 [(set (match_operand:DI 0 "register_operand" "=q")
10737 (match_operator:DI 1 "ix86_comparison_operator"
10738 [(reg FLAGS_REG) (const_int 0)]))]
10739 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10740 "#"
10741 "&& reload_completed"
10742 [(set (match_dup 2) (match_dup 1))
10743 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10744 {
10745 PUT_MODE (operands[1], QImode);
10746 operands[2] = gen_lowpart (QImode, operands[0]);
10747 })
10748
10749 (define_insn_and_split "*setcc_si_1_and"
10750 [(set (match_operand:SI 0 "register_operand" "=q")
10751 (match_operator:SI 1 "ix86_comparison_operator"
10752 [(reg FLAGS_REG) (const_int 0)]))
10753 (clobber (reg:CC FLAGS_REG))]
10754 "!TARGET_PARTIAL_REG_STALL
10755 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10756 "#"
10757 "&& reload_completed"
10758 [(set (match_dup 2) (match_dup 1))
10759 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10760 (clobber (reg:CC FLAGS_REG))])]
10761 {
10762 PUT_MODE (operands[1], QImode);
10763 operands[2] = gen_lowpart (QImode, operands[0]);
10764 })
10765
10766 (define_insn_and_split "*setcc_si_1_movzbl"
10767 [(set (match_operand:SI 0 "register_operand" "=q")
10768 (match_operator:SI 1 "ix86_comparison_operator"
10769 [(reg FLAGS_REG) (const_int 0)]))]
10770 "!TARGET_PARTIAL_REG_STALL
10771 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10772 "#"
10773 "&& reload_completed"
10774 [(set (match_dup 2) (match_dup 1))
10775 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10776 {
10777 PUT_MODE (operands[1], QImode);
10778 operands[2] = gen_lowpart (QImode, operands[0]);
10779 })
10780
10781 (define_insn "*setcc_qi"
10782 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10783 (match_operator:QI 1 "ix86_comparison_operator"
10784 [(reg FLAGS_REG) (const_int 0)]))]
10785 ""
10786 "set%C1\t%0"
10787 [(set_attr "type" "setcc")
10788 (set_attr "mode" "QI")])
10789
10790 (define_insn "*setcc_qi_slp"
10791 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10792 (match_operator:QI 1 "ix86_comparison_operator"
10793 [(reg FLAGS_REG) (const_int 0)]))]
10794 ""
10795 "set%C1\t%0"
10796 [(set_attr "type" "setcc")
10797 (set_attr "mode" "QI")])
10798
10799 ;; In general it is not safe to assume too much about CCmode registers,
10800 ;; so simplify-rtx stops when it sees a second one. Under certain
10801 ;; conditions this is safe on x86, so help combine not create
10802 ;;
10803 ;; seta %al
10804 ;; testb %al, %al
10805 ;; sete %al
10806
10807 (define_split
10808 [(set (match_operand:QI 0 "nonimmediate_operand")
10809 (ne:QI (match_operator 1 "ix86_comparison_operator"
10810 [(reg FLAGS_REG) (const_int 0)])
10811 (const_int 0)))]
10812 ""
10813 [(set (match_dup 0) (match_dup 1))]
10814 "PUT_MODE (operands[1], QImode);")
10815
10816 (define_split
10817 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10818 (ne:QI (match_operator 1 "ix86_comparison_operator"
10819 [(reg FLAGS_REG) (const_int 0)])
10820 (const_int 0)))]
10821 ""
10822 [(set (match_dup 0) (match_dup 1))]
10823 "PUT_MODE (operands[1], QImode);")
10824
10825 (define_split
10826 [(set (match_operand:QI 0 "nonimmediate_operand")
10827 (eq:QI (match_operator 1 "ix86_comparison_operator"
10828 [(reg FLAGS_REG) (const_int 0)])
10829 (const_int 0)))]
10830 ""
10831 [(set (match_dup 0) (match_dup 1))]
10832 {
10833 rtx new_op1 = copy_rtx (operands[1]);
10834 operands[1] = new_op1;
10835 PUT_MODE (new_op1, QImode);
10836 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10837 GET_MODE (XEXP (new_op1, 0))));
10838
10839 /* Make sure that (a) the CCmode we have for the flags is strong
10840 enough for the reversed compare or (b) we have a valid FP compare. */
10841 if (! ix86_comparison_operator (new_op1, VOIDmode))
10842 FAIL;
10843 })
10844
10845 (define_split
10846 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10847 (eq:QI (match_operator 1 "ix86_comparison_operator"
10848 [(reg FLAGS_REG) (const_int 0)])
10849 (const_int 0)))]
10850 ""
10851 [(set (match_dup 0) (match_dup 1))]
10852 {
10853 rtx new_op1 = copy_rtx (operands[1]);
10854 operands[1] = new_op1;
10855 PUT_MODE (new_op1, QImode);
10856 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10857 GET_MODE (XEXP (new_op1, 0))));
10858
10859 /* Make sure that (a) the CCmode we have for the flags is strong
10860 enough for the reversed compare or (b) we have a valid FP compare. */
10861 if (! ix86_comparison_operator (new_op1, VOIDmode))
10862 FAIL;
10863 })
10864
10865 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10866 ;; subsequent logical operations are used to imitate conditional moves.
10867 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10868 ;; it directly.
10869
10870 (define_insn "setcc_<mode>_sse"
10871 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10872 (match_operator:MODEF 3 "sse_comparison_operator"
10873 [(match_operand:MODEF 1 "register_operand" "0,x")
10874 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10875 "SSE_FLOAT_MODE_P (<MODE>mode)"
10876 "@
10877 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10878 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10879 [(set_attr "isa" "noavx,avx")
10880 (set_attr "type" "ssecmp")
10881 (set_attr "length_immediate" "1")
10882 (set_attr "prefix" "orig,vex")
10883 (set_attr "mode" "<MODE>")])
10884 \f
10885 ;; Basic conditional jump instructions.
10886 ;; We ignore the overflow flag for signed branch instructions.
10887
10888 (define_insn "*jcc_1"
10889 [(set (pc)
10890 (if_then_else (match_operator 1 "ix86_comparison_operator"
10891 [(reg FLAGS_REG) (const_int 0)])
10892 (label_ref (match_operand 0))
10893 (pc)))]
10894 ""
10895 "%+j%C1\t%l0"
10896 [(set_attr "type" "ibr")
10897 (set_attr "modrm" "0")
10898 (set (attr "length")
10899 (if_then_else (and (ge (minus (match_dup 0) (pc))
10900 (const_int -126))
10901 (lt (minus (match_dup 0) (pc))
10902 (const_int 128)))
10903 (const_int 2)
10904 (const_int 6)))])
10905
10906 (define_insn "*jcc_2"
10907 [(set (pc)
10908 (if_then_else (match_operator 1 "ix86_comparison_operator"
10909 [(reg FLAGS_REG) (const_int 0)])
10910 (pc)
10911 (label_ref (match_operand 0))))]
10912 ""
10913 "%+j%c1\t%l0"
10914 [(set_attr "type" "ibr")
10915 (set_attr "modrm" "0")
10916 (set (attr "length")
10917 (if_then_else (and (ge (minus (match_dup 0) (pc))
10918 (const_int -126))
10919 (lt (minus (match_dup 0) (pc))
10920 (const_int 128)))
10921 (const_int 2)
10922 (const_int 6)))])
10923
10924 ;; In general it is not safe to assume too much about CCmode registers,
10925 ;; so simplify-rtx stops when it sees a second one. Under certain
10926 ;; conditions this is safe on x86, so help combine not create
10927 ;;
10928 ;; seta %al
10929 ;; testb %al, %al
10930 ;; je Lfoo
10931
10932 (define_split
10933 [(set (pc)
10934 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10935 [(reg FLAGS_REG) (const_int 0)])
10936 (const_int 0))
10937 (label_ref (match_operand 1))
10938 (pc)))]
10939 ""
10940 [(set (pc)
10941 (if_then_else (match_dup 0)
10942 (label_ref (match_dup 1))
10943 (pc)))]
10944 "PUT_MODE (operands[0], VOIDmode);")
10945
10946 (define_split
10947 [(set (pc)
10948 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10949 [(reg FLAGS_REG) (const_int 0)])
10950 (const_int 0))
10951 (label_ref (match_operand 1))
10952 (pc)))]
10953 ""
10954 [(set (pc)
10955 (if_then_else (match_dup 0)
10956 (label_ref (match_dup 1))
10957 (pc)))]
10958 {
10959 rtx new_op0 = copy_rtx (operands[0]);
10960 operands[0] = new_op0;
10961 PUT_MODE (new_op0, VOIDmode);
10962 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10963 GET_MODE (XEXP (new_op0, 0))));
10964
10965 /* Make sure that (a) the CCmode we have for the flags is strong
10966 enough for the reversed compare or (b) we have a valid FP compare. */
10967 if (! ix86_comparison_operator (new_op0, VOIDmode))
10968 FAIL;
10969 })
10970
10971 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10972 ;; pass generates from shift insn with QImode operand. Actually, the mode
10973 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10974 ;; appropriate modulo of the bit offset value.
10975
10976 (define_insn_and_split "*jcc_bt<mode>"
10977 [(set (pc)
10978 (if_then_else (match_operator 0 "bt_comparison_operator"
10979 [(zero_extract:SWI48
10980 (match_operand:SWI48 1 "register_operand" "r")
10981 (const_int 1)
10982 (zero_extend:SI
10983 (match_operand:QI 2 "register_operand" "r")))
10984 (const_int 0)])
10985 (label_ref (match_operand 3))
10986 (pc)))
10987 (clobber (reg:CC FLAGS_REG))]
10988 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10989 "#"
10990 "&& 1"
10991 [(set (reg:CCC FLAGS_REG)
10992 (compare:CCC
10993 (zero_extract:SWI48
10994 (match_dup 1)
10995 (const_int 1)
10996 (match_dup 2))
10997 (const_int 0)))
10998 (set (pc)
10999 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11000 (label_ref (match_dup 3))
11001 (pc)))]
11002 {
11003 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11004
11005 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11006 })
11007
11008 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
11009 ;; also for DImode, this is what combine produces.
11010 (define_insn_and_split "*jcc_bt<mode>_mask"
11011 [(set (pc)
11012 (if_then_else (match_operator 0 "bt_comparison_operator"
11013 [(zero_extract:SWI48
11014 (match_operand:SWI48 1 "register_operand" "r")
11015 (const_int 1)
11016 (and:SI
11017 (match_operand:SI 2 "register_operand" "r")
11018 (match_operand:SI 3 "const_int_operand" "n")))])
11019 (label_ref (match_operand 4))
11020 (pc)))
11021 (clobber (reg:CC FLAGS_REG))]
11022 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11023 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11024 == GET_MODE_BITSIZE (<MODE>mode)-1"
11025 "#"
11026 "&& 1"
11027 [(set (reg:CCC FLAGS_REG)
11028 (compare:CCC
11029 (zero_extract:SWI48
11030 (match_dup 1)
11031 (const_int 1)
11032 (match_dup 2))
11033 (const_int 0)))
11034 (set (pc)
11035 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11036 (label_ref (match_dup 4))
11037 (pc)))]
11038 {
11039 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11040
11041 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11042 })
11043
11044 (define_insn_and_split "*jcc_btsi_1"
11045 [(set (pc)
11046 (if_then_else (match_operator 0 "bt_comparison_operator"
11047 [(and:SI
11048 (lshiftrt:SI
11049 (match_operand:SI 1 "register_operand" "r")
11050 (match_operand:QI 2 "register_operand" "r"))
11051 (const_int 1))
11052 (const_int 0)])
11053 (label_ref (match_operand 3))
11054 (pc)))
11055 (clobber (reg:CC FLAGS_REG))]
11056 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11057 "#"
11058 "&& 1"
11059 [(set (reg:CCC FLAGS_REG)
11060 (compare:CCC
11061 (zero_extract:SI
11062 (match_dup 1)
11063 (const_int 1)
11064 (match_dup 2))
11065 (const_int 0)))
11066 (set (pc)
11067 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11068 (label_ref (match_dup 3))
11069 (pc)))]
11070 {
11071 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11072
11073 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11074 })
11075
11076 ;; avoid useless masking of bit offset operand
11077 (define_insn_and_split "*jcc_btsi_mask_1"
11078 [(set (pc)
11079 (if_then_else
11080 (match_operator 0 "bt_comparison_operator"
11081 [(and:SI
11082 (lshiftrt:SI
11083 (match_operand:SI 1 "register_operand" "r")
11084 (subreg:QI
11085 (and:SI
11086 (match_operand:SI 2 "register_operand" "r")
11087 (match_operand:SI 3 "const_int_operand" "n")) 0))
11088 (const_int 1))
11089 (const_int 0)])
11090 (label_ref (match_operand 4))
11091 (pc)))
11092 (clobber (reg:CC FLAGS_REG))]
11093 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11094 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11095 "#"
11096 "&& 1"
11097 [(set (reg:CCC FLAGS_REG)
11098 (compare:CCC
11099 (zero_extract:SI
11100 (match_dup 1)
11101 (const_int 1)
11102 (match_dup 2))
11103 (const_int 0)))
11104 (set (pc)
11105 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11106 (label_ref (match_dup 4))
11107 (pc)))]
11108 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11109
11110 ;; Define combination compare-and-branch fp compare instructions to help
11111 ;; combine.
11112
11113 (define_insn "*fp_jcc_1_387"
11114 [(set (pc)
11115 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11116 [(match_operand 1 "register_operand" "f")
11117 (match_operand 2 "nonimmediate_operand" "fm")])
11118 (label_ref (match_operand 3))
11119 (pc)))
11120 (clobber (reg:CCFP FPSR_REG))
11121 (clobber (reg:CCFP FLAGS_REG))
11122 (clobber (match_scratch:HI 4 "=a"))]
11123 "TARGET_80387
11124 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11125 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11126 && SELECT_CC_MODE (GET_CODE (operands[0]),
11127 operands[1], operands[2]) == CCFPmode
11128 && !TARGET_CMOVE"
11129 "#")
11130
11131 (define_insn "*fp_jcc_1r_387"
11132 [(set (pc)
11133 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11134 [(match_operand 1 "register_operand" "f")
11135 (match_operand 2 "nonimmediate_operand" "fm")])
11136 (pc)
11137 (label_ref (match_operand 3))))
11138 (clobber (reg:CCFP FPSR_REG))
11139 (clobber (reg:CCFP FLAGS_REG))
11140 (clobber (match_scratch:HI 4 "=a"))]
11141 "TARGET_80387
11142 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11143 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11144 && SELECT_CC_MODE (GET_CODE (operands[0]),
11145 operands[1], operands[2]) == CCFPmode
11146 && !TARGET_CMOVE"
11147 "#")
11148
11149 (define_insn "*fp_jcc_2_387"
11150 [(set (pc)
11151 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11152 [(match_operand 1 "register_operand" "f")
11153 (match_operand 2 "register_operand" "f")])
11154 (label_ref (match_operand 3))
11155 (pc)))
11156 (clobber (reg:CCFP FPSR_REG))
11157 (clobber (reg:CCFP FLAGS_REG))
11158 (clobber (match_scratch:HI 4 "=a"))]
11159 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11160 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11161 && !TARGET_CMOVE"
11162 "#")
11163
11164 (define_insn "*fp_jcc_2r_387"
11165 [(set (pc)
11166 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11167 [(match_operand 1 "register_operand" "f")
11168 (match_operand 2 "register_operand" "f")])
11169 (pc)
11170 (label_ref (match_operand 3))))
11171 (clobber (reg:CCFP FPSR_REG))
11172 (clobber (reg:CCFP FLAGS_REG))
11173 (clobber (match_scratch:HI 4 "=a"))]
11174 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11175 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11176 && !TARGET_CMOVE"
11177 "#")
11178
11179 (define_insn "*fp_jcc_3_387"
11180 [(set (pc)
11181 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11182 [(match_operand 1 "register_operand" "f")
11183 (match_operand 2 "const0_operand")])
11184 (label_ref (match_operand 3))
11185 (pc)))
11186 (clobber (reg:CCFP FPSR_REG))
11187 (clobber (reg:CCFP FLAGS_REG))
11188 (clobber (match_scratch:HI 4 "=a"))]
11189 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11190 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11191 && SELECT_CC_MODE (GET_CODE (operands[0]),
11192 operands[1], operands[2]) == CCFPmode
11193 && !TARGET_CMOVE"
11194 "#")
11195
11196 (define_split
11197 [(set (pc)
11198 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11199 [(match_operand 1 "register_operand")
11200 (match_operand 2 "nonimmediate_operand")])
11201 (match_operand 3)
11202 (match_operand 4)))
11203 (clobber (reg:CCFP FPSR_REG))
11204 (clobber (reg:CCFP FLAGS_REG))]
11205 "reload_completed"
11206 [(const_int 0)]
11207 {
11208 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11209 operands[3], operands[4], NULL_RTX, NULL_RTX);
11210 DONE;
11211 })
11212
11213 (define_split
11214 [(set (pc)
11215 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11216 [(match_operand 1 "register_operand")
11217 (match_operand 2 "general_operand")])
11218 (match_operand 3)
11219 (match_operand 4)))
11220 (clobber (reg:CCFP FPSR_REG))
11221 (clobber (reg:CCFP FLAGS_REG))
11222 (clobber (match_scratch:HI 5 "=a"))]
11223 "reload_completed"
11224 [(const_int 0)]
11225 {
11226 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11227 operands[3], operands[4], operands[5], NULL_RTX);
11228 DONE;
11229 })
11230
11231 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11232 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11233 ;; with a precedence over other operators and is always put in the first
11234 ;; place. Swap condition and operands to match ficom instruction.
11235
11236 (define_insn "*fp_jcc_4_<mode>_387"
11237 [(set (pc)
11238 (if_then_else
11239 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11240 [(match_operator 1 "float_operator"
11241 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11242 (match_operand 3 "register_operand" "f,f")])
11243 (label_ref (match_operand 4))
11244 (pc)))
11245 (clobber (reg:CCFP FPSR_REG))
11246 (clobber (reg:CCFP FLAGS_REG))
11247 (clobber (match_scratch:HI 5 "=a,a"))]
11248 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11249 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11250 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11251 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11252 && !TARGET_CMOVE"
11253 "#")
11254
11255 (define_split
11256 [(set (pc)
11257 (if_then_else
11258 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11259 [(match_operator 1 "float_operator"
11260 [(match_operand:SWI24 2 "memory_operand")])
11261 (match_operand 3 "register_operand")])
11262 (match_operand 4)
11263 (match_operand 5)))
11264 (clobber (reg:CCFP FPSR_REG))
11265 (clobber (reg:CCFP FLAGS_REG))
11266 (clobber (match_scratch:HI 6 "=a"))]
11267 "reload_completed"
11268 [(const_int 0)]
11269 {
11270 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11271
11272 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11273 operands[3], operands[7],
11274 operands[4], operands[5], operands[6], NULL_RTX);
11275 DONE;
11276 })
11277
11278 ;; %%% Kill this when reload knows how to do it.
11279 (define_split
11280 [(set (pc)
11281 (if_then_else
11282 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11283 [(match_operator 1 "float_operator"
11284 [(match_operand:SWI24 2 "register_operand")])
11285 (match_operand 3 "register_operand")])
11286 (match_operand 4)
11287 (match_operand 5)))
11288 (clobber (reg:CCFP FPSR_REG))
11289 (clobber (reg:CCFP FLAGS_REG))
11290 (clobber (match_scratch:HI 6 "=a"))]
11291 "reload_completed"
11292 [(const_int 0)]
11293 {
11294 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11295 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11296
11297 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11298 operands[3], operands[7],
11299 operands[4], operands[5], operands[6], operands[2]);
11300 DONE;
11301 })
11302 \f
11303 ;; Unconditional and other jump instructions
11304
11305 (define_insn "jump"
11306 [(set (pc)
11307 (label_ref (match_operand 0)))]
11308 ""
11309 "jmp\t%l0"
11310 [(set_attr "type" "ibr")
11311 (set (attr "length")
11312 (if_then_else (and (ge (minus (match_dup 0) (pc))
11313 (const_int -126))
11314 (lt (minus (match_dup 0) (pc))
11315 (const_int 128)))
11316 (const_int 2)
11317 (const_int 5)))
11318 (set_attr "modrm" "0")])
11319
11320 (define_expand "indirect_jump"
11321 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11322 ""
11323 {
11324 if (TARGET_X32)
11325 operands[0] = convert_memory_address (word_mode, operands[0]);
11326 })
11327
11328 (define_insn "*indirect_jump"
11329 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11330 ""
11331 "jmp\t%A0"
11332 [(set_attr "type" "ibr")
11333 (set_attr "length_immediate" "0")])
11334
11335 (define_expand "tablejump"
11336 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11337 (use (label_ref (match_operand 1)))])]
11338 ""
11339 {
11340 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11341 relative. Convert the relative address to an absolute address. */
11342 if (flag_pic)
11343 {
11344 rtx op0, op1;
11345 enum rtx_code code;
11346
11347 /* We can't use @GOTOFF for text labels on VxWorks;
11348 see gotoff_operand. */
11349 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11350 {
11351 code = PLUS;
11352 op0 = operands[0];
11353 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11354 }
11355 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11356 {
11357 code = PLUS;
11358 op0 = operands[0];
11359 op1 = pic_offset_table_rtx;
11360 }
11361 else
11362 {
11363 code = MINUS;
11364 op0 = pic_offset_table_rtx;
11365 op1 = operands[0];
11366 }
11367
11368 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11369 OPTAB_DIRECT);
11370 }
11371
11372 if (TARGET_X32)
11373 operands[0] = convert_memory_address (word_mode, operands[0]);
11374 })
11375
11376 (define_insn "*tablejump_1"
11377 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11378 (use (label_ref (match_operand 1)))]
11379 ""
11380 "jmp\t%A0"
11381 [(set_attr "type" "ibr")
11382 (set_attr "length_immediate" "0")])
11383 \f
11384 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11385
11386 (define_peephole2
11387 [(set (reg FLAGS_REG) (match_operand 0))
11388 (set (match_operand:QI 1 "register_operand")
11389 (match_operator:QI 2 "ix86_comparison_operator"
11390 [(reg FLAGS_REG) (const_int 0)]))
11391 (set (match_operand 3 "q_regs_operand")
11392 (zero_extend (match_dup 1)))]
11393 "(peep2_reg_dead_p (3, operands[1])
11394 || operands_match_p (operands[1], operands[3]))
11395 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11396 [(set (match_dup 4) (match_dup 0))
11397 (set (strict_low_part (match_dup 5))
11398 (match_dup 2))]
11399 {
11400 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11401 operands[5] = gen_lowpart (QImode, operands[3]);
11402 ix86_expand_clear (operands[3]);
11403 })
11404
11405 (define_peephole2
11406 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11407 (match_operand 4)])
11408 (set (match_operand:QI 1 "register_operand")
11409 (match_operator:QI 2 "ix86_comparison_operator"
11410 [(reg FLAGS_REG) (const_int 0)]))
11411 (set (match_operand 3 "q_regs_operand")
11412 (zero_extend (match_dup 1)))]
11413 "(peep2_reg_dead_p (3, operands[1])
11414 || operands_match_p (operands[1], operands[3]))
11415 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11416 [(parallel [(set (match_dup 5) (match_dup 0))
11417 (match_dup 4)])
11418 (set (strict_low_part (match_dup 6))
11419 (match_dup 2))]
11420 {
11421 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11422 operands[6] = gen_lowpart (QImode, operands[3]);
11423 ix86_expand_clear (operands[3]);
11424 })
11425
11426 ;; Similar, but match zero extend with andsi3.
11427
11428 (define_peephole2
11429 [(set (reg FLAGS_REG) (match_operand 0))
11430 (set (match_operand:QI 1 "register_operand")
11431 (match_operator:QI 2 "ix86_comparison_operator"
11432 [(reg FLAGS_REG) (const_int 0)]))
11433 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11434 (and:SI (match_dup 3) (const_int 255)))
11435 (clobber (reg:CC FLAGS_REG))])]
11436 "REGNO (operands[1]) == REGNO (operands[3])
11437 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11438 [(set (match_dup 4) (match_dup 0))
11439 (set (strict_low_part (match_dup 5))
11440 (match_dup 2))]
11441 {
11442 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11443 operands[5] = gen_lowpart (QImode, operands[3]);
11444 ix86_expand_clear (operands[3]);
11445 })
11446
11447 (define_peephole2
11448 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11449 (match_operand 4)])
11450 (set (match_operand:QI 1 "register_operand")
11451 (match_operator:QI 2 "ix86_comparison_operator"
11452 [(reg FLAGS_REG) (const_int 0)]))
11453 (parallel [(set (match_operand 3 "q_regs_operand")
11454 (zero_extend (match_dup 1)))
11455 (clobber (reg:CC FLAGS_REG))])]
11456 "(peep2_reg_dead_p (3, operands[1])
11457 || operands_match_p (operands[1], operands[3]))
11458 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11459 [(parallel [(set (match_dup 5) (match_dup 0))
11460 (match_dup 4)])
11461 (set (strict_low_part (match_dup 6))
11462 (match_dup 2))]
11463 {
11464 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11465 operands[6] = gen_lowpart (QImode, operands[3]);
11466 ix86_expand_clear (operands[3]);
11467 })
11468 \f
11469 ;; Call instructions.
11470
11471 ;; The predicates normally associated with named expanders are not properly
11472 ;; checked for calls. This is a bug in the generic code, but it isn't that
11473 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11474
11475 ;; P6 processors will jump to the address after the decrement when %esp
11476 ;; is used as a call operand, so they will execute return address as a code.
11477 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11478
11479 ;; Register constraint for call instruction.
11480 (define_mode_attr c [(SI "l") (DI "r")])
11481
11482 ;; Call subroutine returning no value.
11483
11484 (define_expand "call"
11485 [(call (match_operand:QI 0)
11486 (match_operand 1))
11487 (use (match_operand 2))]
11488 ""
11489 {
11490 ix86_expand_call (NULL, operands[0], operands[1],
11491 operands[2], NULL, false);
11492 DONE;
11493 })
11494
11495 (define_expand "sibcall"
11496 [(call (match_operand:QI 0)
11497 (match_operand 1))
11498 (use (match_operand 2))]
11499 ""
11500 {
11501 ix86_expand_call (NULL, operands[0], operands[1],
11502 operands[2], NULL, true);
11503 DONE;
11504 })
11505
11506 (define_insn_and_split "*call_vzeroupper"
11507 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11508 (match_operand 1))
11509 (unspec [(match_operand 2 "const_int_operand")]
11510 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11511 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11512 "#"
11513 "&& reload_completed"
11514 [(const_int 0)]
11515 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11516 [(set_attr "type" "call")])
11517
11518 (define_insn "*call"
11519 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11520 (match_operand 1))]
11521 "!SIBLING_CALL_P (insn)"
11522 "* return ix86_output_call_insn (insn, operands[0]);"
11523 [(set_attr "type" "call")])
11524
11525 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11526 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11527 (match_operand 1))
11528 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11529 (clobber (reg:TI XMM6_REG))
11530 (clobber (reg:TI XMM7_REG))
11531 (clobber (reg:TI XMM8_REG))
11532 (clobber (reg:TI XMM9_REG))
11533 (clobber (reg:TI XMM10_REG))
11534 (clobber (reg:TI XMM11_REG))
11535 (clobber (reg:TI XMM12_REG))
11536 (clobber (reg:TI XMM13_REG))
11537 (clobber (reg:TI XMM14_REG))
11538 (clobber (reg:TI XMM15_REG))
11539 (clobber (reg:DI SI_REG))
11540 (clobber (reg:DI DI_REG))
11541 (unspec [(match_operand 2 "const_int_operand")]
11542 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11543 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11544 "#"
11545 "&& reload_completed"
11546 [(const_int 0)]
11547 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11548 [(set_attr "type" "call")])
11549
11550 (define_insn "*call_rex64_ms_sysv"
11551 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11552 (match_operand 1))
11553 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11554 (clobber (reg:TI XMM6_REG))
11555 (clobber (reg:TI XMM7_REG))
11556 (clobber (reg:TI XMM8_REG))
11557 (clobber (reg:TI XMM9_REG))
11558 (clobber (reg:TI XMM10_REG))
11559 (clobber (reg:TI XMM11_REG))
11560 (clobber (reg:TI XMM12_REG))
11561 (clobber (reg:TI XMM13_REG))
11562 (clobber (reg:TI XMM14_REG))
11563 (clobber (reg:TI XMM15_REG))
11564 (clobber (reg:DI SI_REG))
11565 (clobber (reg:DI DI_REG))]
11566 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11567 "* return ix86_output_call_insn (insn, operands[0]);"
11568 [(set_attr "type" "call")])
11569
11570 (define_insn_and_split "*sibcall_vzeroupper"
11571 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11572 (match_operand 1))
11573 (unspec [(match_operand 2 "const_int_operand")]
11574 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11575 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11576 "#"
11577 "&& reload_completed"
11578 [(const_int 0)]
11579 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11580 [(set_attr "type" "call")])
11581
11582 (define_insn "*sibcall"
11583 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11584 (match_operand 1))]
11585 "SIBLING_CALL_P (insn)"
11586 "* return ix86_output_call_insn (insn, operands[0]);"
11587 [(set_attr "type" "call")])
11588
11589 (define_expand "call_pop"
11590 [(parallel [(call (match_operand:QI 0)
11591 (match_operand:SI 1))
11592 (set (reg:SI SP_REG)
11593 (plus:SI (reg:SI SP_REG)
11594 (match_operand:SI 3)))])]
11595 "!TARGET_64BIT"
11596 {
11597 ix86_expand_call (NULL, operands[0], operands[1],
11598 operands[2], operands[3], false);
11599 DONE;
11600 })
11601
11602 (define_insn_and_split "*call_pop_vzeroupper"
11603 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11604 (match_operand 1))
11605 (set (reg:SI SP_REG)
11606 (plus:SI (reg:SI SP_REG)
11607 (match_operand:SI 2 "immediate_operand" "i")))
11608 (unspec [(match_operand 3 "const_int_operand")]
11609 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11610 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11611 "#"
11612 "&& reload_completed"
11613 [(const_int 0)]
11614 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11615 [(set_attr "type" "call")])
11616
11617 (define_insn "*call_pop"
11618 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11619 (match_operand 1))
11620 (set (reg:SI SP_REG)
11621 (plus:SI (reg:SI SP_REG)
11622 (match_operand:SI 2 "immediate_operand" "i")))]
11623 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11624 "* return ix86_output_call_insn (insn, operands[0]);"
11625 [(set_attr "type" "call")])
11626
11627 (define_insn_and_split "*sibcall_pop_vzeroupper"
11628 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11629 (match_operand 1))
11630 (set (reg:SI SP_REG)
11631 (plus:SI (reg:SI SP_REG)
11632 (match_operand:SI 2 "immediate_operand" "i")))
11633 (unspec [(match_operand 3 "const_int_operand")]
11634 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11635 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11636 "#"
11637 "&& reload_completed"
11638 [(const_int 0)]
11639 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11640 [(set_attr "type" "call")])
11641
11642 (define_insn "*sibcall_pop"
11643 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11644 (match_operand 1))
11645 (set (reg:SI SP_REG)
11646 (plus:SI (reg:SI SP_REG)
11647 (match_operand:SI 2 "immediate_operand" "i")))]
11648 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11649 "* return ix86_output_call_insn (insn, operands[0]);"
11650 [(set_attr "type" "call")])
11651
11652 ;; Call subroutine, returning value in operand 0
11653
11654 (define_expand "call_value"
11655 [(set (match_operand 0)
11656 (call (match_operand:QI 1)
11657 (match_operand 2)))
11658 (use (match_operand 3))]
11659 ""
11660 {
11661 ix86_expand_call (operands[0], operands[1], operands[2],
11662 operands[3], NULL, false);
11663 DONE;
11664 })
11665
11666 (define_expand "sibcall_value"
11667 [(set (match_operand 0)
11668 (call (match_operand:QI 1)
11669 (match_operand 2)))
11670 (use (match_operand 3))]
11671 ""
11672 {
11673 ix86_expand_call (operands[0], operands[1], operands[2],
11674 operands[3], NULL, true);
11675 DONE;
11676 })
11677
11678 (define_insn_and_split "*call_value_vzeroupper"
11679 [(set (match_operand 0)
11680 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11681 (match_operand 2)))
11682 (unspec [(match_operand 3 "const_int_operand")]
11683 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11684 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11685 "#"
11686 "&& reload_completed"
11687 [(const_int 0)]
11688 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11689 [(set_attr "type" "callv")])
11690
11691 (define_insn "*call_value"
11692 [(set (match_operand 0)
11693 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11694 (match_operand 2)))]
11695 "!SIBLING_CALL_P (insn)"
11696 "* return ix86_output_call_insn (insn, operands[1]);"
11697 [(set_attr "type" "callv")])
11698
11699 (define_insn_and_split "*sibcall_value_vzeroupper"
11700 [(set (match_operand 0)
11701 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11702 (match_operand 2)))
11703 (unspec [(match_operand 3 "const_int_operand")]
11704 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11705 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11706 "#"
11707 "&& reload_completed"
11708 [(const_int 0)]
11709 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11710 [(set_attr "type" "callv")])
11711
11712 (define_insn "*sibcall_value"
11713 [(set (match_operand 0)
11714 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11715 (match_operand 2)))]
11716 "SIBLING_CALL_P (insn)"
11717 "* return ix86_output_call_insn (insn, operands[1]);"
11718 [(set_attr "type" "callv")])
11719
11720 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11721 [(set (match_operand 0)
11722 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11723 (match_operand 2)))
11724 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11725 (clobber (reg:TI XMM6_REG))
11726 (clobber (reg:TI XMM7_REG))
11727 (clobber (reg:TI XMM8_REG))
11728 (clobber (reg:TI XMM9_REG))
11729 (clobber (reg:TI XMM10_REG))
11730 (clobber (reg:TI XMM11_REG))
11731 (clobber (reg:TI XMM12_REG))
11732 (clobber (reg:TI XMM13_REG))
11733 (clobber (reg:TI XMM14_REG))
11734 (clobber (reg:TI XMM15_REG))
11735 (clobber (reg:DI SI_REG))
11736 (clobber (reg:DI DI_REG))
11737 (unspec [(match_operand 3 "const_int_operand")]
11738 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11739 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11740 "#"
11741 "&& reload_completed"
11742 [(const_int 0)]
11743 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11744 [(set_attr "type" "callv")])
11745
11746 (define_insn "*call_value_rex64_ms_sysv"
11747 [(set (match_operand 0)
11748 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11749 (match_operand 2)))
11750 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11751 (clobber (reg:TI XMM6_REG))
11752 (clobber (reg:TI XMM7_REG))
11753 (clobber (reg:TI XMM8_REG))
11754 (clobber (reg:TI XMM9_REG))
11755 (clobber (reg:TI XMM10_REG))
11756 (clobber (reg:TI XMM11_REG))
11757 (clobber (reg:TI XMM12_REG))
11758 (clobber (reg:TI XMM13_REG))
11759 (clobber (reg:TI XMM14_REG))
11760 (clobber (reg:TI XMM15_REG))
11761 (clobber (reg:DI SI_REG))
11762 (clobber (reg:DI DI_REG))]
11763 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11764 "* return ix86_output_call_insn (insn, operands[1]);"
11765 [(set_attr "type" "callv")])
11766
11767 (define_expand "call_value_pop"
11768 [(parallel [(set (match_operand 0)
11769 (call (match_operand:QI 1)
11770 (match_operand:SI 2)))
11771 (set (reg:SI SP_REG)
11772 (plus:SI (reg:SI SP_REG)
11773 (match_operand:SI 4)))])]
11774 "!TARGET_64BIT"
11775 {
11776 ix86_expand_call (operands[0], operands[1], operands[2],
11777 operands[3], operands[4], false);
11778 DONE;
11779 })
11780
11781 (define_insn_and_split "*call_value_pop_vzeroupper"
11782 [(set (match_operand 0)
11783 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11784 (match_operand 2)))
11785 (set (reg:SI SP_REG)
11786 (plus:SI (reg:SI SP_REG)
11787 (match_operand:SI 3 "immediate_operand" "i")))
11788 (unspec [(match_operand 4 "const_int_operand")]
11789 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11790 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11791 "#"
11792 "&& reload_completed"
11793 [(const_int 0)]
11794 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11795 [(set_attr "type" "callv")])
11796
11797 (define_insn "*call_value_pop"
11798 [(set (match_operand 0)
11799 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11800 (match_operand 2)))
11801 (set (reg:SI SP_REG)
11802 (plus:SI (reg:SI SP_REG)
11803 (match_operand:SI 3 "immediate_operand" "i")))]
11804 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11805 "* return ix86_output_call_insn (insn, operands[1]);"
11806 [(set_attr "type" "callv")])
11807
11808 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11809 [(set (match_operand 0)
11810 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11811 (match_operand 2)))
11812 (set (reg:SI SP_REG)
11813 (plus:SI (reg:SI SP_REG)
11814 (match_operand:SI 3 "immediate_operand" "i")))
11815 (unspec [(match_operand 4 "const_int_operand")]
11816 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11817 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11818 "#"
11819 "&& reload_completed"
11820 [(const_int 0)]
11821 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11822 [(set_attr "type" "callv")])
11823
11824 (define_insn "*sibcall_value_pop"
11825 [(set (match_operand 0)
11826 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11827 (match_operand 2)))
11828 (set (reg:SI SP_REG)
11829 (plus:SI (reg:SI SP_REG)
11830 (match_operand:SI 3 "immediate_operand" "i")))]
11831 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11832 "* return ix86_output_call_insn (insn, operands[1]);"
11833 [(set_attr "type" "callv")])
11834
11835 ;; Call subroutine returning any type.
11836
11837 (define_expand "untyped_call"
11838 [(parallel [(call (match_operand 0)
11839 (const_int 0))
11840 (match_operand 1)
11841 (match_operand 2)])]
11842 ""
11843 {
11844 int i;
11845
11846 /* In order to give reg-stack an easier job in validating two
11847 coprocessor registers as containing a possible return value,
11848 simply pretend the untyped call returns a complex long double
11849 value.
11850
11851 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11852 and should have the default ABI. */
11853
11854 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11855 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11856 operands[0], const0_rtx,
11857 GEN_INT ((TARGET_64BIT
11858 ? (ix86_abi == SYSV_ABI
11859 ? X86_64_SSE_REGPARM_MAX
11860 : X86_64_MS_SSE_REGPARM_MAX)
11861 : X86_32_SSE_REGPARM_MAX)
11862 - 1),
11863 NULL, false);
11864
11865 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11866 {
11867 rtx set = XVECEXP (operands[2], 0, i);
11868 emit_move_insn (SET_DEST (set), SET_SRC (set));
11869 }
11870
11871 /* The optimizer does not know that the call sets the function value
11872 registers we stored in the result block. We avoid problems by
11873 claiming that all hard registers are used and clobbered at this
11874 point. */
11875 emit_insn (gen_blockage ());
11876
11877 DONE;
11878 })
11879 \f
11880 ;; Prologue and epilogue instructions
11881
11882 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11883 ;; all of memory. This blocks insns from being moved across this point.
11884
11885 (define_insn "blockage"
11886 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11887 ""
11888 ""
11889 [(set_attr "length" "0")])
11890
11891 ;; Do not schedule instructions accessing memory across this point.
11892
11893 (define_expand "memory_blockage"
11894 [(set (match_dup 0)
11895 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11896 ""
11897 {
11898 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11899 MEM_VOLATILE_P (operands[0]) = 1;
11900 })
11901
11902 (define_insn "*memory_blockage"
11903 [(set (match_operand:BLK 0)
11904 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11905 ""
11906 ""
11907 [(set_attr "length" "0")])
11908
11909 ;; As USE insns aren't meaningful after reload, this is used instead
11910 ;; to prevent deleting instructions setting registers for PIC code
11911 (define_insn "prologue_use"
11912 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11913 ""
11914 ""
11915 [(set_attr "length" "0")])
11916
11917 ;; Insn emitted into the body of a function to return from a function.
11918 ;; This is only done if the function's epilogue is known to be simple.
11919 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11920
11921 (define_expand "return"
11922 [(simple_return)]
11923 "ix86_can_use_return_insn_p ()"
11924 {
11925 ix86_maybe_emit_epilogue_vzeroupper ();
11926 if (crtl->args.pops_args)
11927 {
11928 rtx popc = GEN_INT (crtl->args.pops_args);
11929 emit_jump_insn (gen_simple_return_pop_internal (popc));
11930 DONE;
11931 }
11932 })
11933
11934 ;; We need to disable this for TARGET_SEH, as otherwise
11935 ;; shrink-wrapped prologue gets enabled too. This might exceed
11936 ;; the maximum size of prologue in unwind information.
11937
11938 (define_expand "simple_return"
11939 [(simple_return)]
11940 "!TARGET_SEH"
11941 {
11942 ix86_maybe_emit_epilogue_vzeroupper ();
11943 if (crtl->args.pops_args)
11944 {
11945 rtx popc = GEN_INT (crtl->args.pops_args);
11946 emit_jump_insn (gen_simple_return_pop_internal (popc));
11947 DONE;
11948 }
11949 })
11950
11951 (define_insn "simple_return_internal"
11952 [(simple_return)]
11953 "reload_completed"
11954 "ret"
11955 [(set_attr "length" "1")
11956 (set_attr "atom_unit" "jeu")
11957 (set_attr "length_immediate" "0")
11958 (set_attr "modrm" "0")])
11959
11960 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11961 ;; instruction Athlon and K8 have.
11962
11963 (define_insn "simple_return_internal_long"
11964 [(simple_return)
11965 (unspec [(const_int 0)] UNSPEC_REP)]
11966 "reload_completed"
11967 "rep%; ret"
11968 [(set_attr "length" "2")
11969 (set_attr "atom_unit" "jeu")
11970 (set_attr "length_immediate" "0")
11971 (set_attr "prefix_rep" "1")
11972 (set_attr "modrm" "0")])
11973
11974 (define_insn "simple_return_pop_internal"
11975 [(simple_return)
11976 (use (match_operand:SI 0 "const_int_operand"))]
11977 "reload_completed"
11978 "ret\t%0"
11979 [(set_attr "length" "3")
11980 (set_attr "atom_unit" "jeu")
11981 (set_attr "length_immediate" "2")
11982 (set_attr "modrm" "0")])
11983
11984 (define_insn "simple_return_indirect_internal"
11985 [(simple_return)
11986 (use (match_operand:SI 0 "register_operand" "r"))]
11987 "reload_completed"
11988 "jmp\t%A0"
11989 [(set_attr "type" "ibr")
11990 (set_attr "length_immediate" "0")])
11991
11992 (define_insn "nop"
11993 [(const_int 0)]
11994 ""
11995 "nop"
11996 [(set_attr "length" "1")
11997 (set_attr "length_immediate" "0")
11998 (set_attr "modrm" "0")])
11999
12000 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12001 (define_insn "nops"
12002 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12003 UNSPECV_NOPS)]
12004 "reload_completed"
12005 {
12006 int num = INTVAL (operands[0]);
12007
12008 gcc_assert (IN_RANGE (num, 1, 8));
12009
12010 while (num--)
12011 fputs ("\tnop\n", asm_out_file);
12012
12013 return "";
12014 }
12015 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12016 (set_attr "length_immediate" "0")
12017 (set_attr "modrm" "0")])
12018
12019 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12020 ;; branch prediction penalty for the third jump in a 16-byte
12021 ;; block on K8.
12022
12023 (define_insn "pad"
12024 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12025 ""
12026 {
12027 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12028 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12029 #else
12030 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12031 The align insn is used to avoid 3 jump instructions in the row to improve
12032 branch prediction and the benefits hardly outweigh the cost of extra 8
12033 nops on the average inserted by full alignment pseudo operation. */
12034 #endif
12035 return "";
12036 }
12037 [(set_attr "length" "16")])
12038
12039 (define_expand "prologue"
12040 [(const_int 0)]
12041 ""
12042 "ix86_expand_prologue (); DONE;")
12043
12044 (define_insn "set_got"
12045 [(set (match_operand:SI 0 "register_operand" "=r")
12046 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12047 (clobber (reg:CC FLAGS_REG))]
12048 "!TARGET_64BIT"
12049 "* return output_set_got (operands[0], NULL_RTX);"
12050 [(set_attr "type" "multi")
12051 (set_attr "length" "12")])
12052
12053 (define_insn "set_got_labelled"
12054 [(set (match_operand:SI 0 "register_operand" "=r")
12055 (unspec:SI [(label_ref (match_operand 1))]
12056 UNSPEC_SET_GOT))
12057 (clobber (reg:CC FLAGS_REG))]
12058 "!TARGET_64BIT"
12059 "* return output_set_got (operands[0], operands[1]);"
12060 [(set_attr "type" "multi")
12061 (set_attr "length" "12")])
12062
12063 (define_insn "set_got_rex64"
12064 [(set (match_operand:DI 0 "register_operand" "=r")
12065 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12066 "TARGET_64BIT"
12067 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12068 [(set_attr "type" "lea")
12069 (set_attr "length_address" "4")
12070 (set_attr "mode" "DI")])
12071
12072 (define_insn "set_rip_rex64"
12073 [(set (match_operand:DI 0 "register_operand" "=r")
12074 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12075 "TARGET_64BIT"
12076 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12077 [(set_attr "type" "lea")
12078 (set_attr "length_address" "4")
12079 (set_attr "mode" "DI")])
12080
12081 (define_insn "set_got_offset_rex64"
12082 [(set (match_operand:DI 0 "register_operand" "=r")
12083 (unspec:DI
12084 [(label_ref (match_operand 1))]
12085 UNSPEC_SET_GOT_OFFSET))]
12086 "TARGET_LP64"
12087 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12088 [(set_attr "type" "imov")
12089 (set_attr "length_immediate" "0")
12090 (set_attr "length_address" "8")
12091 (set_attr "mode" "DI")])
12092
12093 (define_expand "epilogue"
12094 [(const_int 0)]
12095 ""
12096 "ix86_expand_epilogue (1); DONE;")
12097
12098 (define_expand "sibcall_epilogue"
12099 [(const_int 0)]
12100 ""
12101 "ix86_expand_epilogue (0); DONE;")
12102
12103 (define_expand "eh_return"
12104 [(use (match_operand 0 "register_operand"))]
12105 ""
12106 {
12107 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12108
12109 /* Tricky bit: we write the address of the handler to which we will
12110 be returning into someone else's stack frame, one word below the
12111 stack address we wish to restore. */
12112 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12113 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12114 tmp = gen_rtx_MEM (Pmode, tmp);
12115 emit_move_insn (tmp, ra);
12116
12117 emit_jump_insn (gen_eh_return_internal ());
12118 emit_barrier ();
12119 DONE;
12120 })
12121
12122 (define_insn_and_split "eh_return_internal"
12123 [(eh_return)]
12124 ""
12125 "#"
12126 "epilogue_completed"
12127 [(const_int 0)]
12128 "ix86_expand_epilogue (2); DONE;")
12129
12130 (define_insn "leave"
12131 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12132 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12133 (clobber (mem:BLK (scratch)))]
12134 "!TARGET_64BIT"
12135 "leave"
12136 [(set_attr "type" "leave")])
12137
12138 (define_insn "leave_rex64"
12139 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12140 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12141 (clobber (mem:BLK (scratch)))]
12142 "TARGET_64BIT"
12143 "leave"
12144 [(set_attr "type" "leave")])
12145 \f
12146 ;; Handle -fsplit-stack.
12147
12148 (define_expand "split_stack_prologue"
12149 [(const_int 0)]
12150 ""
12151 {
12152 ix86_expand_split_stack_prologue ();
12153 DONE;
12154 })
12155
12156 ;; In order to support the call/return predictor, we use a return
12157 ;; instruction which the middle-end doesn't see.
12158 (define_insn "split_stack_return"
12159 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12160 UNSPECV_SPLIT_STACK_RETURN)]
12161 ""
12162 {
12163 if (operands[0] == const0_rtx)
12164 return "ret";
12165 else
12166 return "ret\t%0";
12167 }
12168 [(set_attr "atom_unit" "jeu")
12169 (set_attr "modrm" "0")
12170 (set (attr "length")
12171 (if_then_else (match_operand:SI 0 "const0_operand")
12172 (const_int 1)
12173 (const_int 3)))
12174 (set (attr "length_immediate")
12175 (if_then_else (match_operand:SI 0 "const0_operand")
12176 (const_int 0)
12177 (const_int 2)))])
12178
12179 ;; If there are operand 0 bytes available on the stack, jump to
12180 ;; operand 1.
12181
12182 (define_expand "split_stack_space_check"
12183 [(set (pc) (if_then_else
12184 (ltu (minus (reg SP_REG)
12185 (match_operand 0 "register_operand"))
12186 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12187 (label_ref (match_operand 1))
12188 (pc)))]
12189 ""
12190 {
12191 rtx reg, size, limit;
12192
12193 reg = gen_reg_rtx (Pmode);
12194 size = force_reg (Pmode, operands[0]);
12195 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12196 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12197 UNSPEC_STACK_CHECK);
12198 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12199 ix86_expand_branch (GEU, reg, limit, operands[1]);
12200
12201 DONE;
12202 })
12203 \f
12204 ;; Bit manipulation instructions.
12205
12206 (define_expand "ffs<mode>2"
12207 [(set (match_dup 2) (const_int -1))
12208 (parallel [(set (match_dup 3) (match_dup 4))
12209 (set (match_operand:SWI48 0 "register_operand")
12210 (ctz:SWI48
12211 (match_operand:SWI48 1 "nonimmediate_operand")))])
12212 (set (match_dup 0) (if_then_else:SWI48
12213 (eq (match_dup 3) (const_int 0))
12214 (match_dup 2)
12215 (match_dup 0)))
12216 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12217 (clobber (reg:CC FLAGS_REG))])]
12218 ""
12219 {
12220 enum machine_mode flags_mode;
12221
12222 if (<MODE>mode == SImode && !TARGET_CMOVE)
12223 {
12224 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12225 DONE;
12226 }
12227
12228 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12229
12230 operands[2] = gen_reg_rtx (<MODE>mode);
12231 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12232 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12233 })
12234
12235 (define_insn_and_split "ffssi2_no_cmove"
12236 [(set (match_operand:SI 0 "register_operand" "=r")
12237 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12238 (clobber (match_scratch:SI 2 "=&q"))
12239 (clobber (reg:CC FLAGS_REG))]
12240 "!TARGET_CMOVE"
12241 "#"
12242 "&& reload_completed"
12243 [(parallel [(set (match_dup 4) (match_dup 5))
12244 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12245 (set (strict_low_part (match_dup 3))
12246 (eq:QI (match_dup 4) (const_int 0)))
12247 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12248 (clobber (reg:CC FLAGS_REG))])
12249 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12250 (clobber (reg:CC FLAGS_REG))])
12251 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12252 (clobber (reg:CC FLAGS_REG))])]
12253 {
12254 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12255
12256 operands[3] = gen_lowpart (QImode, operands[2]);
12257 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12258 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12259
12260 ix86_expand_clear (operands[2]);
12261 })
12262
12263 (define_insn "*tzcnt<mode>_1"
12264 [(set (reg:CCC FLAGS_REG)
12265 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12266 (const_int 0)))
12267 (set (match_operand:SWI48 0 "register_operand" "=r")
12268 (ctz:SWI48 (match_dup 1)))]
12269 "TARGET_BMI"
12270 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12271 [(set_attr "type" "alu1")
12272 (set_attr "prefix_0f" "1")
12273 (set_attr "prefix_rep" "1")
12274 (set_attr "mode" "<MODE>")])
12275
12276 (define_insn "*bsf<mode>_1"
12277 [(set (reg:CCZ FLAGS_REG)
12278 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12279 (const_int 0)))
12280 (set (match_operand:SWI48 0 "register_operand" "=r")
12281 (ctz:SWI48 (match_dup 1)))]
12282 ""
12283 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12284 [(set_attr "type" "alu1")
12285 (set_attr "prefix_0f" "1")
12286 (set_attr "mode" "<MODE>")])
12287
12288 (define_insn "ctz<mode>2"
12289 [(set (match_operand:SWI248 0 "register_operand" "=r")
12290 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12291 (clobber (reg:CC FLAGS_REG))]
12292 ""
12293 {
12294 if (TARGET_BMI)
12295 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12296 else if (optimize_function_for_size_p (cfun))
12297 ;
12298 else if (TARGET_GENERIC)
12299 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12300 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12301
12302 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12303 }
12304 [(set_attr "type" "alu1")
12305 (set_attr "prefix_0f" "1")
12306 (set (attr "prefix_rep")
12307 (if_then_else
12308 (ior (match_test "TARGET_BMI")
12309 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12310 (match_test "TARGET_GENERIC")))
12311 (const_string "1")
12312 (const_string "0")))
12313 (set_attr "mode" "<MODE>")])
12314
12315 (define_expand "clz<mode>2"
12316 [(parallel
12317 [(set (match_operand:SWI248 0 "register_operand")
12318 (minus:SWI248
12319 (match_dup 2)
12320 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12321 (clobber (reg:CC FLAGS_REG))])
12322 (parallel
12323 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12324 (clobber (reg:CC FLAGS_REG))])]
12325 ""
12326 {
12327 if (TARGET_LZCNT)
12328 {
12329 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12330 DONE;
12331 }
12332 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12333 })
12334
12335 (define_insn "clz<mode>2_lzcnt"
12336 [(set (match_operand:SWI248 0 "register_operand" "=r")
12337 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12338 (clobber (reg:CC FLAGS_REG))]
12339 "TARGET_LZCNT"
12340 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12341 [(set_attr "prefix_rep" "1")
12342 (set_attr "type" "bitmanip")
12343 (set_attr "mode" "<MODE>")])
12344
12345 ;; BMI instructions.
12346 (define_insn "*bmi_andn_<mode>"
12347 [(set (match_operand:SWI48 0 "register_operand" "=r")
12348 (and:SWI48
12349 (not:SWI48
12350 (match_operand:SWI48 1 "register_operand" "r"))
12351 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12352 (clobber (reg:CC FLAGS_REG))]
12353 "TARGET_BMI"
12354 "andn\t{%2, %1, %0|%0, %1, %2}"
12355 [(set_attr "type" "bitmanip")
12356 (set_attr "mode" "<MODE>")])
12357
12358 (define_insn "bmi_bextr_<mode>"
12359 [(set (match_operand:SWI48 0 "register_operand" "=r")
12360 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12361 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12362 UNSPEC_BEXTR))
12363 (clobber (reg:CC FLAGS_REG))]
12364 "TARGET_BMI"
12365 "bextr\t{%2, %1, %0|%0, %1, %2}"
12366 [(set_attr "type" "bitmanip")
12367 (set_attr "mode" "<MODE>")])
12368
12369 (define_insn "*bmi_blsi_<mode>"
12370 [(set (match_operand:SWI48 0 "register_operand" "=r")
12371 (and:SWI48
12372 (neg:SWI48
12373 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12374 (match_dup 1)))
12375 (clobber (reg:CC FLAGS_REG))]
12376 "TARGET_BMI"
12377 "blsi\t{%1, %0|%0, %1}"
12378 [(set_attr "type" "bitmanip")
12379 (set_attr "mode" "<MODE>")])
12380
12381 (define_insn "*bmi_blsmsk_<mode>"
12382 [(set (match_operand:SWI48 0 "register_operand" "=r")
12383 (xor:SWI48
12384 (plus:SWI48
12385 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12386 (const_int -1))
12387 (match_dup 1)))
12388 (clobber (reg:CC FLAGS_REG))]
12389 "TARGET_BMI"
12390 "blsmsk\t{%1, %0|%0, %1}"
12391 [(set_attr "type" "bitmanip")
12392 (set_attr "mode" "<MODE>")])
12393
12394 (define_insn "*bmi_blsr_<mode>"
12395 [(set (match_operand:SWI48 0 "register_operand" "=r")
12396 (and:SWI48
12397 (plus:SWI48
12398 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12399 (const_int -1))
12400 (match_dup 1)))
12401 (clobber (reg:CC FLAGS_REG))]
12402 "TARGET_BMI"
12403 "blsr\t{%1, %0|%0, %1}"
12404 [(set_attr "type" "bitmanip")
12405 (set_attr "mode" "<MODE>")])
12406
12407 ;; BMI2 instructions.
12408 (define_insn "bmi2_bzhi_<mode>3"
12409 [(set (match_operand:SWI48 0 "register_operand" "=r")
12410 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12411 (lshiftrt:SWI48 (const_int -1)
12412 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12413 (clobber (reg:CC FLAGS_REG))]
12414 "TARGET_BMI2"
12415 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12416 [(set_attr "type" "bitmanip")
12417 (set_attr "prefix" "vex")
12418 (set_attr "mode" "<MODE>")])
12419
12420 (define_insn "bmi2_pdep_<mode>3"
12421 [(set (match_operand:SWI48 0 "register_operand" "=r")
12422 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12423 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12424 UNSPEC_PDEP))]
12425 "TARGET_BMI2"
12426 "pdep\t{%2, %1, %0|%0, %1, %2}"
12427 [(set_attr "type" "bitmanip")
12428 (set_attr "prefix" "vex")
12429 (set_attr "mode" "<MODE>")])
12430
12431 (define_insn "bmi2_pext_<mode>3"
12432 [(set (match_operand:SWI48 0 "register_operand" "=r")
12433 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12434 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12435 UNSPEC_PEXT))]
12436 "TARGET_BMI2"
12437 "pext\t{%2, %1, %0|%0, %1, %2}"
12438 [(set_attr "type" "bitmanip")
12439 (set_attr "prefix" "vex")
12440 (set_attr "mode" "<MODE>")])
12441
12442 ;; TBM instructions.
12443 (define_insn "tbm_bextri_<mode>"
12444 [(set (match_operand:SWI48 0 "register_operand" "=r")
12445 (zero_extract:SWI48
12446 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12447 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12448 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12449 (clobber (reg:CC FLAGS_REG))]
12450 "TARGET_TBM"
12451 {
12452 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12453 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12454 }
12455 [(set_attr "type" "bitmanip")
12456 (set_attr "mode" "<MODE>")])
12457
12458 (define_insn "*tbm_blcfill_<mode>"
12459 [(set (match_operand:SWI48 0 "register_operand" "=r")
12460 (and:SWI48
12461 (plus:SWI48
12462 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12463 (const_int 1))
12464 (match_dup 1)))
12465 (clobber (reg:CC FLAGS_REG))]
12466 "TARGET_TBM"
12467 "blcfill\t{%1, %0|%0, %1}"
12468 [(set_attr "type" "bitmanip")
12469 (set_attr "mode" "<MODE>")])
12470
12471 (define_insn "*tbm_blci_<mode>"
12472 [(set (match_operand:SWI48 0 "register_operand" "=r")
12473 (ior:SWI48
12474 (not:SWI48
12475 (plus:SWI48
12476 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12477 (const_int 1)))
12478 (match_dup 1)))
12479 (clobber (reg:CC FLAGS_REG))]
12480 "TARGET_TBM"
12481 "blci\t{%1, %0|%0, %1}"
12482 [(set_attr "type" "bitmanip")
12483 (set_attr "mode" "<MODE>")])
12484
12485 (define_insn "*tbm_blcic_<mode>"
12486 [(set (match_operand:SWI48 0 "register_operand" "=r")
12487 (and:SWI48
12488 (plus:SWI48
12489 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12490 (const_int 1))
12491 (not:SWI48
12492 (match_dup 1))))
12493 (clobber (reg:CC FLAGS_REG))]
12494 "TARGET_TBM"
12495 "blcic\t{%1, %0|%0, %1}"
12496 [(set_attr "type" "bitmanip")
12497 (set_attr "mode" "<MODE>")])
12498
12499 (define_insn "*tbm_blcmsk_<mode>"
12500 [(set (match_operand:SWI48 0 "register_operand" "=r")
12501 (xor:SWI48
12502 (plus:SWI48
12503 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12504 (const_int 1))
12505 (match_dup 1)))
12506 (clobber (reg:CC FLAGS_REG))]
12507 "TARGET_TBM"
12508 "blcmsk\t{%1, %0|%0, %1}"
12509 [(set_attr "type" "bitmanip")
12510 (set_attr "mode" "<MODE>")])
12511
12512 (define_insn "*tbm_blcs_<mode>"
12513 [(set (match_operand:SWI48 0 "register_operand" "=r")
12514 (ior:SWI48
12515 (plus:SWI48
12516 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12517 (const_int 1))
12518 (match_dup 1)))
12519 (clobber (reg:CC FLAGS_REG))]
12520 "TARGET_TBM"
12521 "blcs\t{%1, %0|%0, %1}"
12522 [(set_attr "type" "bitmanip")
12523 (set_attr "mode" "<MODE>")])
12524
12525 (define_insn "*tbm_blsfill_<mode>"
12526 [(set (match_operand:SWI48 0 "register_operand" "=r")
12527 (ior:SWI48
12528 (plus:SWI48
12529 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12530 (const_int -1))
12531 (match_dup 1)))
12532 (clobber (reg:CC FLAGS_REG))]
12533 "TARGET_TBM"
12534 "blsfill\t{%1, %0|%0, %1}"
12535 [(set_attr "type" "bitmanip")
12536 (set_attr "mode" "<MODE>")])
12537
12538 (define_insn "*tbm_blsic_<mode>"
12539 [(set (match_operand:SWI48 0 "register_operand" "=r")
12540 (ior:SWI48
12541 (plus:SWI48
12542 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12543 (const_int -1))
12544 (not:SWI48
12545 (match_dup 1))))
12546 (clobber (reg:CC FLAGS_REG))]
12547 "TARGET_TBM"
12548 "blsic\t{%1, %0|%0, %1}"
12549 [(set_attr "type" "bitmanip")
12550 (set_attr "mode" "<MODE>")])
12551
12552 (define_insn "*tbm_t1mskc_<mode>"
12553 [(set (match_operand:SWI48 0 "register_operand" "=r")
12554 (ior:SWI48
12555 (plus:SWI48
12556 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12557 (const_int 1))
12558 (not:SWI48
12559 (match_dup 1))))
12560 (clobber (reg:CC FLAGS_REG))]
12561 "TARGET_TBM"
12562 "t1mskc\t{%1, %0|%0, %1}"
12563 [(set_attr "type" "bitmanip")
12564 (set_attr "mode" "<MODE>")])
12565
12566 (define_insn "*tbm_tzmsk_<mode>"
12567 [(set (match_operand:SWI48 0 "register_operand" "=r")
12568 (and:SWI48
12569 (plus:SWI48
12570 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12571 (const_int -1))
12572 (not:SWI48
12573 (match_dup 1))))
12574 (clobber (reg:CC FLAGS_REG))]
12575 "TARGET_TBM"
12576 "tzmsk\t{%1, %0|%0, %1}"
12577 [(set_attr "type" "bitmanip")
12578 (set_attr "mode" "<MODE>")])
12579
12580 (define_insn "bsr_rex64"
12581 [(set (match_operand:DI 0 "register_operand" "=r")
12582 (minus:DI (const_int 63)
12583 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12584 (clobber (reg:CC FLAGS_REG))]
12585 "TARGET_64BIT"
12586 "bsr{q}\t{%1, %0|%0, %1}"
12587 [(set_attr "type" "alu1")
12588 (set_attr "prefix_0f" "1")
12589 (set_attr "mode" "DI")])
12590
12591 (define_insn "bsr"
12592 [(set (match_operand:SI 0 "register_operand" "=r")
12593 (minus:SI (const_int 31)
12594 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12595 (clobber (reg:CC FLAGS_REG))]
12596 ""
12597 "bsr{l}\t{%1, %0|%0, %1}"
12598 [(set_attr "type" "alu1")
12599 (set_attr "prefix_0f" "1")
12600 (set_attr "mode" "SI")])
12601
12602 (define_insn "*bsrhi"
12603 [(set (match_operand:HI 0 "register_operand" "=r")
12604 (minus:HI (const_int 15)
12605 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12606 (clobber (reg:CC FLAGS_REG))]
12607 ""
12608 "bsr{w}\t{%1, %0|%0, %1}"
12609 [(set_attr "type" "alu1")
12610 (set_attr "prefix_0f" "1")
12611 (set_attr "mode" "HI")])
12612
12613 (define_insn "popcount<mode>2"
12614 [(set (match_operand:SWI248 0 "register_operand" "=r")
12615 (popcount:SWI248
12616 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12617 (clobber (reg:CC FLAGS_REG))]
12618 "TARGET_POPCNT"
12619 {
12620 #if TARGET_MACHO
12621 return "popcnt\t{%1, %0|%0, %1}";
12622 #else
12623 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12624 #endif
12625 }
12626 [(set_attr "prefix_rep" "1")
12627 (set_attr "type" "bitmanip")
12628 (set_attr "mode" "<MODE>")])
12629
12630 (define_insn "*popcount<mode>2_cmp"
12631 [(set (reg FLAGS_REG)
12632 (compare
12633 (popcount:SWI248
12634 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12635 (const_int 0)))
12636 (set (match_operand:SWI248 0 "register_operand" "=r")
12637 (popcount:SWI248 (match_dup 1)))]
12638 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12639 {
12640 #if TARGET_MACHO
12641 return "popcnt\t{%1, %0|%0, %1}";
12642 #else
12643 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12644 #endif
12645 }
12646 [(set_attr "prefix_rep" "1")
12647 (set_attr "type" "bitmanip")
12648 (set_attr "mode" "<MODE>")])
12649
12650 (define_insn "*popcountsi2_cmp_zext"
12651 [(set (reg FLAGS_REG)
12652 (compare
12653 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12654 (const_int 0)))
12655 (set (match_operand:DI 0 "register_operand" "=r")
12656 (zero_extend:DI(popcount:SI (match_dup 1))))]
12657 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12658 {
12659 #if TARGET_MACHO
12660 return "popcnt\t{%1, %0|%0, %1}";
12661 #else
12662 return "popcnt{l}\t{%1, %0|%0, %1}";
12663 #endif
12664 }
12665 [(set_attr "prefix_rep" "1")
12666 (set_attr "type" "bitmanip")
12667 (set_attr "mode" "SI")])
12668
12669 (define_expand "bswapdi2"
12670 [(set (match_operand:DI 0 "register_operand")
12671 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12672 ""
12673 {
12674 if (TARGET_64BIT && !TARGET_MOVBE)
12675 operands[1] = force_reg (DImode, operands[1]);
12676 })
12677
12678 (define_insn_and_split "*bswapdi2_doubleword"
12679 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12680 (bswap:DI
12681 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12682 "!TARGET_64BIT
12683 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12684 "#"
12685 "&& reload_completed"
12686 [(set (match_dup 2)
12687 (bswap:SI (match_dup 1)))
12688 (set (match_dup 0)
12689 (bswap:SI (match_dup 3)))]
12690 {
12691 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12692
12693 if (REG_P (operands[0]) && REG_P (operands[1]))
12694 {
12695 emit_insn (gen_swapsi (operands[0], operands[2]));
12696 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12697 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12698 DONE;
12699 }
12700
12701 if (!TARGET_MOVBE)
12702 {
12703 if (MEM_P (operands[0]))
12704 {
12705 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12706 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12707
12708 emit_move_insn (operands[0], operands[3]);
12709 emit_move_insn (operands[2], operands[1]);
12710 }
12711 if (MEM_P (operands[1]))
12712 {
12713 emit_move_insn (operands[2], operands[1]);
12714 emit_move_insn (operands[0], operands[3]);
12715
12716 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12717 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12718 }
12719 DONE;
12720 }
12721 })
12722
12723 (define_expand "bswapsi2"
12724 [(set (match_operand:SI 0 "register_operand")
12725 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12726 ""
12727 {
12728 if (TARGET_MOVBE)
12729 ;
12730 else if (TARGET_BSWAP)
12731 operands[1] = force_reg (SImode, operands[1]);
12732 else
12733 {
12734 rtx x = operands[0];
12735
12736 emit_move_insn (x, operands[1]);
12737 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12738 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12739 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12740 DONE;
12741 }
12742 })
12743
12744 (define_insn "*bswap<mode>2_movbe"
12745 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12746 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12747 "TARGET_MOVBE
12748 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12749 "@
12750 bswap\t%0
12751 movbe\t{%1, %0|%0, %1}
12752 movbe\t{%1, %0|%0, %1}"
12753 [(set_attr "type" "bitmanip,imov,imov")
12754 (set_attr "modrm" "0,1,1")
12755 (set_attr "prefix_0f" "*,1,1")
12756 (set_attr "prefix_extra" "*,1,1")
12757 (set_attr "mode" "<MODE>")])
12758
12759 (define_insn "*bswap<mode>2"
12760 [(set (match_operand:SWI48 0 "register_operand" "=r")
12761 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12762 "TARGET_BSWAP"
12763 "bswap\t%0"
12764 [(set_attr "type" "bitmanip")
12765 (set_attr "modrm" "0")
12766 (set_attr "mode" "<MODE>")])
12767
12768 (define_insn "*bswaphi_lowpart_1"
12769 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12770 (bswap:HI (match_dup 0)))
12771 (clobber (reg:CC FLAGS_REG))]
12772 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12773 "@
12774 xchg{b}\t{%h0, %b0|%b0, %h0}
12775 rol{w}\t{$8, %0|%0, 8}"
12776 [(set_attr "length" "2,4")
12777 (set_attr "mode" "QI,HI")])
12778
12779 (define_insn "bswaphi_lowpart"
12780 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12781 (bswap:HI (match_dup 0)))
12782 (clobber (reg:CC FLAGS_REG))]
12783 ""
12784 "rol{w}\t{$8, %0|%0, 8}"
12785 [(set_attr "length" "4")
12786 (set_attr "mode" "HI")])
12787
12788 (define_expand "paritydi2"
12789 [(set (match_operand:DI 0 "register_operand")
12790 (parity:DI (match_operand:DI 1 "register_operand")))]
12791 "! TARGET_POPCNT"
12792 {
12793 rtx scratch = gen_reg_rtx (QImode);
12794 rtx cond;
12795
12796 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12797 NULL_RTX, operands[1]));
12798
12799 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12800 gen_rtx_REG (CCmode, FLAGS_REG),
12801 const0_rtx);
12802 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12803
12804 if (TARGET_64BIT)
12805 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12806 else
12807 {
12808 rtx tmp = gen_reg_rtx (SImode);
12809
12810 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12811 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12812 }
12813 DONE;
12814 })
12815
12816 (define_expand "paritysi2"
12817 [(set (match_operand:SI 0 "register_operand")
12818 (parity:SI (match_operand:SI 1 "register_operand")))]
12819 "! TARGET_POPCNT"
12820 {
12821 rtx scratch = gen_reg_rtx (QImode);
12822 rtx cond;
12823
12824 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12825
12826 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12827 gen_rtx_REG (CCmode, FLAGS_REG),
12828 const0_rtx);
12829 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12830
12831 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12832 DONE;
12833 })
12834
12835 (define_insn_and_split "paritydi2_cmp"
12836 [(set (reg:CC FLAGS_REG)
12837 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12838 UNSPEC_PARITY))
12839 (clobber (match_scratch:DI 0 "=r"))
12840 (clobber (match_scratch:SI 1 "=&r"))
12841 (clobber (match_scratch:HI 2 "=Q"))]
12842 "! TARGET_POPCNT"
12843 "#"
12844 "&& reload_completed"
12845 [(parallel
12846 [(set (match_dup 1)
12847 (xor:SI (match_dup 1) (match_dup 4)))
12848 (clobber (reg:CC FLAGS_REG))])
12849 (parallel
12850 [(set (reg:CC FLAGS_REG)
12851 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12852 (clobber (match_dup 1))
12853 (clobber (match_dup 2))])]
12854 {
12855 operands[4] = gen_lowpart (SImode, operands[3]);
12856
12857 if (TARGET_64BIT)
12858 {
12859 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12860 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12861 }
12862 else
12863 operands[1] = gen_highpart (SImode, operands[3]);
12864 })
12865
12866 (define_insn_and_split "paritysi2_cmp"
12867 [(set (reg:CC FLAGS_REG)
12868 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12869 UNSPEC_PARITY))
12870 (clobber (match_scratch:SI 0 "=r"))
12871 (clobber (match_scratch:HI 1 "=&Q"))]
12872 "! TARGET_POPCNT"
12873 "#"
12874 "&& reload_completed"
12875 [(parallel
12876 [(set (match_dup 1)
12877 (xor:HI (match_dup 1) (match_dup 3)))
12878 (clobber (reg:CC FLAGS_REG))])
12879 (parallel
12880 [(set (reg:CC FLAGS_REG)
12881 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12882 (clobber (match_dup 1))])]
12883 {
12884 operands[3] = gen_lowpart (HImode, operands[2]);
12885
12886 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12887 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12888 })
12889
12890 (define_insn "*parityhi2_cmp"
12891 [(set (reg:CC FLAGS_REG)
12892 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12893 UNSPEC_PARITY))
12894 (clobber (match_scratch:HI 0 "=Q"))]
12895 "! TARGET_POPCNT"
12896 "xor{b}\t{%h0, %b0|%b0, %h0}"
12897 [(set_attr "length" "2")
12898 (set_attr "mode" "HI")])
12899
12900 \f
12901 ;; Thread-local storage patterns for ELF.
12902 ;;
12903 ;; Note that these code sequences must appear exactly as shown
12904 ;; in order to allow linker relaxation.
12905
12906 (define_insn "*tls_global_dynamic_32_gnu"
12907 [(set (match_operand:SI 0 "register_operand" "=a")
12908 (unspec:SI
12909 [(match_operand:SI 1 "register_operand" "b")
12910 (match_operand 2 "tls_symbolic_operand")
12911 (match_operand 3 "constant_call_address_operand" "z")]
12912 UNSPEC_TLS_GD))
12913 (clobber (match_scratch:SI 4 "=d"))
12914 (clobber (match_scratch:SI 5 "=c"))
12915 (clobber (reg:CC FLAGS_REG))]
12916 "!TARGET_64BIT && TARGET_GNU_TLS"
12917 {
12918 output_asm_insn
12919 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12920 if (TARGET_SUN_TLS)
12921 #ifdef HAVE_AS_IX86_TLSGDPLT
12922 return "call\t%a2@tlsgdplt";
12923 #else
12924 return "call\t%p3@plt";
12925 #endif
12926 return "call\t%P3";
12927 }
12928 [(set_attr "type" "multi")
12929 (set_attr "length" "12")])
12930
12931 (define_expand "tls_global_dynamic_32"
12932 [(parallel
12933 [(set (match_operand:SI 0 "register_operand")
12934 (unspec:SI [(match_operand:SI 2 "register_operand")
12935 (match_operand 1 "tls_symbolic_operand")
12936 (match_operand 3 "constant_call_address_operand")]
12937 UNSPEC_TLS_GD))
12938 (clobber (match_scratch:SI 4))
12939 (clobber (match_scratch:SI 5))
12940 (clobber (reg:CC FLAGS_REG))])])
12941
12942 (define_insn "*tls_global_dynamic_64_<mode>"
12943 [(set (match_operand:P 0 "register_operand" "=a")
12944 (call:P
12945 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12946 (match_operand 3)))
12947 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12948 UNSPEC_TLS_GD)]
12949 "TARGET_64BIT"
12950 {
12951 if (!TARGET_X32)
12952 fputs (ASM_BYTE "0x66\n", asm_out_file);
12953 output_asm_insn
12954 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12955 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12956 fputs ("\trex64\n", asm_out_file);
12957 if (TARGET_SUN_TLS)
12958 return "call\t%p2@plt";
12959 return "call\t%P2";
12960 }
12961 [(set_attr "type" "multi")
12962 (set (attr "length")
12963 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12964
12965 (define_expand "tls_global_dynamic_64_<mode>"
12966 [(parallel
12967 [(set (match_operand:P 0 "register_operand")
12968 (call:P
12969 (mem:QI (match_operand 2 "constant_call_address_operand"))
12970 (const_int 0)))
12971 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12972 UNSPEC_TLS_GD)])]
12973 "TARGET_64BIT")
12974
12975 (define_insn "*tls_local_dynamic_base_32_gnu"
12976 [(set (match_operand:SI 0 "register_operand" "=a")
12977 (unspec:SI
12978 [(match_operand:SI 1 "register_operand" "b")
12979 (match_operand 2 "constant_call_address_operand" "z")]
12980 UNSPEC_TLS_LD_BASE))
12981 (clobber (match_scratch:SI 3 "=d"))
12982 (clobber (match_scratch:SI 4 "=c"))
12983 (clobber (reg:CC FLAGS_REG))]
12984 "!TARGET_64BIT && TARGET_GNU_TLS"
12985 {
12986 output_asm_insn
12987 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12988 if (TARGET_SUN_TLS)
12989 #ifdef HAVE_AS_IX86_TLSLDMPLT
12990 return "call\t%&@tlsldmplt";
12991 #else
12992 return "call\t%p2@plt";
12993 #endif
12994 return "call\t%P2";
12995 }
12996 [(set_attr "type" "multi")
12997 (set_attr "length" "11")])
12998
12999 (define_expand "tls_local_dynamic_base_32"
13000 [(parallel
13001 [(set (match_operand:SI 0 "register_operand")
13002 (unspec:SI
13003 [(match_operand:SI 1 "register_operand")
13004 (match_operand 2 "constant_call_address_operand")]
13005 UNSPEC_TLS_LD_BASE))
13006 (clobber (match_scratch:SI 3))
13007 (clobber (match_scratch:SI 4))
13008 (clobber (reg:CC FLAGS_REG))])])
13009
13010 (define_insn "*tls_local_dynamic_base_64_<mode>"
13011 [(set (match_operand:P 0 "register_operand" "=a")
13012 (call:P
13013 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
13014 (match_operand 2)))
13015 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13016 "TARGET_64BIT"
13017 {
13018 output_asm_insn
13019 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13020 if (TARGET_SUN_TLS)
13021 return "call\t%p1@plt";
13022 return "call\t%P1";
13023 }
13024 [(set_attr "type" "multi")
13025 (set_attr "length" "12")])
13026
13027 (define_expand "tls_local_dynamic_base_64_<mode>"
13028 [(parallel
13029 [(set (match_operand:P 0 "register_operand")
13030 (call:P
13031 (mem:QI (match_operand 1 "constant_call_address_operand"))
13032 (const_int 0)))
13033 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13034 "TARGET_64BIT")
13035
13036 ;; Local dynamic of a single variable is a lose. Show combine how
13037 ;; to convert that back to global dynamic.
13038
13039 (define_insn_and_split "*tls_local_dynamic_32_once"
13040 [(set (match_operand:SI 0 "register_operand" "=a")
13041 (plus:SI
13042 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13043 (match_operand 2 "constant_call_address_operand" "z")]
13044 UNSPEC_TLS_LD_BASE)
13045 (const:SI (unspec:SI
13046 [(match_operand 3 "tls_symbolic_operand")]
13047 UNSPEC_DTPOFF))))
13048 (clobber (match_scratch:SI 4 "=d"))
13049 (clobber (match_scratch:SI 5 "=c"))
13050 (clobber (reg:CC FLAGS_REG))]
13051 ""
13052 "#"
13053 ""
13054 [(parallel
13055 [(set (match_dup 0)
13056 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13057 UNSPEC_TLS_GD))
13058 (clobber (match_dup 4))
13059 (clobber (match_dup 5))
13060 (clobber (reg:CC FLAGS_REG))])])
13061
13062 ;; Segment register for the thread base ptr load
13063 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13064
13065 ;; Load and add the thread base pointer from %<tp_seg>:0.
13066 (define_insn "*load_tp_x32"
13067 [(set (match_operand:SI 0 "register_operand" "=r")
13068 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13069 "TARGET_X32"
13070 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13071 [(set_attr "type" "imov")
13072 (set_attr "modrm" "0")
13073 (set_attr "length" "7")
13074 (set_attr "memory" "load")
13075 (set_attr "imm_disp" "false")])
13076
13077 (define_insn "*load_tp_x32_zext"
13078 [(set (match_operand:DI 0 "register_operand" "=r")
13079 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13080 "TARGET_X32"
13081 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13082 [(set_attr "type" "imov")
13083 (set_attr "modrm" "0")
13084 (set_attr "length" "7")
13085 (set_attr "memory" "load")
13086 (set_attr "imm_disp" "false")])
13087
13088 (define_insn "*load_tp_<mode>"
13089 [(set (match_operand:P 0 "register_operand" "=r")
13090 (unspec:P [(const_int 0)] UNSPEC_TP))]
13091 "!TARGET_X32"
13092 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13093 [(set_attr "type" "imov")
13094 (set_attr "modrm" "0")
13095 (set_attr "length" "7")
13096 (set_attr "memory" "load")
13097 (set_attr "imm_disp" "false")])
13098
13099 (define_insn "*add_tp_x32"
13100 [(set (match_operand:SI 0 "register_operand" "=r")
13101 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13102 (match_operand:SI 1 "register_operand" "0")))
13103 (clobber (reg:CC FLAGS_REG))]
13104 "TARGET_X32"
13105 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13106 [(set_attr "type" "alu")
13107 (set_attr "modrm" "0")
13108 (set_attr "length" "7")
13109 (set_attr "memory" "load")
13110 (set_attr "imm_disp" "false")])
13111
13112 (define_insn "*add_tp_x32_zext"
13113 [(set (match_operand:DI 0 "register_operand" "=r")
13114 (zero_extend:DI
13115 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13116 (match_operand:SI 1 "register_operand" "0"))))
13117 (clobber (reg:CC FLAGS_REG))]
13118 "TARGET_X32"
13119 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13120 [(set_attr "type" "alu")
13121 (set_attr "modrm" "0")
13122 (set_attr "length" "7")
13123 (set_attr "memory" "load")
13124 (set_attr "imm_disp" "false")])
13125
13126 (define_insn "*add_tp_<mode>"
13127 [(set (match_operand:P 0 "register_operand" "=r")
13128 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13129 (match_operand:P 1 "register_operand" "0")))
13130 (clobber (reg:CC FLAGS_REG))]
13131 "!TARGET_X32"
13132 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13133 [(set_attr "type" "alu")
13134 (set_attr "modrm" "0")
13135 (set_attr "length" "7")
13136 (set_attr "memory" "load")
13137 (set_attr "imm_disp" "false")])
13138
13139 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13140 ;; %rax as destination of the initial executable code sequence.
13141 (define_insn "tls_initial_exec_64_sun"
13142 [(set (match_operand:DI 0 "register_operand" "=a")
13143 (unspec:DI
13144 [(match_operand 1 "tls_symbolic_operand")]
13145 UNSPEC_TLS_IE_SUN))
13146 (clobber (reg:CC FLAGS_REG))]
13147 "TARGET_64BIT && TARGET_SUN_TLS"
13148 {
13149 output_asm_insn
13150 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13151 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13152 }
13153 [(set_attr "type" "multi")])
13154
13155 ;; GNU2 TLS patterns can be split.
13156
13157 (define_expand "tls_dynamic_gnu2_32"
13158 [(set (match_dup 3)
13159 (plus:SI (match_operand:SI 2 "register_operand")
13160 (const:SI
13161 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13162 UNSPEC_TLSDESC))))
13163 (parallel
13164 [(set (match_operand:SI 0 "register_operand")
13165 (unspec:SI [(match_dup 1) (match_dup 3)
13166 (match_dup 2) (reg:SI SP_REG)]
13167 UNSPEC_TLSDESC))
13168 (clobber (reg:CC FLAGS_REG))])]
13169 "!TARGET_64BIT && TARGET_GNU2_TLS"
13170 {
13171 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13172 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13173 })
13174
13175 (define_insn "*tls_dynamic_gnu2_lea_32"
13176 [(set (match_operand:SI 0 "register_operand" "=r")
13177 (plus:SI (match_operand:SI 1 "register_operand" "b")
13178 (const:SI
13179 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13180 UNSPEC_TLSDESC))))]
13181 "!TARGET_64BIT && TARGET_GNU2_TLS"
13182 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13183 [(set_attr "type" "lea")
13184 (set_attr "mode" "SI")
13185 (set_attr "length" "6")
13186 (set_attr "length_address" "4")])
13187
13188 (define_insn "*tls_dynamic_gnu2_call_32"
13189 [(set (match_operand:SI 0 "register_operand" "=a")
13190 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13191 (match_operand:SI 2 "register_operand" "0")
13192 ;; we have to make sure %ebx still points to the GOT
13193 (match_operand:SI 3 "register_operand" "b")
13194 (reg:SI SP_REG)]
13195 UNSPEC_TLSDESC))
13196 (clobber (reg:CC FLAGS_REG))]
13197 "!TARGET_64BIT && TARGET_GNU2_TLS"
13198 "call\t{*%a1@TLSCALL(%2)|[DWORD 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_32"
13204 [(set (match_operand:SI 0 "register_operand" "=&a")
13205 (plus:SI
13206 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13207 (match_operand:SI 4)
13208 (match_operand:SI 2 "register_operand" "b")
13209 (reg:SI SP_REG)]
13210 UNSPEC_TLSDESC)
13211 (const:SI (unspec:SI
13212 [(match_operand 1 "tls_symbolic_operand")]
13213 UNSPEC_DTPOFF))))
13214 (clobber (reg:CC FLAGS_REG))]
13215 "!TARGET_64BIT && TARGET_GNU2_TLS"
13216 "#"
13217 ""
13218 [(set (match_dup 0) (match_dup 5))]
13219 {
13220 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13221 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13222 })
13223
13224 (define_expand "tls_dynamic_gnu2_64"
13225 [(set (match_dup 2)
13226 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13227 UNSPEC_TLSDESC))
13228 (parallel
13229 [(set (match_operand:DI 0 "register_operand")
13230 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13231 UNSPEC_TLSDESC))
13232 (clobber (reg:CC FLAGS_REG))])]
13233 "TARGET_64BIT && TARGET_GNU2_TLS"
13234 {
13235 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13236 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13237 })
13238
13239 (define_insn "*tls_dynamic_gnu2_lea_64"
13240 [(set (match_operand:DI 0 "register_operand" "=r")
13241 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13242 UNSPEC_TLSDESC))]
13243 "TARGET_64BIT && TARGET_GNU2_TLS"
13244 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13245 [(set_attr "type" "lea")
13246 (set_attr "mode" "DI")
13247 (set_attr "length" "7")
13248 (set_attr "length_address" "4")])
13249
13250 (define_insn "*tls_dynamic_gnu2_call_64"
13251 [(set (match_operand:DI 0 "register_operand" "=a")
13252 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13253 (match_operand:DI 2 "register_operand" "0")
13254 (reg:DI SP_REG)]
13255 UNSPEC_TLSDESC))
13256 (clobber (reg:CC FLAGS_REG))]
13257 "TARGET_64BIT && TARGET_GNU2_TLS"
13258 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13259 [(set_attr "type" "call")
13260 (set_attr "length" "2")
13261 (set_attr "length_address" "0")])
13262
13263 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13264 [(set (match_operand:DI 0 "register_operand" "=&a")
13265 (plus:DI
13266 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13267 (match_operand:DI 3)
13268 (reg:DI SP_REG)]
13269 UNSPEC_TLSDESC)
13270 (const:DI (unspec:DI
13271 [(match_operand 1 "tls_symbolic_operand")]
13272 UNSPEC_DTPOFF))))
13273 (clobber (reg:CC FLAGS_REG))]
13274 "TARGET_64BIT && TARGET_GNU2_TLS"
13275 "#"
13276 ""
13277 [(set (match_dup 0) (match_dup 4))]
13278 {
13279 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13280 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13281 })
13282 \f
13283 ;; These patterns match the binary 387 instructions for addM3, subM3,
13284 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13285 ;; SFmode. The first is the normal insn, the second the same insn but
13286 ;; with one operand a conversion, and the third the same insn but with
13287 ;; the other operand a conversion. The conversion may be SFmode or
13288 ;; SImode if the target mode DFmode, but only SImode if the target mode
13289 ;; is SFmode.
13290
13291 ;; Gcc is slightly more smart about handling normal two address instructions
13292 ;; so use special patterns for add and mull.
13293
13294 (define_insn "*fop_<mode>_comm_mixed"
13295 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13296 (match_operator:MODEF 3 "binary_fp_operator"
13297 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13298 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13299 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13300 && COMMUTATIVE_ARITH_P (operands[3])
13301 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13302 "* return output_387_binary_op (insn, operands);"
13303 [(set (attr "type")
13304 (if_then_else (eq_attr "alternative" "1,2")
13305 (if_then_else (match_operand:MODEF 3 "mult_operator")
13306 (const_string "ssemul")
13307 (const_string "sseadd"))
13308 (if_then_else (match_operand:MODEF 3 "mult_operator")
13309 (const_string "fmul")
13310 (const_string "fop"))))
13311 (set_attr "isa" "*,noavx,avx")
13312 (set_attr "prefix" "orig,orig,vex")
13313 (set_attr "mode" "<MODE>")])
13314
13315 (define_insn "*fop_<mode>_comm_sse"
13316 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13317 (match_operator:MODEF 3 "binary_fp_operator"
13318 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13319 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13320 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13321 && COMMUTATIVE_ARITH_P (operands[3])
13322 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13323 "* return output_387_binary_op (insn, operands);"
13324 [(set (attr "type")
13325 (if_then_else (match_operand:MODEF 3 "mult_operator")
13326 (const_string "ssemul")
13327 (const_string "sseadd")))
13328 (set_attr "isa" "noavx,avx")
13329 (set_attr "prefix" "orig,vex")
13330 (set_attr "mode" "<MODE>")])
13331
13332 (define_insn "*fop_<mode>_comm_i387"
13333 [(set (match_operand:MODEF 0 "register_operand" "=f")
13334 (match_operator:MODEF 3 "binary_fp_operator"
13335 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13336 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13337 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13338 && COMMUTATIVE_ARITH_P (operands[3])
13339 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13340 "* return output_387_binary_op (insn, operands);"
13341 [(set (attr "type")
13342 (if_then_else (match_operand:MODEF 3 "mult_operator")
13343 (const_string "fmul")
13344 (const_string "fop")))
13345 (set_attr "mode" "<MODE>")])
13346
13347 (define_insn "*fop_<mode>_1_mixed"
13348 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13349 (match_operator:MODEF 3 "binary_fp_operator"
13350 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13351 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13352 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
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 [(and (eq_attr "alternative" "2,3")
13358 (match_operand:MODEF 3 "mult_operator"))
13359 (const_string "ssemul")
13360 (and (eq_attr "alternative" "2,3")
13361 (match_operand:MODEF 3 "div_operator"))
13362 (const_string "ssediv")
13363 (eq_attr "alternative" "2,3")
13364 (const_string "sseadd")
13365 (match_operand:MODEF 3 "mult_operator")
13366 (const_string "fmul")
13367 (match_operand:MODEF 3 "div_operator")
13368 (const_string "fdiv")
13369 ]
13370 (const_string "fop")))
13371 (set_attr "isa" "*,*,noavx,avx")
13372 (set_attr "prefix" "orig,orig,orig,vex")
13373 (set_attr "mode" "<MODE>")])
13374
13375 (define_insn "*rcpsf2_sse"
13376 [(set (match_operand:SF 0 "register_operand" "=x")
13377 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13378 UNSPEC_RCP))]
13379 "TARGET_SSE_MATH"
13380 "%vrcpss\t{%1, %d0|%d0, %1}"
13381 [(set_attr "type" "sse")
13382 (set_attr "atom_sse_attr" "rcp")
13383 (set_attr "prefix" "maybe_vex")
13384 (set_attr "mode" "SF")])
13385
13386 (define_insn "*fop_<mode>_1_sse"
13387 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13388 (match_operator:MODEF 3 "binary_fp_operator"
13389 [(match_operand:MODEF 1 "register_operand" "0,x")
13390 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13391 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13392 && !COMMUTATIVE_ARITH_P (operands[3])"
13393 "* return output_387_binary_op (insn, operands);"
13394 [(set (attr "type")
13395 (cond [(match_operand:MODEF 3 "mult_operator")
13396 (const_string "ssemul")
13397 (match_operand:MODEF 3 "div_operator")
13398 (const_string "ssediv")
13399 ]
13400 (const_string "sseadd")))
13401 (set_attr "isa" "noavx,avx")
13402 (set_attr "prefix" "orig,vex")
13403 (set_attr "mode" "<MODE>")])
13404
13405 ;; This pattern is not fully shadowed by the pattern above.
13406 (define_insn "*fop_<mode>_1_i387"
13407 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13408 (match_operator:MODEF 3 "binary_fp_operator"
13409 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13410 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13411 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13412 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13413 && !COMMUTATIVE_ARITH_P (operands[3])
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:MODEF 3 "mult_operator")
13418 (const_string "fmul")
13419 (match_operand:MODEF 3 "div_operator")
13420 (const_string "fdiv")
13421 ]
13422 (const_string "fop")))
13423 (set_attr "mode" "<MODE>")])
13424
13425 ;; ??? Add SSE splitters for these!
13426 (define_insn "*fop_<MODEF:mode>_2_i387"
13427 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13428 (match_operator:MODEF 3 "binary_fp_operator"
13429 [(float:MODEF
13430 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13431 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13432 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13433 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13434 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13435 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13436 [(set (attr "type")
13437 (cond [(match_operand:MODEF 3 "mult_operator")
13438 (const_string "fmul")
13439 (match_operand:MODEF 3 "div_operator")
13440 (const_string "fdiv")
13441 ]
13442 (const_string "fop")))
13443 (set_attr "fp_int_src" "true")
13444 (set_attr "mode" "<SWI24:MODE>")])
13445
13446 (define_insn "*fop_<MODEF:mode>_3_i387"
13447 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13448 (match_operator:MODEF 3 "binary_fp_operator"
13449 [(match_operand:MODEF 1 "register_operand" "0,0")
13450 (float:MODEF
13451 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13452 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13453 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13454 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13455 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13456 [(set (attr "type")
13457 (cond [(match_operand:MODEF 3 "mult_operator")
13458 (const_string "fmul")
13459 (match_operand:MODEF 3 "div_operator")
13460 (const_string "fdiv")
13461 ]
13462 (const_string "fop")))
13463 (set_attr "fp_int_src" "true")
13464 (set_attr "mode" "<MODE>")])
13465
13466 (define_insn "*fop_df_4_i387"
13467 [(set (match_operand:DF 0 "register_operand" "=f,f")
13468 (match_operator:DF 3 "binary_fp_operator"
13469 [(float_extend:DF
13470 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13471 (match_operand:DF 2 "register_operand" "0,f")]))]
13472 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13473 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13474 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13475 "* return output_387_binary_op (insn, operands);"
13476 [(set (attr "type")
13477 (cond [(match_operand:DF 3 "mult_operator")
13478 (const_string "fmul")
13479 (match_operand:DF 3 "div_operator")
13480 (const_string "fdiv")
13481 ]
13482 (const_string "fop")))
13483 (set_attr "mode" "SF")])
13484
13485 (define_insn "*fop_df_5_i387"
13486 [(set (match_operand:DF 0 "register_operand" "=f,f")
13487 (match_operator:DF 3 "binary_fp_operator"
13488 [(match_operand:DF 1 "register_operand" "0,f")
13489 (float_extend:DF
13490 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13491 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13492 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13493 "* return output_387_binary_op (insn, operands);"
13494 [(set (attr "type")
13495 (cond [(match_operand:DF 3 "mult_operator")
13496 (const_string "fmul")
13497 (match_operand:DF 3 "div_operator")
13498 (const_string "fdiv")
13499 ]
13500 (const_string "fop")))
13501 (set_attr "mode" "SF")])
13502
13503 (define_insn "*fop_df_6_i387"
13504 [(set (match_operand:DF 0 "register_operand" "=f,f")
13505 (match_operator:DF 3 "binary_fp_operator"
13506 [(float_extend:DF
13507 (match_operand:SF 1 "register_operand" "0,f"))
13508 (float_extend:DF
13509 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13510 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13511 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13512 "* return output_387_binary_op (insn, operands);"
13513 [(set (attr "type")
13514 (cond [(match_operand:DF 3 "mult_operator")
13515 (const_string "fmul")
13516 (match_operand:DF 3 "div_operator")
13517 (const_string "fdiv")
13518 ]
13519 (const_string "fop")))
13520 (set_attr "mode" "SF")])
13521
13522 (define_insn "*fop_xf_comm_i387"
13523 [(set (match_operand:XF 0 "register_operand" "=f")
13524 (match_operator:XF 3 "binary_fp_operator"
13525 [(match_operand:XF 1 "register_operand" "%0")
13526 (match_operand:XF 2 "register_operand" "f")]))]
13527 "TARGET_80387
13528 && COMMUTATIVE_ARITH_P (operands[3])"
13529 "* return output_387_binary_op (insn, operands);"
13530 [(set (attr "type")
13531 (if_then_else (match_operand:XF 3 "mult_operator")
13532 (const_string "fmul")
13533 (const_string "fop")))
13534 (set_attr "mode" "XF")])
13535
13536 (define_insn "*fop_xf_1_i387"
13537 [(set (match_operand:XF 0 "register_operand" "=f,f")
13538 (match_operator:XF 3 "binary_fp_operator"
13539 [(match_operand:XF 1 "register_operand" "0,f")
13540 (match_operand:XF 2 "register_operand" "f,0")]))]
13541 "TARGET_80387
13542 && !COMMUTATIVE_ARITH_P (operands[3])"
13543 "* return output_387_binary_op (insn, operands);"
13544 [(set (attr "type")
13545 (cond [(match_operand:XF 3 "mult_operator")
13546 (const_string "fmul")
13547 (match_operand:XF 3 "div_operator")
13548 (const_string "fdiv")
13549 ]
13550 (const_string "fop")))
13551 (set_attr "mode" "XF")])
13552
13553 (define_insn "*fop_xf_2_i387"
13554 [(set (match_operand:XF 0 "register_operand" "=f,f")
13555 (match_operator:XF 3 "binary_fp_operator"
13556 [(float:XF
13557 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13558 (match_operand:XF 2 "register_operand" "0,0")]))]
13559 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13560 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13561 [(set (attr "type")
13562 (cond [(match_operand:XF 3 "mult_operator")
13563 (const_string "fmul")
13564 (match_operand:XF 3 "div_operator")
13565 (const_string "fdiv")
13566 ]
13567 (const_string "fop")))
13568 (set_attr "fp_int_src" "true")
13569 (set_attr "mode" "<MODE>")])
13570
13571 (define_insn "*fop_xf_3_i387"
13572 [(set (match_operand:XF 0 "register_operand" "=f,f")
13573 (match_operator:XF 3 "binary_fp_operator"
13574 [(match_operand:XF 1 "register_operand" "0,0")
13575 (float:XF
13576 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13577 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13578 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13579 [(set (attr "type")
13580 (cond [(match_operand:XF 3 "mult_operator")
13581 (const_string "fmul")
13582 (match_operand:XF 3 "div_operator")
13583 (const_string "fdiv")
13584 ]
13585 (const_string "fop")))
13586 (set_attr "fp_int_src" "true")
13587 (set_attr "mode" "<MODE>")])
13588
13589 (define_insn "*fop_xf_4_i387"
13590 [(set (match_operand:XF 0 "register_operand" "=f,f")
13591 (match_operator:XF 3 "binary_fp_operator"
13592 [(float_extend:XF
13593 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13594 (match_operand:XF 2 "register_operand" "0,f")]))]
13595 "TARGET_80387"
13596 "* return output_387_binary_op (insn, operands);"
13597 [(set (attr "type")
13598 (cond [(match_operand:XF 3 "mult_operator")
13599 (const_string "fmul")
13600 (match_operand:XF 3 "div_operator")
13601 (const_string "fdiv")
13602 ]
13603 (const_string "fop")))
13604 (set_attr "mode" "<MODE>")])
13605
13606 (define_insn "*fop_xf_5_i387"
13607 [(set (match_operand:XF 0 "register_operand" "=f,f")
13608 (match_operator:XF 3 "binary_fp_operator"
13609 [(match_operand:XF 1 "register_operand" "0,f")
13610 (float_extend:XF
13611 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13612 "TARGET_80387"
13613 "* return output_387_binary_op (insn, operands);"
13614 [(set (attr "type")
13615 (cond [(match_operand:XF 3 "mult_operator")
13616 (const_string "fmul")
13617 (match_operand:XF 3 "div_operator")
13618 (const_string "fdiv")
13619 ]
13620 (const_string "fop")))
13621 (set_attr "mode" "<MODE>")])
13622
13623 (define_insn "*fop_xf_6_i387"
13624 [(set (match_operand:XF 0 "register_operand" "=f,f")
13625 (match_operator:XF 3 "binary_fp_operator"
13626 [(float_extend:XF
13627 (match_operand:MODEF 1 "register_operand" "0,f"))
13628 (float_extend:XF
13629 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13630 "TARGET_80387"
13631 "* return output_387_binary_op (insn, operands);"
13632 [(set (attr "type")
13633 (cond [(match_operand:XF 3 "mult_operator")
13634 (const_string "fmul")
13635 (match_operand:XF 3 "div_operator")
13636 (const_string "fdiv")
13637 ]
13638 (const_string "fop")))
13639 (set_attr "mode" "<MODE>")])
13640
13641 (define_split
13642 [(set (match_operand 0 "register_operand")
13643 (match_operator 3 "binary_fp_operator"
13644 [(float (match_operand:SWI24 1 "register_operand"))
13645 (match_operand 2 "register_operand")]))]
13646 "reload_completed
13647 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13648 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13649 [(const_int 0)]
13650 {
13651 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13652 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13653 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13654 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13655 GET_MODE (operands[3]),
13656 operands[4],
13657 operands[2])));
13658 ix86_free_from_memory (GET_MODE (operands[1]));
13659 DONE;
13660 })
13661
13662 (define_split
13663 [(set (match_operand 0 "register_operand")
13664 (match_operator 3 "binary_fp_operator"
13665 [(match_operand 1 "register_operand")
13666 (float (match_operand:SWI24 2 "register_operand"))]))]
13667 "reload_completed
13668 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13669 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13670 [(const_int 0)]
13671 {
13672 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13673 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13674 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13675 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13676 GET_MODE (operands[3]),
13677 operands[1],
13678 operands[4])));
13679 ix86_free_from_memory (GET_MODE (operands[2]));
13680 DONE;
13681 })
13682 \f
13683 ;; FPU special functions.
13684
13685 ;; This pattern implements a no-op XFmode truncation for
13686 ;; all fancy i386 XFmode math functions.
13687
13688 (define_insn "truncxf<mode>2_i387_noop_unspec"
13689 [(set (match_operand:MODEF 0 "register_operand" "=f")
13690 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13691 UNSPEC_TRUNC_NOOP))]
13692 "TARGET_USE_FANCY_MATH_387"
13693 "* return output_387_reg_move (insn, operands);"
13694 [(set_attr "type" "fmov")
13695 (set_attr "mode" "<MODE>")])
13696
13697 (define_insn "sqrtxf2"
13698 [(set (match_operand:XF 0 "register_operand" "=f")
13699 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13700 "TARGET_USE_FANCY_MATH_387"
13701 "fsqrt"
13702 [(set_attr "type" "fpspc")
13703 (set_attr "mode" "XF")
13704 (set_attr "athlon_decode" "direct")
13705 (set_attr "amdfam10_decode" "direct")
13706 (set_attr "bdver1_decode" "direct")])
13707
13708 (define_insn "sqrt_extend<mode>xf2_i387"
13709 [(set (match_operand:XF 0 "register_operand" "=f")
13710 (sqrt:XF
13711 (float_extend:XF
13712 (match_operand:MODEF 1 "register_operand" "0"))))]
13713 "TARGET_USE_FANCY_MATH_387"
13714 "fsqrt"
13715 [(set_attr "type" "fpspc")
13716 (set_attr "mode" "XF")
13717 (set_attr "athlon_decode" "direct")
13718 (set_attr "amdfam10_decode" "direct")
13719 (set_attr "bdver1_decode" "direct")])
13720
13721 (define_insn "*rsqrtsf2_sse"
13722 [(set (match_operand:SF 0 "register_operand" "=x")
13723 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13724 UNSPEC_RSQRT))]
13725 "TARGET_SSE_MATH"
13726 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13727 [(set_attr "type" "sse")
13728 (set_attr "atom_sse_attr" "rcp")
13729 (set_attr "prefix" "maybe_vex")
13730 (set_attr "mode" "SF")])
13731
13732 (define_expand "rsqrtsf2"
13733 [(set (match_operand:SF 0 "register_operand")
13734 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13735 UNSPEC_RSQRT))]
13736 "TARGET_SSE_MATH"
13737 {
13738 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13739 DONE;
13740 })
13741
13742 (define_insn "*sqrt<mode>2_sse"
13743 [(set (match_operand:MODEF 0 "register_operand" "=x")
13744 (sqrt:MODEF
13745 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13746 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13747 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13748 [(set_attr "type" "sse")
13749 (set_attr "atom_sse_attr" "sqrt")
13750 (set_attr "prefix" "maybe_vex")
13751 (set_attr "mode" "<MODE>")
13752 (set_attr "athlon_decode" "*")
13753 (set_attr "amdfam10_decode" "*")
13754 (set_attr "bdver1_decode" "*")])
13755
13756 (define_expand "sqrt<mode>2"
13757 [(set (match_operand:MODEF 0 "register_operand")
13758 (sqrt:MODEF
13759 (match_operand:MODEF 1 "nonimmediate_operand")))]
13760 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13761 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13762 {
13763 if (<MODE>mode == SFmode
13764 && TARGET_SSE_MATH
13765 && TARGET_RECIP_SQRT
13766 && !optimize_function_for_size_p (cfun)
13767 && flag_finite_math_only && !flag_trapping_math
13768 && flag_unsafe_math_optimizations)
13769 {
13770 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13771 DONE;
13772 }
13773
13774 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13775 {
13776 rtx op0 = gen_reg_rtx (XFmode);
13777 rtx op1 = force_reg (<MODE>mode, operands[1]);
13778
13779 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13780 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13781 DONE;
13782 }
13783 })
13784
13785 (define_insn "fpremxf4_i387"
13786 [(set (match_operand:XF 0 "register_operand" "=f")
13787 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13788 (match_operand:XF 3 "register_operand" "1")]
13789 UNSPEC_FPREM_F))
13790 (set (match_operand:XF 1 "register_operand" "=u")
13791 (unspec:XF [(match_dup 2) (match_dup 3)]
13792 UNSPEC_FPREM_U))
13793 (set (reg:CCFP FPSR_REG)
13794 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13795 UNSPEC_C2_FLAG))]
13796 "TARGET_USE_FANCY_MATH_387"
13797 "fprem"
13798 [(set_attr "type" "fpspc")
13799 (set_attr "mode" "XF")])
13800
13801 (define_expand "fmodxf3"
13802 [(use (match_operand:XF 0 "register_operand"))
13803 (use (match_operand:XF 1 "general_operand"))
13804 (use (match_operand:XF 2 "general_operand"))]
13805 "TARGET_USE_FANCY_MATH_387"
13806 {
13807 rtx label = gen_label_rtx ();
13808
13809 rtx op1 = gen_reg_rtx (XFmode);
13810 rtx op2 = gen_reg_rtx (XFmode);
13811
13812 emit_move_insn (op2, operands[2]);
13813 emit_move_insn (op1, operands[1]);
13814
13815 emit_label (label);
13816 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13817 ix86_emit_fp_unordered_jump (label);
13818 LABEL_NUSES (label) = 1;
13819
13820 emit_move_insn (operands[0], op1);
13821 DONE;
13822 })
13823
13824 (define_expand "fmod<mode>3"
13825 [(use (match_operand:MODEF 0 "register_operand"))
13826 (use (match_operand:MODEF 1 "general_operand"))
13827 (use (match_operand:MODEF 2 "general_operand"))]
13828 "TARGET_USE_FANCY_MATH_387"
13829 {
13830 rtx (*gen_truncxf) (rtx, rtx);
13831
13832 rtx label = gen_label_rtx ();
13833
13834 rtx op1 = gen_reg_rtx (XFmode);
13835 rtx op2 = gen_reg_rtx (XFmode);
13836
13837 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13838 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13839
13840 emit_label (label);
13841 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13842 ix86_emit_fp_unordered_jump (label);
13843 LABEL_NUSES (label) = 1;
13844
13845 /* Truncate the result properly for strict SSE math. */
13846 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13847 && !TARGET_MIX_SSE_I387)
13848 gen_truncxf = gen_truncxf<mode>2;
13849 else
13850 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13851
13852 emit_insn (gen_truncxf (operands[0], op1));
13853 DONE;
13854 })
13855
13856 (define_insn "fprem1xf4_i387"
13857 [(set (match_operand:XF 0 "register_operand" "=f")
13858 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13859 (match_operand:XF 3 "register_operand" "1")]
13860 UNSPEC_FPREM1_F))
13861 (set (match_operand:XF 1 "register_operand" "=u")
13862 (unspec:XF [(match_dup 2) (match_dup 3)]
13863 UNSPEC_FPREM1_U))
13864 (set (reg:CCFP FPSR_REG)
13865 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13866 UNSPEC_C2_FLAG))]
13867 "TARGET_USE_FANCY_MATH_387"
13868 "fprem1"
13869 [(set_attr "type" "fpspc")
13870 (set_attr "mode" "XF")])
13871
13872 (define_expand "remainderxf3"
13873 [(use (match_operand:XF 0 "register_operand"))
13874 (use (match_operand:XF 1 "general_operand"))
13875 (use (match_operand:XF 2 "general_operand"))]
13876 "TARGET_USE_FANCY_MATH_387"
13877 {
13878 rtx label = gen_label_rtx ();
13879
13880 rtx op1 = gen_reg_rtx (XFmode);
13881 rtx op2 = gen_reg_rtx (XFmode);
13882
13883 emit_move_insn (op2, operands[2]);
13884 emit_move_insn (op1, operands[1]);
13885
13886 emit_label (label);
13887 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13888 ix86_emit_fp_unordered_jump (label);
13889 LABEL_NUSES (label) = 1;
13890
13891 emit_move_insn (operands[0], op1);
13892 DONE;
13893 })
13894
13895 (define_expand "remainder<mode>3"
13896 [(use (match_operand:MODEF 0 "register_operand"))
13897 (use (match_operand:MODEF 1 "general_operand"))
13898 (use (match_operand:MODEF 2 "general_operand"))]
13899 "TARGET_USE_FANCY_MATH_387"
13900 {
13901 rtx (*gen_truncxf) (rtx, rtx);
13902
13903 rtx label = gen_label_rtx ();
13904
13905 rtx op1 = gen_reg_rtx (XFmode);
13906 rtx op2 = gen_reg_rtx (XFmode);
13907
13908 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13909 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13910
13911 emit_label (label);
13912
13913 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13914 ix86_emit_fp_unordered_jump (label);
13915 LABEL_NUSES (label) = 1;
13916
13917 /* Truncate the result properly for strict SSE math. */
13918 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13919 && !TARGET_MIX_SSE_I387)
13920 gen_truncxf = gen_truncxf<mode>2;
13921 else
13922 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13923
13924 emit_insn (gen_truncxf (operands[0], op1));
13925 DONE;
13926 })
13927
13928 (define_int_iterator SINCOS
13929 [UNSPEC_SIN
13930 UNSPEC_COS])
13931
13932 (define_int_attr sincos
13933 [(UNSPEC_SIN "sin")
13934 (UNSPEC_COS "cos")])
13935
13936 (define_insn "*<sincos>xf2_i387"
13937 [(set (match_operand:XF 0 "register_operand" "=f")
13938 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13939 SINCOS))]
13940 "TARGET_USE_FANCY_MATH_387
13941 && flag_unsafe_math_optimizations"
13942 "f<sincos>"
13943 [(set_attr "type" "fpspc")
13944 (set_attr "mode" "XF")])
13945
13946 (define_insn "*<sincos>_extend<mode>xf2_i387"
13947 [(set (match_operand:XF 0 "register_operand" "=f")
13948 (unspec:XF [(float_extend:XF
13949 (match_operand:MODEF 1 "register_operand" "0"))]
13950 SINCOS))]
13951 "TARGET_USE_FANCY_MATH_387
13952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13953 || TARGET_MIX_SSE_I387)
13954 && flag_unsafe_math_optimizations"
13955 "f<sincos>"
13956 [(set_attr "type" "fpspc")
13957 (set_attr "mode" "XF")])
13958
13959 ;; When sincos pattern is defined, sin and cos builtin functions will be
13960 ;; expanded to sincos pattern with one of its outputs left unused.
13961 ;; CSE pass will figure out if two sincos patterns can be combined,
13962 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13963 ;; depending on the unused output.
13964
13965 (define_insn "sincosxf3"
13966 [(set (match_operand:XF 0 "register_operand" "=f")
13967 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13968 UNSPEC_SINCOS_COS))
13969 (set (match_operand:XF 1 "register_operand" "=u")
13970 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13971 "TARGET_USE_FANCY_MATH_387
13972 && flag_unsafe_math_optimizations"
13973 "fsincos"
13974 [(set_attr "type" "fpspc")
13975 (set_attr "mode" "XF")])
13976
13977 (define_split
13978 [(set (match_operand:XF 0 "register_operand")
13979 (unspec:XF [(match_operand:XF 2 "register_operand")]
13980 UNSPEC_SINCOS_COS))
13981 (set (match_operand:XF 1 "register_operand")
13982 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13983 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13984 && can_create_pseudo_p ()"
13985 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13986
13987 (define_split
13988 [(set (match_operand:XF 0 "register_operand")
13989 (unspec:XF [(match_operand:XF 2 "register_operand")]
13990 UNSPEC_SINCOS_COS))
13991 (set (match_operand:XF 1 "register_operand")
13992 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13993 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13994 && can_create_pseudo_p ()"
13995 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13996
13997 (define_insn "sincos_extend<mode>xf3_i387"
13998 [(set (match_operand:XF 0 "register_operand" "=f")
13999 (unspec:XF [(float_extend:XF
14000 (match_operand:MODEF 2 "register_operand" "0"))]
14001 UNSPEC_SINCOS_COS))
14002 (set (match_operand:XF 1 "register_operand" "=u")
14003 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14004 "TARGET_USE_FANCY_MATH_387
14005 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14006 || TARGET_MIX_SSE_I387)
14007 && flag_unsafe_math_optimizations"
14008 "fsincos"
14009 [(set_attr "type" "fpspc")
14010 (set_attr "mode" "XF")])
14011
14012 (define_split
14013 [(set (match_operand:XF 0 "register_operand")
14014 (unspec:XF [(float_extend:XF
14015 (match_operand:MODEF 2 "register_operand"))]
14016 UNSPEC_SINCOS_COS))
14017 (set (match_operand:XF 1 "register_operand")
14018 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14019 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14020 && can_create_pseudo_p ()"
14021 [(set (match_dup 1)
14022 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14023
14024 (define_split
14025 [(set (match_operand:XF 0 "register_operand")
14026 (unspec:XF [(float_extend:XF
14027 (match_operand:MODEF 2 "register_operand"))]
14028 UNSPEC_SINCOS_COS))
14029 (set (match_operand:XF 1 "register_operand")
14030 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14031 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14032 && can_create_pseudo_p ()"
14033 [(set (match_dup 0)
14034 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14035
14036 (define_expand "sincos<mode>3"
14037 [(use (match_operand:MODEF 0 "register_operand"))
14038 (use (match_operand:MODEF 1 "register_operand"))
14039 (use (match_operand:MODEF 2 "register_operand"))]
14040 "TARGET_USE_FANCY_MATH_387
14041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042 || TARGET_MIX_SSE_I387)
14043 && flag_unsafe_math_optimizations"
14044 {
14045 rtx op0 = gen_reg_rtx (XFmode);
14046 rtx op1 = gen_reg_rtx (XFmode);
14047
14048 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14049 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14051 DONE;
14052 })
14053
14054 (define_insn "fptanxf4_i387"
14055 [(set (match_operand:XF 0 "register_operand" "=f")
14056 (match_operand:XF 3 "const_double_operand" "F"))
14057 (set (match_operand:XF 1 "register_operand" "=u")
14058 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14059 UNSPEC_TAN))]
14060 "TARGET_USE_FANCY_MATH_387
14061 && flag_unsafe_math_optimizations
14062 && standard_80387_constant_p (operands[3]) == 2"
14063 "fptan"
14064 [(set_attr "type" "fpspc")
14065 (set_attr "mode" "XF")])
14066
14067 (define_insn "fptan_extend<mode>xf4_i387"
14068 [(set (match_operand:MODEF 0 "register_operand" "=f")
14069 (match_operand:MODEF 3 "const_double_operand" "F"))
14070 (set (match_operand:XF 1 "register_operand" "=u")
14071 (unspec:XF [(float_extend:XF
14072 (match_operand:MODEF 2 "register_operand" "0"))]
14073 UNSPEC_TAN))]
14074 "TARGET_USE_FANCY_MATH_387
14075 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14076 || TARGET_MIX_SSE_I387)
14077 && flag_unsafe_math_optimizations
14078 && standard_80387_constant_p (operands[3]) == 2"
14079 "fptan"
14080 [(set_attr "type" "fpspc")
14081 (set_attr "mode" "XF")])
14082
14083 (define_expand "tanxf2"
14084 [(use (match_operand:XF 0 "register_operand"))
14085 (use (match_operand:XF 1 "register_operand"))]
14086 "TARGET_USE_FANCY_MATH_387
14087 && flag_unsafe_math_optimizations"
14088 {
14089 rtx one = gen_reg_rtx (XFmode);
14090 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14091
14092 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14093 DONE;
14094 })
14095
14096 (define_expand "tan<mode>2"
14097 [(use (match_operand:MODEF 0 "register_operand"))
14098 (use (match_operand:MODEF 1 "register_operand"))]
14099 "TARGET_USE_FANCY_MATH_387
14100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14101 || TARGET_MIX_SSE_I387)
14102 && flag_unsafe_math_optimizations"
14103 {
14104 rtx op0 = gen_reg_rtx (XFmode);
14105
14106 rtx one = gen_reg_rtx (<MODE>mode);
14107 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14108
14109 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14110 operands[1], op2));
14111 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14112 DONE;
14113 })
14114
14115 (define_insn "*fpatanxf3_i387"
14116 [(set (match_operand:XF 0 "register_operand" "=f")
14117 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14118 (match_operand:XF 2 "register_operand" "u")]
14119 UNSPEC_FPATAN))
14120 (clobber (match_scratch:XF 3 "=2"))]
14121 "TARGET_USE_FANCY_MATH_387
14122 && flag_unsafe_math_optimizations"
14123 "fpatan"
14124 [(set_attr "type" "fpspc")
14125 (set_attr "mode" "XF")])
14126
14127 (define_insn "fpatan_extend<mode>xf3_i387"
14128 [(set (match_operand:XF 0 "register_operand" "=f")
14129 (unspec:XF [(float_extend:XF
14130 (match_operand:MODEF 1 "register_operand" "0"))
14131 (float_extend:XF
14132 (match_operand:MODEF 2 "register_operand" "u"))]
14133 UNSPEC_FPATAN))
14134 (clobber (match_scratch:XF 3 "=2"))]
14135 "TARGET_USE_FANCY_MATH_387
14136 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14137 || TARGET_MIX_SSE_I387)
14138 && flag_unsafe_math_optimizations"
14139 "fpatan"
14140 [(set_attr "type" "fpspc")
14141 (set_attr "mode" "XF")])
14142
14143 (define_expand "atan2xf3"
14144 [(parallel [(set (match_operand:XF 0 "register_operand")
14145 (unspec:XF [(match_operand:XF 2 "register_operand")
14146 (match_operand:XF 1 "register_operand")]
14147 UNSPEC_FPATAN))
14148 (clobber (match_scratch:XF 3))])]
14149 "TARGET_USE_FANCY_MATH_387
14150 && flag_unsafe_math_optimizations")
14151
14152 (define_expand "atan2<mode>3"
14153 [(use (match_operand:MODEF 0 "register_operand"))
14154 (use (match_operand:MODEF 1 "register_operand"))
14155 (use (match_operand:MODEF 2 "register_operand"))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14158 || TARGET_MIX_SSE_I387)
14159 && flag_unsafe_math_optimizations"
14160 {
14161 rtx op0 = gen_reg_rtx (XFmode);
14162
14163 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14164 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14165 DONE;
14166 })
14167
14168 (define_expand "atanxf2"
14169 [(parallel [(set (match_operand:XF 0 "register_operand")
14170 (unspec:XF [(match_dup 2)
14171 (match_operand:XF 1 "register_operand")]
14172 UNSPEC_FPATAN))
14173 (clobber (match_scratch:XF 3))])]
14174 "TARGET_USE_FANCY_MATH_387
14175 && flag_unsafe_math_optimizations"
14176 {
14177 operands[2] = gen_reg_rtx (XFmode);
14178 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14179 })
14180
14181 (define_expand "atan<mode>2"
14182 [(use (match_operand:MODEF 0 "register_operand"))
14183 (use (match_operand:MODEF 1 "register_operand"))]
14184 "TARGET_USE_FANCY_MATH_387
14185 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14186 || TARGET_MIX_SSE_I387)
14187 && flag_unsafe_math_optimizations"
14188 {
14189 rtx op0 = gen_reg_rtx (XFmode);
14190
14191 rtx op2 = gen_reg_rtx (<MODE>mode);
14192 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14193
14194 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14195 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14196 DONE;
14197 })
14198
14199 (define_expand "asinxf2"
14200 [(set (match_dup 2)
14201 (mult:XF (match_operand:XF 1 "register_operand")
14202 (match_dup 1)))
14203 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14204 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14205 (parallel [(set (match_operand:XF 0 "register_operand")
14206 (unspec:XF [(match_dup 5) (match_dup 1)]
14207 UNSPEC_FPATAN))
14208 (clobber (match_scratch:XF 6))])]
14209 "TARGET_USE_FANCY_MATH_387
14210 && flag_unsafe_math_optimizations"
14211 {
14212 int i;
14213
14214 if (optimize_insn_for_size_p ())
14215 FAIL;
14216
14217 for (i = 2; i < 6; i++)
14218 operands[i] = gen_reg_rtx (XFmode);
14219
14220 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14221 })
14222
14223 (define_expand "asin<mode>2"
14224 [(use (match_operand:MODEF 0 "register_operand"))
14225 (use (match_operand:MODEF 1 "general_operand"))]
14226 "TARGET_USE_FANCY_MATH_387
14227 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14228 || TARGET_MIX_SSE_I387)
14229 && flag_unsafe_math_optimizations"
14230 {
14231 rtx op0 = gen_reg_rtx (XFmode);
14232 rtx op1 = gen_reg_rtx (XFmode);
14233
14234 if (optimize_insn_for_size_p ())
14235 FAIL;
14236
14237 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14238 emit_insn (gen_asinxf2 (op0, op1));
14239 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14240 DONE;
14241 })
14242
14243 (define_expand "acosxf2"
14244 [(set (match_dup 2)
14245 (mult:XF (match_operand:XF 1 "register_operand")
14246 (match_dup 1)))
14247 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14248 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14249 (parallel [(set (match_operand:XF 0 "register_operand")
14250 (unspec:XF [(match_dup 1) (match_dup 5)]
14251 UNSPEC_FPATAN))
14252 (clobber (match_scratch:XF 6))])]
14253 "TARGET_USE_FANCY_MATH_387
14254 && flag_unsafe_math_optimizations"
14255 {
14256 int i;
14257
14258 if (optimize_insn_for_size_p ())
14259 FAIL;
14260
14261 for (i = 2; i < 6; i++)
14262 operands[i] = gen_reg_rtx (XFmode);
14263
14264 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14265 })
14266
14267 (define_expand "acos<mode>2"
14268 [(use (match_operand:MODEF 0 "register_operand"))
14269 (use (match_operand:MODEF 1 "general_operand"))]
14270 "TARGET_USE_FANCY_MATH_387
14271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14272 || TARGET_MIX_SSE_I387)
14273 && flag_unsafe_math_optimizations"
14274 {
14275 rtx op0 = gen_reg_rtx (XFmode);
14276 rtx op1 = gen_reg_rtx (XFmode);
14277
14278 if (optimize_insn_for_size_p ())
14279 FAIL;
14280
14281 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14282 emit_insn (gen_acosxf2 (op0, op1));
14283 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14284 DONE;
14285 })
14286
14287 (define_insn "fyl2xxf3_i387"
14288 [(set (match_operand:XF 0 "register_operand" "=f")
14289 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14290 (match_operand:XF 2 "register_operand" "u")]
14291 UNSPEC_FYL2X))
14292 (clobber (match_scratch:XF 3 "=2"))]
14293 "TARGET_USE_FANCY_MATH_387
14294 && flag_unsafe_math_optimizations"
14295 "fyl2x"
14296 [(set_attr "type" "fpspc")
14297 (set_attr "mode" "XF")])
14298
14299 (define_insn "fyl2x_extend<mode>xf3_i387"
14300 [(set (match_operand:XF 0 "register_operand" "=f")
14301 (unspec:XF [(float_extend:XF
14302 (match_operand:MODEF 1 "register_operand" "0"))
14303 (match_operand:XF 2 "register_operand" "u")]
14304 UNSPEC_FYL2X))
14305 (clobber (match_scratch:XF 3 "=2"))]
14306 "TARGET_USE_FANCY_MATH_387
14307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14308 || TARGET_MIX_SSE_I387)
14309 && flag_unsafe_math_optimizations"
14310 "fyl2x"
14311 [(set_attr "type" "fpspc")
14312 (set_attr "mode" "XF")])
14313
14314 (define_expand "logxf2"
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], standard_80387_constant_rtx (4)); /* fldln2 */
14324 })
14325
14326 (define_expand "log<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, standard_80387_constant_rtx (4)); /* fldln2 */
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_expand "log10xf2"
14345 [(parallel [(set (match_operand:XF 0 "register_operand")
14346 (unspec:XF [(match_operand:XF 1 "register_operand")
14347 (match_dup 2)] UNSPEC_FYL2X))
14348 (clobber (match_scratch:XF 3))])]
14349 "TARGET_USE_FANCY_MATH_387
14350 && flag_unsafe_math_optimizations"
14351 {
14352 operands[2] = gen_reg_rtx (XFmode);
14353 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14354 })
14355
14356 (define_expand "log10<mode>2"
14357 [(use (match_operand:MODEF 0 "register_operand"))
14358 (use (match_operand:MODEF 1 "register_operand"))]
14359 "TARGET_USE_FANCY_MATH_387
14360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14361 || TARGET_MIX_SSE_I387)
14362 && flag_unsafe_math_optimizations"
14363 {
14364 rtx op0 = gen_reg_rtx (XFmode);
14365
14366 rtx op2 = gen_reg_rtx (XFmode);
14367 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14368
14369 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14370 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14371 DONE;
14372 })
14373
14374 (define_expand "log2xf2"
14375 [(parallel [(set (match_operand:XF 0 "register_operand")
14376 (unspec:XF [(match_operand:XF 1 "register_operand")
14377 (match_dup 2)] UNSPEC_FYL2X))
14378 (clobber (match_scratch:XF 3))])]
14379 "TARGET_USE_FANCY_MATH_387
14380 && flag_unsafe_math_optimizations"
14381 {
14382 operands[2] = gen_reg_rtx (XFmode);
14383 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14384 })
14385
14386 (define_expand "log2<mode>2"
14387 [(use (match_operand:MODEF 0 "register_operand"))
14388 (use (match_operand:MODEF 1 "register_operand"))]
14389 "TARGET_USE_FANCY_MATH_387
14390 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14391 || TARGET_MIX_SSE_I387)
14392 && flag_unsafe_math_optimizations"
14393 {
14394 rtx op0 = gen_reg_rtx (XFmode);
14395
14396 rtx op2 = gen_reg_rtx (XFmode);
14397 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14398
14399 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14400 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14401 DONE;
14402 })
14403
14404 (define_insn "fyl2xp1xf3_i387"
14405 [(set (match_operand:XF 0 "register_operand" "=f")
14406 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14407 (match_operand:XF 2 "register_operand" "u")]
14408 UNSPEC_FYL2XP1))
14409 (clobber (match_scratch:XF 3 "=2"))]
14410 "TARGET_USE_FANCY_MATH_387
14411 && flag_unsafe_math_optimizations"
14412 "fyl2xp1"
14413 [(set_attr "type" "fpspc")
14414 (set_attr "mode" "XF")])
14415
14416 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14417 [(set (match_operand:XF 0 "register_operand" "=f")
14418 (unspec:XF [(float_extend:XF
14419 (match_operand:MODEF 1 "register_operand" "0"))
14420 (match_operand:XF 2 "register_operand" "u")]
14421 UNSPEC_FYL2XP1))
14422 (clobber (match_scratch:XF 3 "=2"))]
14423 "TARGET_USE_FANCY_MATH_387
14424 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14425 || TARGET_MIX_SSE_I387)
14426 && flag_unsafe_math_optimizations"
14427 "fyl2xp1"
14428 [(set_attr "type" "fpspc")
14429 (set_attr "mode" "XF")])
14430
14431 (define_expand "log1pxf2"
14432 [(use (match_operand:XF 0 "register_operand"))
14433 (use (match_operand:XF 1 "register_operand"))]
14434 "TARGET_USE_FANCY_MATH_387
14435 && flag_unsafe_math_optimizations"
14436 {
14437 if (optimize_insn_for_size_p ())
14438 FAIL;
14439
14440 ix86_emit_i387_log1p (operands[0], operands[1]);
14441 DONE;
14442 })
14443
14444 (define_expand "log1p<mode>2"
14445 [(use (match_operand:MODEF 0 "register_operand"))
14446 (use (match_operand:MODEF 1 "register_operand"))]
14447 "TARGET_USE_FANCY_MATH_387
14448 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14449 || TARGET_MIX_SSE_I387)
14450 && flag_unsafe_math_optimizations"
14451 {
14452 rtx op0;
14453
14454 if (optimize_insn_for_size_p ())
14455 FAIL;
14456
14457 op0 = gen_reg_rtx (XFmode);
14458
14459 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14460
14461 ix86_emit_i387_log1p (op0, operands[1]);
14462 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14463 DONE;
14464 })
14465
14466 (define_insn "fxtractxf3_i387"
14467 [(set (match_operand:XF 0 "register_operand" "=f")
14468 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14469 UNSPEC_XTRACT_FRACT))
14470 (set (match_operand:XF 1 "register_operand" "=u")
14471 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14472 "TARGET_USE_FANCY_MATH_387
14473 && flag_unsafe_math_optimizations"
14474 "fxtract"
14475 [(set_attr "type" "fpspc")
14476 (set_attr "mode" "XF")])
14477
14478 (define_insn "fxtract_extend<mode>xf3_i387"
14479 [(set (match_operand:XF 0 "register_operand" "=f")
14480 (unspec:XF [(float_extend:XF
14481 (match_operand:MODEF 2 "register_operand" "0"))]
14482 UNSPEC_XTRACT_FRACT))
14483 (set (match_operand:XF 1 "register_operand" "=u")
14484 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14485 "TARGET_USE_FANCY_MATH_387
14486 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14487 || TARGET_MIX_SSE_I387)
14488 && flag_unsafe_math_optimizations"
14489 "fxtract"
14490 [(set_attr "type" "fpspc")
14491 (set_attr "mode" "XF")])
14492
14493 (define_expand "logbxf2"
14494 [(parallel [(set (match_dup 2)
14495 (unspec:XF [(match_operand:XF 1 "register_operand")]
14496 UNSPEC_XTRACT_FRACT))
14497 (set (match_operand:XF 0 "register_operand")
14498 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14499 "TARGET_USE_FANCY_MATH_387
14500 && flag_unsafe_math_optimizations"
14501 "operands[2] = gen_reg_rtx (XFmode);")
14502
14503 (define_expand "logb<mode>2"
14504 [(use (match_operand:MODEF 0 "register_operand"))
14505 (use (match_operand:MODEF 1 "register_operand"))]
14506 "TARGET_USE_FANCY_MATH_387
14507 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14508 || TARGET_MIX_SSE_I387)
14509 && flag_unsafe_math_optimizations"
14510 {
14511 rtx op0 = gen_reg_rtx (XFmode);
14512 rtx op1 = gen_reg_rtx (XFmode);
14513
14514 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14515 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14516 DONE;
14517 })
14518
14519 (define_expand "ilogbxf2"
14520 [(use (match_operand:SI 0 "register_operand"))
14521 (use (match_operand:XF 1 "register_operand"))]
14522 "TARGET_USE_FANCY_MATH_387
14523 && flag_unsafe_math_optimizations"
14524 {
14525 rtx op0, op1;
14526
14527 if (optimize_insn_for_size_p ())
14528 FAIL;
14529
14530 op0 = gen_reg_rtx (XFmode);
14531 op1 = gen_reg_rtx (XFmode);
14532
14533 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14534 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14535 DONE;
14536 })
14537
14538 (define_expand "ilogb<mode>2"
14539 [(use (match_operand:SI 0 "register_operand"))
14540 (use (match_operand:MODEF 1 "register_operand"))]
14541 "TARGET_USE_FANCY_MATH_387
14542 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14543 || TARGET_MIX_SSE_I387)
14544 && flag_unsafe_math_optimizations"
14545 {
14546 rtx op0, op1;
14547
14548 if (optimize_insn_for_size_p ())
14549 FAIL;
14550
14551 op0 = gen_reg_rtx (XFmode);
14552 op1 = gen_reg_rtx (XFmode);
14553
14554 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14555 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14556 DONE;
14557 })
14558
14559 (define_insn "*f2xm1xf2_i387"
14560 [(set (match_operand:XF 0 "register_operand" "=f")
14561 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14562 UNSPEC_F2XM1))]
14563 "TARGET_USE_FANCY_MATH_387
14564 && flag_unsafe_math_optimizations"
14565 "f2xm1"
14566 [(set_attr "type" "fpspc")
14567 (set_attr "mode" "XF")])
14568
14569 (define_insn "*fscalexf4_i387"
14570 [(set (match_operand:XF 0 "register_operand" "=f")
14571 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14572 (match_operand:XF 3 "register_operand" "1")]
14573 UNSPEC_FSCALE_FRACT))
14574 (set (match_operand:XF 1 "register_operand" "=u")
14575 (unspec:XF [(match_dup 2) (match_dup 3)]
14576 UNSPEC_FSCALE_EXP))]
14577 "TARGET_USE_FANCY_MATH_387
14578 && flag_unsafe_math_optimizations"
14579 "fscale"
14580 [(set_attr "type" "fpspc")
14581 (set_attr "mode" "XF")])
14582
14583 (define_expand "expNcorexf3"
14584 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14585 (match_operand:XF 2 "register_operand")))
14586 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14587 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14588 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14589 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14590 (parallel [(set (match_operand:XF 0 "register_operand")
14591 (unspec:XF [(match_dup 8) (match_dup 4)]
14592 UNSPEC_FSCALE_FRACT))
14593 (set (match_dup 9)
14594 (unspec:XF [(match_dup 8) (match_dup 4)]
14595 UNSPEC_FSCALE_EXP))])]
14596 "TARGET_USE_FANCY_MATH_387
14597 && flag_unsafe_math_optimizations"
14598 {
14599 int i;
14600
14601 if (optimize_insn_for_size_p ())
14602 FAIL;
14603
14604 for (i = 3; i < 10; i++)
14605 operands[i] = gen_reg_rtx (XFmode);
14606
14607 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14608 })
14609
14610 (define_expand "expxf2"
14611 [(use (match_operand:XF 0 "register_operand"))
14612 (use (match_operand:XF 1 "register_operand"))]
14613 "TARGET_USE_FANCY_MATH_387
14614 && flag_unsafe_math_optimizations"
14615 {
14616 rtx op2;
14617
14618 if (optimize_insn_for_size_p ())
14619 FAIL;
14620
14621 op2 = gen_reg_rtx (XFmode);
14622 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14623
14624 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14625 DONE;
14626 })
14627
14628 (define_expand "exp<mode>2"
14629 [(use (match_operand:MODEF 0 "register_operand"))
14630 (use (match_operand:MODEF 1 "general_operand"))]
14631 "TARGET_USE_FANCY_MATH_387
14632 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14633 || TARGET_MIX_SSE_I387)
14634 && flag_unsafe_math_optimizations"
14635 {
14636 rtx op0, op1;
14637
14638 if (optimize_insn_for_size_p ())
14639 FAIL;
14640
14641 op0 = gen_reg_rtx (XFmode);
14642 op1 = gen_reg_rtx (XFmode);
14643
14644 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14645 emit_insn (gen_expxf2 (op0, op1));
14646 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14647 DONE;
14648 })
14649
14650 (define_expand "exp10xf2"
14651 [(use (match_operand:XF 0 "register_operand"))
14652 (use (match_operand:XF 1 "register_operand"))]
14653 "TARGET_USE_FANCY_MATH_387
14654 && flag_unsafe_math_optimizations"
14655 {
14656 rtx op2;
14657
14658 if (optimize_insn_for_size_p ())
14659 FAIL;
14660
14661 op2 = gen_reg_rtx (XFmode);
14662 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14663
14664 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14665 DONE;
14666 })
14667
14668 (define_expand "exp10<mode>2"
14669 [(use (match_operand:MODEF 0 "register_operand"))
14670 (use (match_operand:MODEF 1 "general_operand"))]
14671 "TARGET_USE_FANCY_MATH_387
14672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14673 || TARGET_MIX_SSE_I387)
14674 && flag_unsafe_math_optimizations"
14675 {
14676 rtx op0, op1;
14677
14678 if (optimize_insn_for_size_p ())
14679 FAIL;
14680
14681 op0 = gen_reg_rtx (XFmode);
14682 op1 = gen_reg_rtx (XFmode);
14683
14684 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14685 emit_insn (gen_exp10xf2 (op0, op1));
14686 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14687 DONE;
14688 })
14689
14690 (define_expand "exp2xf2"
14691 [(use (match_operand:XF 0 "register_operand"))
14692 (use (match_operand:XF 1 "register_operand"))]
14693 "TARGET_USE_FANCY_MATH_387
14694 && flag_unsafe_math_optimizations"
14695 {
14696 rtx op2;
14697
14698 if (optimize_insn_for_size_p ())
14699 FAIL;
14700
14701 op2 = gen_reg_rtx (XFmode);
14702 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14703
14704 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14705 DONE;
14706 })
14707
14708 (define_expand "exp2<mode>2"
14709 [(use (match_operand:MODEF 0 "register_operand"))
14710 (use (match_operand:MODEF 1 "general_operand"))]
14711 "TARGET_USE_FANCY_MATH_387
14712 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14713 || TARGET_MIX_SSE_I387)
14714 && flag_unsafe_math_optimizations"
14715 {
14716 rtx op0, op1;
14717
14718 if (optimize_insn_for_size_p ())
14719 FAIL;
14720
14721 op0 = gen_reg_rtx (XFmode);
14722 op1 = gen_reg_rtx (XFmode);
14723
14724 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14725 emit_insn (gen_exp2xf2 (op0, op1));
14726 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14727 DONE;
14728 })
14729
14730 (define_expand "expm1xf2"
14731 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14732 (match_dup 2)))
14733 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14734 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14735 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14736 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14737 (parallel [(set (match_dup 7)
14738 (unspec:XF [(match_dup 6) (match_dup 4)]
14739 UNSPEC_FSCALE_FRACT))
14740 (set (match_dup 8)
14741 (unspec:XF [(match_dup 6) (match_dup 4)]
14742 UNSPEC_FSCALE_EXP))])
14743 (parallel [(set (match_dup 10)
14744 (unspec:XF [(match_dup 9) (match_dup 8)]
14745 UNSPEC_FSCALE_FRACT))
14746 (set (match_dup 11)
14747 (unspec:XF [(match_dup 9) (match_dup 8)]
14748 UNSPEC_FSCALE_EXP))])
14749 (set (match_dup 12) (minus:XF (match_dup 10)
14750 (float_extend:XF (match_dup 13))))
14751 (set (match_operand:XF 0 "register_operand")
14752 (plus:XF (match_dup 12) (match_dup 7)))]
14753 "TARGET_USE_FANCY_MATH_387
14754 && flag_unsafe_math_optimizations"
14755 {
14756 int i;
14757
14758 if (optimize_insn_for_size_p ())
14759 FAIL;
14760
14761 for (i = 2; i < 13; i++)
14762 operands[i] = gen_reg_rtx (XFmode);
14763
14764 operands[13]
14765 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14766
14767 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14768 })
14769
14770 (define_expand "expm1<mode>2"
14771 [(use (match_operand:MODEF 0 "register_operand"))
14772 (use (match_operand:MODEF 1 "general_operand"))]
14773 "TARGET_USE_FANCY_MATH_387
14774 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14775 || TARGET_MIX_SSE_I387)
14776 && flag_unsafe_math_optimizations"
14777 {
14778 rtx op0, op1;
14779
14780 if (optimize_insn_for_size_p ())
14781 FAIL;
14782
14783 op0 = gen_reg_rtx (XFmode);
14784 op1 = gen_reg_rtx (XFmode);
14785
14786 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14787 emit_insn (gen_expm1xf2 (op0, op1));
14788 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14789 DONE;
14790 })
14791
14792 (define_expand "ldexpxf3"
14793 [(set (match_dup 3)
14794 (float:XF (match_operand:SI 2 "register_operand")))
14795 (parallel [(set (match_operand:XF 0 " register_operand")
14796 (unspec:XF [(match_operand:XF 1 "register_operand")
14797 (match_dup 3)]
14798 UNSPEC_FSCALE_FRACT))
14799 (set (match_dup 4)
14800 (unspec:XF [(match_dup 1) (match_dup 3)]
14801 UNSPEC_FSCALE_EXP))])]
14802 "TARGET_USE_FANCY_MATH_387
14803 && flag_unsafe_math_optimizations"
14804 {
14805 if (optimize_insn_for_size_p ())
14806 FAIL;
14807
14808 operands[3] = gen_reg_rtx (XFmode);
14809 operands[4] = gen_reg_rtx (XFmode);
14810 })
14811
14812 (define_expand "ldexp<mode>3"
14813 [(use (match_operand:MODEF 0 "register_operand"))
14814 (use (match_operand:MODEF 1 "general_operand"))
14815 (use (match_operand:SI 2 "register_operand"))]
14816 "TARGET_USE_FANCY_MATH_387
14817 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14818 || TARGET_MIX_SSE_I387)
14819 && flag_unsafe_math_optimizations"
14820 {
14821 rtx op0, op1;
14822
14823 if (optimize_insn_for_size_p ())
14824 FAIL;
14825
14826 op0 = gen_reg_rtx (XFmode);
14827 op1 = gen_reg_rtx (XFmode);
14828
14829 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14830 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14831 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14832 DONE;
14833 })
14834
14835 (define_expand "scalbxf3"
14836 [(parallel [(set (match_operand:XF 0 " register_operand")
14837 (unspec:XF [(match_operand:XF 1 "register_operand")
14838 (match_operand:XF 2 "register_operand")]
14839 UNSPEC_FSCALE_FRACT))
14840 (set (match_dup 3)
14841 (unspec:XF [(match_dup 1) (match_dup 2)]
14842 UNSPEC_FSCALE_EXP))])]
14843 "TARGET_USE_FANCY_MATH_387
14844 && flag_unsafe_math_optimizations"
14845 {
14846 if (optimize_insn_for_size_p ())
14847 FAIL;
14848
14849 operands[3] = gen_reg_rtx (XFmode);
14850 })
14851
14852 (define_expand "scalb<mode>3"
14853 [(use (match_operand:MODEF 0 "register_operand"))
14854 (use (match_operand:MODEF 1 "general_operand"))
14855 (use (match_operand:MODEF 2 "general_operand"))]
14856 "TARGET_USE_FANCY_MATH_387
14857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14858 || TARGET_MIX_SSE_I387)
14859 && flag_unsafe_math_optimizations"
14860 {
14861 rtx op0, op1, op2;
14862
14863 if (optimize_insn_for_size_p ())
14864 FAIL;
14865
14866 op0 = gen_reg_rtx (XFmode);
14867 op1 = gen_reg_rtx (XFmode);
14868 op2 = gen_reg_rtx (XFmode);
14869
14870 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14871 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14872 emit_insn (gen_scalbxf3 (op0, op1, op2));
14873 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14874 DONE;
14875 })
14876
14877 (define_expand "significandxf2"
14878 [(parallel [(set (match_operand:XF 0 "register_operand")
14879 (unspec:XF [(match_operand:XF 1 "register_operand")]
14880 UNSPEC_XTRACT_FRACT))
14881 (set (match_dup 2)
14882 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14883 "TARGET_USE_FANCY_MATH_387
14884 && flag_unsafe_math_optimizations"
14885 "operands[2] = gen_reg_rtx (XFmode);")
14886
14887 (define_expand "significand<mode>2"
14888 [(use (match_operand:MODEF 0 "register_operand"))
14889 (use (match_operand:MODEF 1 "register_operand"))]
14890 "TARGET_USE_FANCY_MATH_387
14891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14892 || TARGET_MIX_SSE_I387)
14893 && flag_unsafe_math_optimizations"
14894 {
14895 rtx op0 = gen_reg_rtx (XFmode);
14896 rtx op1 = gen_reg_rtx (XFmode);
14897
14898 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14899 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14900 DONE;
14901 })
14902 \f
14903
14904 (define_insn "sse4_1_round<mode>2"
14905 [(set (match_operand:MODEF 0 "register_operand" "=x")
14906 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14907 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14908 UNSPEC_ROUND))]
14909 "TARGET_ROUND"
14910 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14911 [(set_attr "type" "ssecvt")
14912 (set_attr "prefix_extra" "1")
14913 (set_attr "prefix" "maybe_vex")
14914 (set_attr "mode" "<MODE>")])
14915
14916 (define_insn "rintxf2"
14917 [(set (match_operand:XF 0 "register_operand" "=f")
14918 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14919 UNSPEC_FRNDINT))]
14920 "TARGET_USE_FANCY_MATH_387
14921 && flag_unsafe_math_optimizations"
14922 "frndint"
14923 [(set_attr "type" "fpspc")
14924 (set_attr "mode" "XF")])
14925
14926 (define_expand "rint<mode>2"
14927 [(use (match_operand:MODEF 0 "register_operand"))
14928 (use (match_operand:MODEF 1 "register_operand"))]
14929 "(TARGET_USE_FANCY_MATH_387
14930 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14931 || TARGET_MIX_SSE_I387)
14932 && flag_unsafe_math_optimizations)
14933 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14934 && !flag_trapping_math)"
14935 {
14936 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14937 && !flag_trapping_math)
14938 {
14939 if (TARGET_ROUND)
14940 emit_insn (gen_sse4_1_round<mode>2
14941 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14942 else if (optimize_insn_for_size_p ())
14943 FAIL;
14944 else
14945 ix86_expand_rint (operands[0], operands[1]);
14946 }
14947 else
14948 {
14949 rtx op0 = gen_reg_rtx (XFmode);
14950 rtx op1 = gen_reg_rtx (XFmode);
14951
14952 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14953 emit_insn (gen_rintxf2 (op0, op1));
14954
14955 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14956 }
14957 DONE;
14958 })
14959
14960 (define_expand "round<mode>2"
14961 [(match_operand:X87MODEF 0 "register_operand")
14962 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14963 "(TARGET_USE_FANCY_MATH_387
14964 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14965 || TARGET_MIX_SSE_I387)
14966 && flag_unsafe_math_optimizations)
14967 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14968 && !flag_trapping_math && !flag_rounding_math)"
14969 {
14970 if (optimize_insn_for_size_p ())
14971 FAIL;
14972
14973 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14974 && !flag_trapping_math && !flag_rounding_math)
14975 {
14976 if (TARGET_ROUND)
14977 {
14978 operands[1] = force_reg (<MODE>mode, operands[1]);
14979 ix86_expand_round_sse4 (operands[0], operands[1]);
14980 }
14981 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14982 ix86_expand_round (operands[0], operands[1]);
14983 else
14984 ix86_expand_rounddf_32 (operands[0], operands[1]);
14985 }
14986 else
14987 {
14988 operands[1] = force_reg (<MODE>mode, operands[1]);
14989 ix86_emit_i387_round (operands[0], operands[1]);
14990 }
14991 DONE;
14992 })
14993
14994 (define_insn_and_split "*fistdi2_1"
14995 [(set (match_operand:DI 0 "nonimmediate_operand")
14996 (unspec:DI [(match_operand:XF 1 "register_operand")]
14997 UNSPEC_FIST))]
14998 "TARGET_USE_FANCY_MATH_387
14999 && can_create_pseudo_p ()"
15000 "#"
15001 "&& 1"
15002 [(const_int 0)]
15003 {
15004 if (memory_operand (operands[0], VOIDmode))
15005 emit_insn (gen_fistdi2 (operands[0], operands[1]));
15006 else
15007 {
15008 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15009 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15010 operands[2]));
15011 }
15012 DONE;
15013 }
15014 [(set_attr "type" "fpspc")
15015 (set_attr "mode" "DI")])
15016
15017 (define_insn "fistdi2"
15018 [(set (match_operand:DI 0 "memory_operand" "=m")
15019 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15020 UNSPEC_FIST))
15021 (clobber (match_scratch:XF 2 "=&1f"))]
15022 "TARGET_USE_FANCY_MATH_387"
15023 "* return output_fix_trunc (insn, operands, false);"
15024 [(set_attr "type" "fpspc")
15025 (set_attr "mode" "DI")])
15026
15027 (define_insn "fistdi2_with_temp"
15028 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15029 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15030 UNSPEC_FIST))
15031 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15032 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15033 "TARGET_USE_FANCY_MATH_387"
15034 "#"
15035 [(set_attr "type" "fpspc")
15036 (set_attr "mode" "DI")])
15037
15038 (define_split
15039 [(set (match_operand:DI 0 "register_operand")
15040 (unspec:DI [(match_operand:XF 1 "register_operand")]
15041 UNSPEC_FIST))
15042 (clobber (match_operand:DI 2 "memory_operand"))
15043 (clobber (match_scratch 3))]
15044 "reload_completed"
15045 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15046 (clobber (match_dup 3))])
15047 (set (match_dup 0) (match_dup 2))])
15048
15049 (define_split
15050 [(set (match_operand:DI 0 "memory_operand")
15051 (unspec:DI [(match_operand:XF 1 "register_operand")]
15052 UNSPEC_FIST))
15053 (clobber (match_operand:DI 2 "memory_operand"))
15054 (clobber (match_scratch 3))]
15055 "reload_completed"
15056 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15057 (clobber (match_dup 3))])])
15058
15059 (define_insn_and_split "*fist<mode>2_1"
15060 [(set (match_operand:SWI24 0 "register_operand")
15061 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15062 UNSPEC_FIST))]
15063 "TARGET_USE_FANCY_MATH_387
15064 && can_create_pseudo_p ()"
15065 "#"
15066 "&& 1"
15067 [(const_int 0)]
15068 {
15069 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15070 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15071 operands[2]));
15072 DONE;
15073 }
15074 [(set_attr "type" "fpspc")
15075 (set_attr "mode" "<MODE>")])
15076
15077 (define_insn "fist<mode>2"
15078 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15079 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15080 UNSPEC_FIST))]
15081 "TARGET_USE_FANCY_MATH_387"
15082 "* return output_fix_trunc (insn, operands, false);"
15083 [(set_attr "type" "fpspc")
15084 (set_attr "mode" "<MODE>")])
15085
15086 (define_insn "fist<mode>2_with_temp"
15087 [(set (match_operand:SWI24 0 "register_operand" "=r")
15088 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15089 UNSPEC_FIST))
15090 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15091 "TARGET_USE_FANCY_MATH_387"
15092 "#"
15093 [(set_attr "type" "fpspc")
15094 (set_attr "mode" "<MODE>")])
15095
15096 (define_split
15097 [(set (match_operand:SWI24 0 "register_operand")
15098 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15099 UNSPEC_FIST))
15100 (clobber (match_operand:SWI24 2 "memory_operand"))]
15101 "reload_completed"
15102 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15103 (set (match_dup 0) (match_dup 2))])
15104
15105 (define_split
15106 [(set (match_operand:SWI24 0 "memory_operand")
15107 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15108 UNSPEC_FIST))
15109 (clobber (match_operand:SWI24 2 "memory_operand"))]
15110 "reload_completed"
15111 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15112
15113 (define_expand "lrintxf<mode>2"
15114 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15115 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15116 UNSPEC_FIST))]
15117 "TARGET_USE_FANCY_MATH_387")
15118
15119 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15120 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15121 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15122 UNSPEC_FIX_NOTRUNC))]
15123 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15124 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15125
15126 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15127 [(match_operand:SWI248x 0 "nonimmediate_operand")
15128 (match_operand:X87MODEF 1 "register_operand")]
15129 "(TARGET_USE_FANCY_MATH_387
15130 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15131 || TARGET_MIX_SSE_I387)
15132 && flag_unsafe_math_optimizations)
15133 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15134 && <SWI248x:MODE>mode != HImode
15135 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15136 && !flag_trapping_math && !flag_rounding_math)"
15137 {
15138 if (optimize_insn_for_size_p ())
15139 FAIL;
15140
15141 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15142 && <SWI248x:MODE>mode != HImode
15143 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15144 && !flag_trapping_math && !flag_rounding_math)
15145 ix86_expand_lround (operands[0], operands[1]);
15146 else
15147 ix86_emit_i387_round (operands[0], operands[1]);
15148 DONE;
15149 })
15150
15151 (define_int_iterator FRNDINT_ROUNDING
15152 [UNSPEC_FRNDINT_FLOOR
15153 UNSPEC_FRNDINT_CEIL
15154 UNSPEC_FRNDINT_TRUNC])
15155
15156 (define_int_iterator FIST_ROUNDING
15157 [UNSPEC_FIST_FLOOR
15158 UNSPEC_FIST_CEIL])
15159
15160 ;; Base name for define_insn
15161 (define_int_attr rounding_insn
15162 [(UNSPEC_FRNDINT_FLOOR "floor")
15163 (UNSPEC_FRNDINT_CEIL "ceil")
15164 (UNSPEC_FRNDINT_TRUNC "btrunc")
15165 (UNSPEC_FIST_FLOOR "floor")
15166 (UNSPEC_FIST_CEIL "ceil")])
15167
15168 (define_int_attr rounding
15169 [(UNSPEC_FRNDINT_FLOOR "floor")
15170 (UNSPEC_FRNDINT_CEIL "ceil")
15171 (UNSPEC_FRNDINT_TRUNC "trunc")
15172 (UNSPEC_FIST_FLOOR "floor")
15173 (UNSPEC_FIST_CEIL "ceil")])
15174
15175 (define_int_attr ROUNDING
15176 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15177 (UNSPEC_FRNDINT_CEIL "CEIL")
15178 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15179 (UNSPEC_FIST_FLOOR "FLOOR")
15180 (UNSPEC_FIST_CEIL "CEIL")])
15181
15182 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15183 (define_insn_and_split "frndintxf2_<rounding>"
15184 [(set (match_operand:XF 0 "register_operand")
15185 (unspec:XF [(match_operand:XF 1 "register_operand")]
15186 FRNDINT_ROUNDING))
15187 (clobber (reg:CC FLAGS_REG))]
15188 "TARGET_USE_FANCY_MATH_387
15189 && flag_unsafe_math_optimizations
15190 && can_create_pseudo_p ()"
15191 "#"
15192 "&& 1"
15193 [(const_int 0)]
15194 {
15195 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15196
15197 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15198 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15199
15200 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15201 operands[2], operands[3]));
15202 DONE;
15203 }
15204 [(set_attr "type" "frndint")
15205 (set_attr "i387_cw" "<rounding>")
15206 (set_attr "mode" "XF")])
15207
15208 (define_insn "frndintxf2_<rounding>_i387"
15209 [(set (match_operand:XF 0 "register_operand" "=f")
15210 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15211 FRNDINT_ROUNDING))
15212 (use (match_operand:HI 2 "memory_operand" "m"))
15213 (use (match_operand:HI 3 "memory_operand" "m"))]
15214 "TARGET_USE_FANCY_MATH_387
15215 && flag_unsafe_math_optimizations"
15216 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15217 [(set_attr "type" "frndint")
15218 (set_attr "i387_cw" "<rounding>")
15219 (set_attr "mode" "XF")])
15220
15221 (define_expand "<rounding_insn>xf2"
15222 [(parallel [(set (match_operand:XF 0 "register_operand")
15223 (unspec:XF [(match_operand:XF 1 "register_operand")]
15224 FRNDINT_ROUNDING))
15225 (clobber (reg:CC FLAGS_REG))])]
15226 "TARGET_USE_FANCY_MATH_387
15227 && flag_unsafe_math_optimizations
15228 && !optimize_insn_for_size_p ()")
15229
15230 (define_expand "<rounding_insn><mode>2"
15231 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15232 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15233 FRNDINT_ROUNDING))
15234 (clobber (reg:CC FLAGS_REG))])]
15235 "(TARGET_USE_FANCY_MATH_387
15236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15237 || TARGET_MIX_SSE_I387)
15238 && flag_unsafe_math_optimizations)
15239 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15240 && !flag_trapping_math)"
15241 {
15242 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15243 && !flag_trapping_math)
15244 {
15245 if (TARGET_ROUND)
15246 emit_insn (gen_sse4_1_round<mode>2
15247 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15248 else if (optimize_insn_for_size_p ())
15249 FAIL;
15250 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15251 {
15252 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15253 ix86_expand_floorceil (operands[0], operands[1], true);
15254 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15255 ix86_expand_floorceil (operands[0], operands[1], false);
15256 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15257 ix86_expand_trunc (operands[0], operands[1]);
15258 else
15259 gcc_unreachable ();
15260 }
15261 else
15262 {
15263 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15264 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15265 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15266 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15267 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15268 ix86_expand_truncdf_32 (operands[0], operands[1]);
15269 else
15270 gcc_unreachable ();
15271 }
15272 }
15273 else
15274 {
15275 rtx op0, op1;
15276
15277 if (optimize_insn_for_size_p ())
15278 FAIL;
15279
15280 op0 = gen_reg_rtx (XFmode);
15281 op1 = gen_reg_rtx (XFmode);
15282 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15283 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15284
15285 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15286 }
15287 DONE;
15288 })
15289
15290 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15291 (define_insn_and_split "frndintxf2_mask_pm"
15292 [(set (match_operand:XF 0 "register_operand")
15293 (unspec:XF [(match_operand:XF 1 "register_operand")]
15294 UNSPEC_FRNDINT_MASK_PM))
15295 (clobber (reg:CC FLAGS_REG))]
15296 "TARGET_USE_FANCY_MATH_387
15297 && flag_unsafe_math_optimizations
15298 && can_create_pseudo_p ()"
15299 "#"
15300 "&& 1"
15301 [(const_int 0)]
15302 {
15303 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15304
15305 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15306 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15307
15308 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15309 operands[2], operands[3]));
15310 DONE;
15311 }
15312 [(set_attr "type" "frndint")
15313 (set_attr "i387_cw" "mask_pm")
15314 (set_attr "mode" "XF")])
15315
15316 (define_insn "frndintxf2_mask_pm_i387"
15317 [(set (match_operand:XF 0 "register_operand" "=f")
15318 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15319 UNSPEC_FRNDINT_MASK_PM))
15320 (use (match_operand:HI 2 "memory_operand" "m"))
15321 (use (match_operand:HI 3 "memory_operand" "m"))]
15322 "TARGET_USE_FANCY_MATH_387
15323 && flag_unsafe_math_optimizations"
15324 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15325 [(set_attr "type" "frndint")
15326 (set_attr "i387_cw" "mask_pm")
15327 (set_attr "mode" "XF")])
15328
15329 (define_expand "nearbyintxf2"
15330 [(parallel [(set (match_operand:XF 0 "register_operand")
15331 (unspec:XF [(match_operand:XF 1 "register_operand")]
15332 UNSPEC_FRNDINT_MASK_PM))
15333 (clobber (reg:CC FLAGS_REG))])]
15334 "TARGET_USE_FANCY_MATH_387
15335 && flag_unsafe_math_optimizations")
15336
15337 (define_expand "nearbyint<mode>2"
15338 [(use (match_operand:MODEF 0 "register_operand"))
15339 (use (match_operand:MODEF 1 "register_operand"))]
15340 "TARGET_USE_FANCY_MATH_387
15341 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15342 || TARGET_MIX_SSE_I387)
15343 && flag_unsafe_math_optimizations"
15344 {
15345 rtx op0 = gen_reg_rtx (XFmode);
15346 rtx op1 = gen_reg_rtx (XFmode);
15347
15348 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15349 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15350
15351 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15352 DONE;
15353 })
15354
15355 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15356 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15357 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15358 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15359 FIST_ROUNDING))
15360 (clobber (reg:CC FLAGS_REG))]
15361 "TARGET_USE_FANCY_MATH_387
15362 && flag_unsafe_math_optimizations
15363 && can_create_pseudo_p ()"
15364 "#"
15365 "&& 1"
15366 [(const_int 0)]
15367 {
15368 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15369
15370 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15371 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15372 if (memory_operand (operands[0], VOIDmode))
15373 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15374 operands[2], operands[3]));
15375 else
15376 {
15377 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15378 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15379 (operands[0], operands[1], operands[2],
15380 operands[3], operands[4]));
15381 }
15382 DONE;
15383 }
15384 [(set_attr "type" "fistp")
15385 (set_attr "i387_cw" "<rounding>")
15386 (set_attr "mode" "<MODE>")])
15387
15388 (define_insn "fistdi2_<rounding>"
15389 [(set (match_operand:DI 0 "memory_operand" "=m")
15390 (unspec:DI [(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 (clobber (match_scratch:XF 4 "=&1f"))]
15395 "TARGET_USE_FANCY_MATH_387
15396 && flag_unsafe_math_optimizations"
15397 "* return output_fix_trunc (insn, operands, false);"
15398 [(set_attr "type" "fistp")
15399 (set_attr "i387_cw" "<rounding>")
15400 (set_attr "mode" "DI")])
15401
15402 (define_insn "fistdi2_<rounding>_with_temp"
15403 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15404 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15405 FIST_ROUNDING))
15406 (use (match_operand:HI 2 "memory_operand" "m,m"))
15407 (use (match_operand:HI 3 "memory_operand" "m,m"))
15408 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15409 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15410 "TARGET_USE_FANCY_MATH_387
15411 && flag_unsafe_math_optimizations"
15412 "#"
15413 [(set_attr "type" "fistp")
15414 (set_attr "i387_cw" "<rounding>")
15415 (set_attr "mode" "DI")])
15416
15417 (define_split
15418 [(set (match_operand:DI 0 "register_operand")
15419 (unspec:DI [(match_operand:XF 1 "register_operand")]
15420 FIST_ROUNDING))
15421 (use (match_operand:HI 2 "memory_operand"))
15422 (use (match_operand:HI 3 "memory_operand"))
15423 (clobber (match_operand:DI 4 "memory_operand"))
15424 (clobber (match_scratch 5))]
15425 "reload_completed"
15426 [(parallel [(set (match_dup 4)
15427 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15428 (use (match_dup 2))
15429 (use (match_dup 3))
15430 (clobber (match_dup 5))])
15431 (set (match_dup 0) (match_dup 4))])
15432
15433 (define_split
15434 [(set (match_operand:DI 0 "memory_operand")
15435 (unspec:DI [(match_operand:XF 1 "register_operand")]
15436 FIST_ROUNDING))
15437 (use (match_operand:HI 2 "memory_operand"))
15438 (use (match_operand:HI 3 "memory_operand"))
15439 (clobber (match_operand:DI 4 "memory_operand"))
15440 (clobber (match_scratch 5))]
15441 "reload_completed"
15442 [(parallel [(set (match_dup 0)
15443 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15444 (use (match_dup 2))
15445 (use (match_dup 3))
15446 (clobber (match_dup 5))])])
15447
15448 (define_insn "fist<mode>2_<rounding>"
15449 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15450 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15451 FIST_ROUNDING))
15452 (use (match_operand:HI 2 "memory_operand" "m"))
15453 (use (match_operand:HI 3 "memory_operand" "m"))]
15454 "TARGET_USE_FANCY_MATH_387
15455 && flag_unsafe_math_optimizations"
15456 "* return output_fix_trunc (insn, operands, false);"
15457 [(set_attr "type" "fistp")
15458 (set_attr "i387_cw" "<rounding>")
15459 (set_attr "mode" "<MODE>")])
15460
15461 (define_insn "fist<mode>2_<rounding>_with_temp"
15462 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15463 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15464 FIST_ROUNDING))
15465 (use (match_operand:HI 2 "memory_operand" "m,m"))
15466 (use (match_operand:HI 3 "memory_operand" "m,m"))
15467 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15468 "TARGET_USE_FANCY_MATH_387
15469 && flag_unsafe_math_optimizations"
15470 "#"
15471 [(set_attr "type" "fistp")
15472 (set_attr "i387_cw" "<rounding>")
15473 (set_attr "mode" "<MODE>")])
15474
15475 (define_split
15476 [(set (match_operand:SWI24 0 "register_operand")
15477 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15478 FIST_ROUNDING))
15479 (use (match_operand:HI 2 "memory_operand"))
15480 (use (match_operand:HI 3 "memory_operand"))
15481 (clobber (match_operand:SWI24 4 "memory_operand"))]
15482 "reload_completed"
15483 [(parallel [(set (match_dup 4)
15484 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15485 (use (match_dup 2))
15486 (use (match_dup 3))])
15487 (set (match_dup 0) (match_dup 4))])
15488
15489 (define_split
15490 [(set (match_operand:SWI24 0 "memory_operand")
15491 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15492 FIST_ROUNDING))
15493 (use (match_operand:HI 2 "memory_operand"))
15494 (use (match_operand:HI 3 "memory_operand"))
15495 (clobber (match_operand:SWI24 4 "memory_operand"))]
15496 "reload_completed"
15497 [(parallel [(set (match_dup 0)
15498 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15499 (use (match_dup 2))
15500 (use (match_dup 3))])])
15501
15502 (define_expand "l<rounding_insn>xf<mode>2"
15503 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15504 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15505 FIST_ROUNDING))
15506 (clobber (reg:CC FLAGS_REG))])]
15507 "TARGET_USE_FANCY_MATH_387
15508 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15509 && flag_unsafe_math_optimizations")
15510
15511 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15512 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15513 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15514 FIST_ROUNDING))
15515 (clobber (reg:CC FLAGS_REG))])]
15516 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15517 && !flag_trapping_math"
15518 {
15519 if (TARGET_64BIT && optimize_insn_for_size_p ())
15520 FAIL;
15521
15522 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15523 ix86_expand_lfloorceil (operands[0], operands[1], true);
15524 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15525 ix86_expand_lfloorceil (operands[0], operands[1], false);
15526 else
15527 gcc_unreachable ();
15528
15529 DONE;
15530 })
15531
15532 (define_insn "fxam<mode>2_i387"
15533 [(set (match_operand:HI 0 "register_operand" "=a")
15534 (unspec:HI
15535 [(match_operand:X87MODEF 1 "register_operand" "f")]
15536 UNSPEC_FXAM))]
15537 "TARGET_USE_FANCY_MATH_387"
15538 "fxam\n\tfnstsw\t%0"
15539 [(set_attr "type" "multi")
15540 (set_attr "length" "4")
15541 (set_attr "unit" "i387")
15542 (set_attr "mode" "<MODE>")])
15543
15544 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15545 [(set (match_operand:HI 0 "register_operand")
15546 (unspec:HI
15547 [(match_operand:MODEF 1 "memory_operand")]
15548 UNSPEC_FXAM_MEM))]
15549 "TARGET_USE_FANCY_MATH_387
15550 && can_create_pseudo_p ()"
15551 "#"
15552 "&& 1"
15553 [(set (match_dup 2)(match_dup 1))
15554 (set (match_dup 0)
15555 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15556 {
15557 operands[2] = gen_reg_rtx (<MODE>mode);
15558
15559 MEM_VOLATILE_P (operands[1]) = 1;
15560 }
15561 [(set_attr "type" "multi")
15562 (set_attr "unit" "i387")
15563 (set_attr "mode" "<MODE>")])
15564
15565 (define_expand "isinfxf2"
15566 [(use (match_operand:SI 0 "register_operand"))
15567 (use (match_operand:XF 1 "register_operand"))]
15568 "TARGET_USE_FANCY_MATH_387
15569 && TARGET_C99_FUNCTIONS"
15570 {
15571 rtx mask = GEN_INT (0x45);
15572 rtx val = GEN_INT (0x05);
15573
15574 rtx cond;
15575
15576 rtx scratch = gen_reg_rtx (HImode);
15577 rtx res = gen_reg_rtx (QImode);
15578
15579 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15580
15581 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15582 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15583 cond = gen_rtx_fmt_ee (EQ, QImode,
15584 gen_rtx_REG (CCmode, FLAGS_REG),
15585 const0_rtx);
15586 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15587 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15588 DONE;
15589 })
15590
15591 (define_expand "isinf<mode>2"
15592 [(use (match_operand:SI 0 "register_operand"))
15593 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15594 "TARGET_USE_FANCY_MATH_387
15595 && TARGET_C99_FUNCTIONS
15596 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15597 {
15598 rtx mask = GEN_INT (0x45);
15599 rtx val = GEN_INT (0x05);
15600
15601 rtx cond;
15602
15603 rtx scratch = gen_reg_rtx (HImode);
15604 rtx res = gen_reg_rtx (QImode);
15605
15606 /* Remove excess precision by forcing value through memory. */
15607 if (memory_operand (operands[1], VOIDmode))
15608 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15609 else
15610 {
15611 enum ix86_stack_slot slot = (virtuals_instantiated
15612 ? SLOT_TEMP
15613 : SLOT_VIRTUAL);
15614 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15615
15616 emit_move_insn (temp, operands[1]);
15617 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15618 }
15619
15620 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15621 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15622 cond = gen_rtx_fmt_ee (EQ, QImode,
15623 gen_rtx_REG (CCmode, FLAGS_REG),
15624 const0_rtx);
15625 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15626 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15627 DONE;
15628 })
15629
15630 (define_expand "signbitxf2"
15631 [(use (match_operand:SI 0 "register_operand"))
15632 (use (match_operand:XF 1 "register_operand"))]
15633 "TARGET_USE_FANCY_MATH_387"
15634 {
15635 rtx scratch = gen_reg_rtx (HImode);
15636
15637 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15638 emit_insn (gen_andsi3 (operands[0],
15639 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15640 DONE;
15641 })
15642
15643 (define_insn "movmsk_df"
15644 [(set (match_operand:SI 0 "register_operand" "=r")
15645 (unspec:SI
15646 [(match_operand:DF 1 "register_operand" "x")]
15647 UNSPEC_MOVMSK))]
15648 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15649 "%vmovmskpd\t{%1, %0|%0, %1}"
15650 [(set_attr "type" "ssemov")
15651 (set_attr "prefix" "maybe_vex")
15652 (set_attr "mode" "DF")])
15653
15654 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15655 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15656 (define_expand "signbitdf2"
15657 [(use (match_operand:SI 0 "register_operand"))
15658 (use (match_operand:DF 1 "register_operand"))]
15659 "TARGET_USE_FANCY_MATH_387
15660 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15661 {
15662 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15663 {
15664 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15665 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15666 }
15667 else
15668 {
15669 rtx scratch = gen_reg_rtx (HImode);
15670
15671 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15672 emit_insn (gen_andsi3 (operands[0],
15673 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15674 }
15675 DONE;
15676 })
15677
15678 (define_expand "signbitsf2"
15679 [(use (match_operand:SI 0 "register_operand"))
15680 (use (match_operand:SF 1 "register_operand"))]
15681 "TARGET_USE_FANCY_MATH_387
15682 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15683 {
15684 rtx scratch = gen_reg_rtx (HImode);
15685
15686 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15687 emit_insn (gen_andsi3 (operands[0],
15688 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15689 DONE;
15690 })
15691 \f
15692 ;; Block operation instructions
15693
15694 (define_insn "cld"
15695 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15696 ""
15697 "cld"
15698 [(set_attr "length" "1")
15699 (set_attr "length_immediate" "0")
15700 (set_attr "modrm" "0")])
15701
15702 (define_expand "movmem<mode>"
15703 [(use (match_operand:BLK 0 "memory_operand"))
15704 (use (match_operand:BLK 1 "memory_operand"))
15705 (use (match_operand:SWI48 2 "nonmemory_operand"))
15706 (use (match_operand:SWI48 3 "const_int_operand"))
15707 (use (match_operand:SI 4 "const_int_operand"))
15708 (use (match_operand:SI 5 "const_int_operand"))]
15709 ""
15710 {
15711 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15712 operands[4], operands[5]))
15713 DONE;
15714 else
15715 FAIL;
15716 })
15717
15718 ;; Most CPUs don't like single string operations
15719 ;; Handle this case here to simplify previous expander.
15720
15721 (define_expand "strmov"
15722 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15723 (set (match_operand 1 "memory_operand") (match_dup 4))
15724 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15725 (clobber (reg:CC FLAGS_REG))])
15726 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15727 (clobber (reg:CC FLAGS_REG))])]
15728 ""
15729 {
15730 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15731
15732 /* If .md ever supports :P for Pmode, these can be directly
15733 in the pattern above. */
15734 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15735 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15736
15737 /* Can't use this if the user has appropriated esi or edi. */
15738 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15739 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15740 {
15741 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15742 operands[2], operands[3],
15743 operands[5], operands[6]));
15744 DONE;
15745 }
15746
15747 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15748 })
15749
15750 (define_expand "strmov_singleop"
15751 [(parallel [(set (match_operand 1 "memory_operand")
15752 (match_operand 3 "memory_operand"))
15753 (set (match_operand 0 "register_operand")
15754 (match_operand 4))
15755 (set (match_operand 2 "register_operand")
15756 (match_operand 5))])]
15757 ""
15758 "ix86_current_function_needs_cld = 1;")
15759
15760 (define_insn "*strmovdi_rex_1"
15761 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15762 (mem:DI (match_operand:P 3 "register_operand" "1")))
15763 (set (match_operand:P 0 "register_operand" "=D")
15764 (plus:P (match_dup 2)
15765 (const_int 8)))
15766 (set (match_operand:P 1 "register_operand" "=S")
15767 (plus:P (match_dup 3)
15768 (const_int 8)))]
15769 "TARGET_64BIT
15770 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15771 "%^movsq"
15772 [(set_attr "type" "str")
15773 (set_attr "memory" "both")
15774 (set_attr "mode" "DI")])
15775
15776 (define_insn "*strmovsi_1"
15777 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15778 (mem:SI (match_operand:P 3 "register_operand" "1")))
15779 (set (match_operand:P 0 "register_operand" "=D")
15780 (plus:P (match_dup 2)
15781 (const_int 4)))
15782 (set (match_operand:P 1 "register_operand" "=S")
15783 (plus:P (match_dup 3)
15784 (const_int 4)))]
15785 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15786 "%^movs{l|d}"
15787 [(set_attr "type" "str")
15788 (set_attr "memory" "both")
15789 (set_attr "mode" "SI")])
15790
15791 (define_insn "*strmovhi_1"
15792 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15793 (mem:HI (match_operand:P 3 "register_operand" "1")))
15794 (set (match_operand:P 0 "register_operand" "=D")
15795 (plus:P (match_dup 2)
15796 (const_int 2)))
15797 (set (match_operand:P 1 "register_operand" "=S")
15798 (plus:P (match_dup 3)
15799 (const_int 2)))]
15800 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15801 "%^movsw"
15802 [(set_attr "type" "str")
15803 (set_attr "memory" "both")
15804 (set_attr "mode" "HI")])
15805
15806 (define_insn "*strmovqi_1"
15807 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15808 (mem:QI (match_operand:P 3 "register_operand" "1")))
15809 (set (match_operand:P 0 "register_operand" "=D")
15810 (plus:P (match_dup 2)
15811 (const_int 1)))
15812 (set (match_operand:P 1 "register_operand" "=S")
15813 (plus:P (match_dup 3)
15814 (const_int 1)))]
15815 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15816 "%^movsb"
15817 [(set_attr "type" "str")
15818 (set_attr "memory" "both")
15819 (set (attr "prefix_rex")
15820 (if_then_else
15821 (match_test "<P:MODE>mode == DImode")
15822 (const_string "0")
15823 (const_string "*")))
15824 (set_attr "mode" "QI")])
15825
15826 (define_expand "rep_mov"
15827 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15828 (set (match_operand 0 "register_operand")
15829 (match_operand 5))
15830 (set (match_operand 2 "register_operand")
15831 (match_operand 6))
15832 (set (match_operand 1 "memory_operand")
15833 (match_operand 3 "memory_operand"))
15834 (use (match_dup 4))])]
15835 ""
15836 "ix86_current_function_needs_cld = 1;")
15837
15838 (define_insn "*rep_movdi_rex64"
15839 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15840 (set (match_operand:P 0 "register_operand" "=D")
15841 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15842 (const_int 3))
15843 (match_operand:P 3 "register_operand" "0")))
15844 (set (match_operand:P 1 "register_operand" "=S")
15845 (plus:P (ashift:P (match_dup 5) (const_int 3))
15846 (match_operand:P 4 "register_operand" "1")))
15847 (set (mem:BLK (match_dup 3))
15848 (mem:BLK (match_dup 4)))
15849 (use (match_dup 5))]
15850 "TARGET_64BIT
15851 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15852 "%^rep{%;} movsq"
15853 [(set_attr "type" "str")
15854 (set_attr "prefix_rep" "1")
15855 (set_attr "memory" "both")
15856 (set_attr "mode" "DI")])
15857
15858 (define_insn "*rep_movsi"
15859 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15860 (set (match_operand:P 0 "register_operand" "=D")
15861 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15862 (const_int 2))
15863 (match_operand:P 3 "register_operand" "0")))
15864 (set (match_operand:P 1 "register_operand" "=S")
15865 (plus:P (ashift:P (match_dup 5) (const_int 2))
15866 (match_operand:P 4 "register_operand" "1")))
15867 (set (mem:BLK (match_dup 3))
15868 (mem:BLK (match_dup 4)))
15869 (use (match_dup 5))]
15870 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15871 "%^rep{%;} movs{l|d}"
15872 [(set_attr "type" "str")
15873 (set_attr "prefix_rep" "1")
15874 (set_attr "memory" "both")
15875 (set_attr "mode" "SI")])
15876
15877 (define_insn "*rep_movqi"
15878 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15879 (set (match_operand:P 0 "register_operand" "=D")
15880 (plus:P (match_operand:P 3 "register_operand" "0")
15881 (match_operand:P 5 "register_operand" "2")))
15882 (set (match_operand:P 1 "register_operand" "=S")
15883 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15884 (set (mem:BLK (match_dup 3))
15885 (mem:BLK (match_dup 4)))
15886 (use (match_dup 5))]
15887 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15888 "%^rep{%;} movsb"
15889 [(set_attr "type" "str")
15890 (set_attr "prefix_rep" "1")
15891 (set_attr "memory" "both")
15892 (set_attr "mode" "QI")])
15893
15894 (define_expand "setmem<mode>"
15895 [(use (match_operand:BLK 0 "memory_operand"))
15896 (use (match_operand:SWI48 1 "nonmemory_operand"))
15897 (use (match_operand:QI 2 "nonmemory_operand"))
15898 (use (match_operand 3 "const_int_operand"))
15899 (use (match_operand:SI 4 "const_int_operand"))
15900 (use (match_operand:SI 5 "const_int_operand"))]
15901 ""
15902 {
15903 if (ix86_expand_setmem (operands[0], operands[1],
15904 operands[2], operands[3],
15905 operands[4], operands[5]))
15906 DONE;
15907 else
15908 FAIL;
15909 })
15910
15911 ;; Most CPUs don't like single string operations
15912 ;; Handle this case here to simplify previous expander.
15913
15914 (define_expand "strset"
15915 [(set (match_operand 1 "memory_operand")
15916 (match_operand 2 "register_operand"))
15917 (parallel [(set (match_operand 0 "register_operand")
15918 (match_dup 3))
15919 (clobber (reg:CC FLAGS_REG))])]
15920 ""
15921 {
15922 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15923 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15924
15925 /* If .md ever supports :P for Pmode, this can be directly
15926 in the pattern above. */
15927 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15928 GEN_INT (GET_MODE_SIZE (GET_MODE
15929 (operands[2]))));
15930 /* Can't use this if the user has appropriated eax or edi. */
15931 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15932 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15933 {
15934 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15935 operands[3]));
15936 DONE;
15937 }
15938 })
15939
15940 (define_expand "strset_singleop"
15941 [(parallel [(set (match_operand 1 "memory_operand")
15942 (match_operand 2 "register_operand"))
15943 (set (match_operand 0 "register_operand")
15944 (match_operand 3))])]
15945 ""
15946 "ix86_current_function_needs_cld = 1;")
15947
15948 (define_insn "*strsetdi_rex_1"
15949 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15950 (match_operand:DI 2 "register_operand" "a"))
15951 (set (match_operand:P 0 "register_operand" "=D")
15952 (plus:P (match_dup 1)
15953 (const_int 8)))]
15954 "TARGET_64BIT
15955 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15956 "%^stosq"
15957 [(set_attr "type" "str")
15958 (set_attr "memory" "store")
15959 (set_attr "mode" "DI")])
15960
15961 (define_insn "*strsetsi_1"
15962 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15963 (match_operand:SI 2 "register_operand" "a"))
15964 (set (match_operand:P 0 "register_operand" "=D")
15965 (plus:P (match_dup 1)
15966 (const_int 4)))]
15967 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15968 "%^stos{l|d}"
15969 [(set_attr "type" "str")
15970 (set_attr "memory" "store")
15971 (set_attr "mode" "SI")])
15972
15973 (define_insn "*strsethi_1"
15974 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15975 (match_operand:HI 2 "register_operand" "a"))
15976 (set (match_operand:P 0 "register_operand" "=D")
15977 (plus:P (match_dup 1)
15978 (const_int 2)))]
15979 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15980 "%^stosw"
15981 [(set_attr "type" "str")
15982 (set_attr "memory" "store")
15983 (set_attr "mode" "HI")])
15984
15985 (define_insn "*strsetqi_1"
15986 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15987 (match_operand:QI 2 "register_operand" "a"))
15988 (set (match_operand:P 0 "register_operand" "=D")
15989 (plus:P (match_dup 1)
15990 (const_int 1)))]
15991 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15992 "%^stosb"
15993 [(set_attr "type" "str")
15994 (set_attr "memory" "store")
15995 (set (attr "prefix_rex")
15996 (if_then_else
15997 (match_test "<P:MODE>mode == DImode")
15998 (const_string "0")
15999 (const_string "*")))
16000 (set_attr "mode" "QI")])
16001
16002 (define_expand "rep_stos"
16003 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16004 (set (match_operand 0 "register_operand")
16005 (match_operand 4))
16006 (set (match_operand 2 "memory_operand") (const_int 0))
16007 (use (match_operand 3 "register_operand"))
16008 (use (match_dup 1))])]
16009 ""
16010 "ix86_current_function_needs_cld = 1;")
16011
16012 (define_insn "*rep_stosdi_rex64"
16013 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16014 (set (match_operand:P 0 "register_operand" "=D")
16015 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16016 (const_int 3))
16017 (match_operand:P 3 "register_operand" "0")))
16018 (set (mem:BLK (match_dup 3))
16019 (const_int 0))
16020 (use (match_operand:DI 2 "register_operand" "a"))
16021 (use (match_dup 4))]
16022 "TARGET_64BIT
16023 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16024 "%^rep{%;} stosq"
16025 [(set_attr "type" "str")
16026 (set_attr "prefix_rep" "1")
16027 (set_attr "memory" "store")
16028 (set_attr "mode" "DI")])
16029
16030 (define_insn "*rep_stossi"
16031 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16032 (set (match_operand:P 0 "register_operand" "=D")
16033 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16034 (const_int 2))
16035 (match_operand:P 3 "register_operand" "0")))
16036 (set (mem:BLK (match_dup 3))
16037 (const_int 0))
16038 (use (match_operand:SI 2 "register_operand" "a"))
16039 (use (match_dup 4))]
16040 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16041 "%^rep{%;} stos{l|d}"
16042 [(set_attr "type" "str")
16043 (set_attr "prefix_rep" "1")
16044 (set_attr "memory" "store")
16045 (set_attr "mode" "SI")])
16046
16047 (define_insn "*rep_stosqi"
16048 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16049 (set (match_operand:P 0 "register_operand" "=D")
16050 (plus:P (match_operand:P 3 "register_operand" "0")
16051 (match_operand:P 4 "register_operand" "1")))
16052 (set (mem:BLK (match_dup 3))
16053 (const_int 0))
16054 (use (match_operand:QI 2 "register_operand" "a"))
16055 (use (match_dup 4))]
16056 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16057 "%^rep{%;} stosb"
16058 [(set_attr "type" "str")
16059 (set_attr "prefix_rep" "1")
16060 (set_attr "memory" "store")
16061 (set (attr "prefix_rex")
16062 (if_then_else
16063 (match_test "<P:MODE>mode == DImode")
16064 (const_string "0")
16065 (const_string "*")))
16066 (set_attr "mode" "QI")])
16067
16068 (define_expand "cmpstrnsi"
16069 [(set (match_operand:SI 0 "register_operand")
16070 (compare:SI (match_operand:BLK 1 "general_operand")
16071 (match_operand:BLK 2 "general_operand")))
16072 (use (match_operand 3 "general_operand"))
16073 (use (match_operand 4 "immediate_operand"))]
16074 ""
16075 {
16076 rtx addr1, addr2, out, outlow, count, countreg, align;
16077
16078 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16079 FAIL;
16080
16081 /* Can't use this if the user has appropriated ecx, esi or edi. */
16082 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16083 FAIL;
16084
16085 out = operands[0];
16086 if (!REG_P (out))
16087 out = gen_reg_rtx (SImode);
16088
16089 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16090 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16091 if (addr1 != XEXP (operands[1], 0))
16092 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16093 if (addr2 != XEXP (operands[2], 0))
16094 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16095
16096 count = operands[3];
16097 countreg = ix86_zero_extend_to_Pmode (count);
16098
16099 /* %%% Iff we are testing strict equality, we can use known alignment
16100 to good advantage. This may be possible with combine, particularly
16101 once cc0 is dead. */
16102 align = operands[4];
16103
16104 if (CONST_INT_P (count))
16105 {
16106 if (INTVAL (count) == 0)
16107 {
16108 emit_move_insn (operands[0], const0_rtx);
16109 DONE;
16110 }
16111 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16112 operands[1], operands[2]));
16113 }
16114 else
16115 {
16116 rtx (*gen_cmp) (rtx, rtx);
16117
16118 gen_cmp = (TARGET_64BIT
16119 ? gen_cmpdi_1 : gen_cmpsi_1);
16120
16121 emit_insn (gen_cmp (countreg, countreg));
16122 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16123 operands[1], operands[2]));
16124 }
16125
16126 outlow = gen_lowpart (QImode, out);
16127 emit_insn (gen_cmpintqi (outlow));
16128 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16129
16130 if (operands[0] != out)
16131 emit_move_insn (operands[0], out);
16132
16133 DONE;
16134 })
16135
16136 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16137
16138 (define_expand "cmpintqi"
16139 [(set (match_dup 1)
16140 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16141 (set (match_dup 2)
16142 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16143 (parallel [(set (match_operand:QI 0 "register_operand")
16144 (minus:QI (match_dup 1)
16145 (match_dup 2)))
16146 (clobber (reg:CC FLAGS_REG))])]
16147 ""
16148 {
16149 operands[1] = gen_reg_rtx (QImode);
16150 operands[2] = gen_reg_rtx (QImode);
16151 })
16152
16153 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16154 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16155
16156 (define_expand "cmpstrnqi_nz_1"
16157 [(parallel [(set (reg:CC FLAGS_REG)
16158 (compare:CC (match_operand 4 "memory_operand")
16159 (match_operand 5 "memory_operand")))
16160 (use (match_operand 2 "register_operand"))
16161 (use (match_operand:SI 3 "immediate_operand"))
16162 (clobber (match_operand 0 "register_operand"))
16163 (clobber (match_operand 1 "register_operand"))
16164 (clobber (match_dup 2))])]
16165 ""
16166 "ix86_current_function_needs_cld = 1;")
16167
16168 (define_insn "*cmpstrnqi_nz_1"
16169 [(set (reg:CC FLAGS_REG)
16170 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16171 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16172 (use (match_operand:P 6 "register_operand" "2"))
16173 (use (match_operand:SI 3 "immediate_operand" "i"))
16174 (clobber (match_operand:P 0 "register_operand" "=S"))
16175 (clobber (match_operand:P 1 "register_operand" "=D"))
16176 (clobber (match_operand:P 2 "register_operand" "=c"))]
16177 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16178 "%^repz{%;} cmpsb"
16179 [(set_attr "type" "str")
16180 (set_attr "mode" "QI")
16181 (set (attr "prefix_rex")
16182 (if_then_else
16183 (match_test "<P:MODE>mode == DImode")
16184 (const_string "0")
16185 (const_string "*")))
16186 (set_attr "prefix_rep" "1")])
16187
16188 ;; The same, but the count is not known to not be zero.
16189
16190 (define_expand "cmpstrnqi_1"
16191 [(parallel [(set (reg:CC FLAGS_REG)
16192 (if_then_else:CC (ne (match_operand 2 "register_operand")
16193 (const_int 0))
16194 (compare:CC (match_operand 4 "memory_operand")
16195 (match_operand 5 "memory_operand"))
16196 (const_int 0)))
16197 (use (match_operand:SI 3 "immediate_operand"))
16198 (use (reg:CC FLAGS_REG))
16199 (clobber (match_operand 0 "register_operand"))
16200 (clobber (match_operand 1 "register_operand"))
16201 (clobber (match_dup 2))])]
16202 ""
16203 "ix86_current_function_needs_cld = 1;")
16204
16205 (define_insn "*cmpstrnqi_1"
16206 [(set (reg:CC FLAGS_REG)
16207 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16208 (const_int 0))
16209 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16210 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16211 (const_int 0)))
16212 (use (match_operand:SI 3 "immediate_operand" "i"))
16213 (use (reg:CC FLAGS_REG))
16214 (clobber (match_operand:P 0 "register_operand" "=S"))
16215 (clobber (match_operand:P 1 "register_operand" "=D"))
16216 (clobber (match_operand:P 2 "register_operand" "=c"))]
16217 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16218 "%^repz{%;} cmpsb"
16219 [(set_attr "type" "str")
16220 (set_attr "mode" "QI")
16221 (set (attr "prefix_rex")
16222 (if_then_else
16223 (match_test "<P:MODE>mode == DImode")
16224 (const_string "0")
16225 (const_string "*")))
16226 (set_attr "prefix_rep" "1")])
16227
16228 (define_expand "strlen<mode>"
16229 [(set (match_operand:P 0 "register_operand")
16230 (unspec:P [(match_operand:BLK 1 "general_operand")
16231 (match_operand:QI 2 "immediate_operand")
16232 (match_operand 3 "immediate_operand")]
16233 UNSPEC_SCAS))]
16234 ""
16235 {
16236 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16237 DONE;
16238 else
16239 FAIL;
16240 })
16241
16242 (define_expand "strlenqi_1"
16243 [(parallel [(set (match_operand 0 "register_operand")
16244 (match_operand 2))
16245 (clobber (match_operand 1 "register_operand"))
16246 (clobber (reg:CC FLAGS_REG))])]
16247 ""
16248 "ix86_current_function_needs_cld = 1;")
16249
16250 (define_insn "*strlenqi_1"
16251 [(set (match_operand:P 0 "register_operand" "=&c")
16252 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16253 (match_operand:QI 2 "register_operand" "a")
16254 (match_operand:P 3 "immediate_operand" "i")
16255 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16256 (clobber (match_operand:P 1 "register_operand" "=D"))
16257 (clobber (reg:CC FLAGS_REG))]
16258 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16259 "%^repnz{%;} scasb"
16260 [(set_attr "type" "str")
16261 (set_attr "mode" "QI")
16262 (set (attr "prefix_rex")
16263 (if_then_else
16264 (match_test "<P:MODE>mode == DImode")
16265 (const_string "0")
16266 (const_string "*")))
16267 (set_attr "prefix_rep" "1")])
16268
16269 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16270 ;; handled in combine, but it is not currently up to the task.
16271 ;; When used for their truth value, the cmpstrn* expanders generate
16272 ;; code like this:
16273 ;;
16274 ;; repz cmpsb
16275 ;; seta %al
16276 ;; setb %dl
16277 ;; cmpb %al, %dl
16278 ;; jcc label
16279 ;;
16280 ;; The intermediate three instructions are unnecessary.
16281
16282 ;; This one handles cmpstrn*_nz_1...
16283 (define_peephole2
16284 [(parallel[
16285 (set (reg:CC FLAGS_REG)
16286 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16287 (mem:BLK (match_operand 5 "register_operand"))))
16288 (use (match_operand 6 "register_operand"))
16289 (use (match_operand:SI 3 "immediate_operand"))
16290 (clobber (match_operand 0 "register_operand"))
16291 (clobber (match_operand 1 "register_operand"))
16292 (clobber (match_operand 2 "register_operand"))])
16293 (set (match_operand:QI 7 "register_operand")
16294 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16295 (set (match_operand:QI 8 "register_operand")
16296 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16297 (set (reg FLAGS_REG)
16298 (compare (match_dup 7) (match_dup 8)))
16299 ]
16300 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16301 [(parallel[
16302 (set (reg:CC FLAGS_REG)
16303 (compare:CC (mem:BLK (match_dup 4))
16304 (mem:BLK (match_dup 5))))
16305 (use (match_dup 6))
16306 (use (match_dup 3))
16307 (clobber (match_dup 0))
16308 (clobber (match_dup 1))
16309 (clobber (match_dup 2))])])
16310
16311 ;; ...and this one handles cmpstrn*_1.
16312 (define_peephole2
16313 [(parallel[
16314 (set (reg:CC FLAGS_REG)
16315 (if_then_else:CC (ne (match_operand 6 "register_operand")
16316 (const_int 0))
16317 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16318 (mem:BLK (match_operand 5 "register_operand")))
16319 (const_int 0)))
16320 (use (match_operand:SI 3 "immediate_operand"))
16321 (use (reg:CC FLAGS_REG))
16322 (clobber (match_operand 0 "register_operand"))
16323 (clobber (match_operand 1 "register_operand"))
16324 (clobber (match_operand 2 "register_operand"))])
16325 (set (match_operand:QI 7 "register_operand")
16326 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16327 (set (match_operand:QI 8 "register_operand")
16328 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16329 (set (reg FLAGS_REG)
16330 (compare (match_dup 7) (match_dup 8)))
16331 ]
16332 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16333 [(parallel[
16334 (set (reg:CC FLAGS_REG)
16335 (if_then_else:CC (ne (match_dup 6)
16336 (const_int 0))
16337 (compare:CC (mem:BLK (match_dup 4))
16338 (mem:BLK (match_dup 5)))
16339 (const_int 0)))
16340 (use (match_dup 3))
16341 (use (reg:CC FLAGS_REG))
16342 (clobber (match_dup 0))
16343 (clobber (match_dup 1))
16344 (clobber (match_dup 2))])])
16345 \f
16346 ;; Conditional move instructions.
16347
16348 (define_expand "mov<mode>cc"
16349 [(set (match_operand:SWIM 0 "register_operand")
16350 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16351 (match_operand:SWIM 2 "<general_operand>")
16352 (match_operand:SWIM 3 "<general_operand>")))]
16353 ""
16354 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16355
16356 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16357 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16358 ;; So just document what we're doing explicitly.
16359
16360 (define_expand "x86_mov<mode>cc_0_m1"
16361 [(parallel
16362 [(set (match_operand:SWI48 0 "register_operand")
16363 (if_then_else:SWI48
16364 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16365 [(match_operand 1 "flags_reg_operand")
16366 (const_int 0)])
16367 (const_int -1)
16368 (const_int 0)))
16369 (clobber (reg:CC FLAGS_REG))])])
16370
16371 (define_insn "*x86_mov<mode>cc_0_m1"
16372 [(set (match_operand:SWI48 0 "register_operand" "=r")
16373 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16374 [(reg FLAGS_REG) (const_int 0)])
16375 (const_int -1)
16376 (const_int 0)))
16377 (clobber (reg:CC FLAGS_REG))]
16378 ""
16379 "sbb{<imodesuffix>}\t%0, %0"
16380 ; Since we don't have the proper number of operands for an alu insn,
16381 ; fill in all the blanks.
16382 [(set_attr "type" "alu")
16383 (set_attr "use_carry" "1")
16384 (set_attr "pent_pair" "pu")
16385 (set_attr "memory" "none")
16386 (set_attr "imm_disp" "false")
16387 (set_attr "mode" "<MODE>")
16388 (set_attr "length_immediate" "0")])
16389
16390 (define_insn "*x86_mov<mode>cc_0_m1_se"
16391 [(set (match_operand:SWI48 0 "register_operand" "=r")
16392 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16393 [(reg FLAGS_REG) (const_int 0)])
16394 (const_int 1)
16395 (const_int 0)))
16396 (clobber (reg:CC FLAGS_REG))]
16397 ""
16398 "sbb{<imodesuffix>}\t%0, %0"
16399 [(set_attr "type" "alu")
16400 (set_attr "use_carry" "1")
16401 (set_attr "pent_pair" "pu")
16402 (set_attr "memory" "none")
16403 (set_attr "imm_disp" "false")
16404 (set_attr "mode" "<MODE>")
16405 (set_attr "length_immediate" "0")])
16406
16407 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16408 [(set (match_operand:SWI48 0 "register_operand" "=r")
16409 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16410 [(reg FLAGS_REG) (const_int 0)])))
16411 (clobber (reg:CC FLAGS_REG))]
16412 ""
16413 "sbb{<imodesuffix>}\t%0, %0"
16414 [(set_attr "type" "alu")
16415 (set_attr "use_carry" "1")
16416 (set_attr "pent_pair" "pu")
16417 (set_attr "memory" "none")
16418 (set_attr "imm_disp" "false")
16419 (set_attr "mode" "<MODE>")
16420 (set_attr "length_immediate" "0")])
16421
16422 (define_insn "*mov<mode>cc_noc"
16423 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16424 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16425 [(reg FLAGS_REG) (const_int 0)])
16426 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16427 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16428 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16429 "@
16430 cmov%O2%C1\t{%2, %0|%0, %2}
16431 cmov%O2%c1\t{%3, %0|%0, %3}"
16432 [(set_attr "type" "icmov")
16433 (set_attr "mode" "<MODE>")])
16434
16435 (define_insn "*movqicc_noc"
16436 [(set (match_operand:QI 0 "register_operand" "=r,r")
16437 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16438 [(reg FLAGS_REG) (const_int 0)])
16439 (match_operand:QI 2 "register_operand" "r,0")
16440 (match_operand:QI 3 "register_operand" "0,r")))]
16441 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16442 "#"
16443 [(set_attr "type" "icmov")
16444 (set_attr "mode" "QI")])
16445
16446 (define_split
16447 [(set (match_operand 0 "register_operand")
16448 (if_then_else (match_operator 1 "ix86_comparison_operator"
16449 [(reg FLAGS_REG) (const_int 0)])
16450 (match_operand 2 "register_operand")
16451 (match_operand 3 "register_operand")))]
16452 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16453 && (GET_MODE (operands[0]) == QImode
16454 || GET_MODE (operands[0]) == HImode)
16455 && reload_completed"
16456 [(set (match_dup 0)
16457 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16458 {
16459 operands[0] = gen_lowpart (SImode, operands[0]);
16460 operands[2] = gen_lowpart (SImode, operands[2]);
16461 operands[3] = gen_lowpart (SImode, operands[3]);
16462 })
16463
16464 (define_expand "mov<mode>cc"
16465 [(set (match_operand:X87MODEF 0 "register_operand")
16466 (if_then_else:X87MODEF
16467 (match_operand 1 "ix86_fp_comparison_operator")
16468 (match_operand:X87MODEF 2 "register_operand")
16469 (match_operand:X87MODEF 3 "register_operand")))]
16470 "(TARGET_80387 && TARGET_CMOVE)
16471 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16472 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16473
16474 (define_insn "*movxfcc_1"
16475 [(set (match_operand:XF 0 "register_operand" "=f,f")
16476 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16477 [(reg FLAGS_REG) (const_int 0)])
16478 (match_operand:XF 2 "register_operand" "f,0")
16479 (match_operand:XF 3 "register_operand" "0,f")))]
16480 "TARGET_80387 && TARGET_CMOVE"
16481 "@
16482 fcmov%F1\t{%2, %0|%0, %2}
16483 fcmov%f1\t{%3, %0|%0, %3}"
16484 [(set_attr "type" "fcmov")
16485 (set_attr "mode" "XF")])
16486
16487 (define_insn "*movdfcc_1_rex64"
16488 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16489 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16490 [(reg FLAGS_REG) (const_int 0)])
16491 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16492 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16493 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16494 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16495 "@
16496 fcmov%F1\t{%2, %0|%0, %2}
16497 fcmov%f1\t{%3, %0|%0, %3}
16498 cmov%O2%C1\t{%2, %0|%0, %2}
16499 cmov%O2%c1\t{%3, %0|%0, %3}"
16500 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16501 (set_attr "mode" "DF,DF,DI,DI")])
16502
16503 (define_insn "*movdfcc_1"
16504 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16505 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16506 [(reg FLAGS_REG) (const_int 0)])
16507 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16508 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16509 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16510 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16511 "@
16512 fcmov%F1\t{%2, %0|%0, %2}
16513 fcmov%f1\t{%3, %0|%0, %3}
16514 #
16515 #"
16516 [(set_attr "type" "fcmov,fcmov,multi,multi")
16517 (set_attr "mode" "DF,DF,DI,DI")])
16518
16519 (define_split
16520 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16521 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16522 [(reg FLAGS_REG) (const_int 0)])
16523 (match_operand:DF 2 "nonimmediate_operand")
16524 (match_operand:DF 3 "nonimmediate_operand")))]
16525 "!TARGET_64BIT && reload_completed"
16526 [(set (match_dup 2)
16527 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16528 (set (match_dup 3)
16529 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16530 {
16531 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16532 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16533 })
16534
16535 (define_insn "*movsfcc_1_387"
16536 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16537 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16538 [(reg FLAGS_REG) (const_int 0)])
16539 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16540 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16541 "TARGET_80387 && TARGET_CMOVE
16542 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16543 "@
16544 fcmov%F1\t{%2, %0|%0, %2}
16545 fcmov%f1\t{%3, %0|%0, %3}
16546 cmov%O2%C1\t{%2, %0|%0, %2}
16547 cmov%O2%c1\t{%3, %0|%0, %3}"
16548 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16549 (set_attr "mode" "SF,SF,SI,SI")])
16550
16551 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16552 ;; the scalar versions to have only XMM registers as operands.
16553
16554 ;; XOP conditional move
16555 (define_insn "*xop_pcmov_<mode>"
16556 [(set (match_operand:MODEF 0 "register_operand" "=x")
16557 (if_then_else:MODEF
16558 (match_operand:MODEF 1 "register_operand" "x")
16559 (match_operand:MODEF 2 "register_operand" "x")
16560 (match_operand:MODEF 3 "register_operand" "x")))]
16561 "TARGET_XOP"
16562 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16563 [(set_attr "type" "sse4arg")])
16564
16565 ;; These versions of the min/max patterns are intentionally ignorant of
16566 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16567 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16568 ;; are undefined in this condition, we're certain this is correct.
16569
16570 (define_insn "<code><mode>3"
16571 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16572 (smaxmin:MODEF
16573 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16574 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16575 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16576 "@
16577 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16578 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16579 [(set_attr "isa" "noavx,avx")
16580 (set_attr "prefix" "orig,vex")
16581 (set_attr "type" "sseadd")
16582 (set_attr "mode" "<MODE>")])
16583
16584 ;; These versions of the min/max patterns implement exactly the operations
16585 ;; min = (op1 < op2 ? op1 : op2)
16586 ;; max = (!(op1 < op2) ? op1 : op2)
16587 ;; Their operands are not commutative, and thus they may be used in the
16588 ;; presence of -0.0 and NaN.
16589
16590 (define_int_iterator IEEE_MAXMIN
16591 [UNSPEC_IEEE_MAX
16592 UNSPEC_IEEE_MIN])
16593
16594 (define_int_attr ieee_maxmin
16595 [(UNSPEC_IEEE_MAX "max")
16596 (UNSPEC_IEEE_MIN "min")])
16597
16598 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16599 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16600 (unspec:MODEF
16601 [(match_operand:MODEF 1 "register_operand" "0,x")
16602 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16603 IEEE_MAXMIN))]
16604 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16605 "@
16606 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16607 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16608 [(set_attr "isa" "noavx,avx")
16609 (set_attr "prefix" "orig,vex")
16610 (set_attr "type" "sseadd")
16611 (set_attr "mode" "<MODE>")])
16612
16613 ;; Make two stack loads independent:
16614 ;; fld aa fld aa
16615 ;; fld %st(0) -> fld bb
16616 ;; fmul bb fmul %st(1), %st
16617 ;;
16618 ;; Actually we only match the last two instructions for simplicity.
16619 (define_peephole2
16620 [(set (match_operand 0 "fp_register_operand")
16621 (match_operand 1 "fp_register_operand"))
16622 (set (match_dup 0)
16623 (match_operator 2 "binary_fp_operator"
16624 [(match_dup 0)
16625 (match_operand 3 "memory_operand")]))]
16626 "REGNO (operands[0]) != REGNO (operands[1])"
16627 [(set (match_dup 0) (match_dup 3))
16628 (set (match_dup 0) (match_dup 4))]
16629
16630 ;; The % modifier is not operational anymore in peephole2's, so we have to
16631 ;; swap the operands manually in the case of addition and multiplication.
16632 {
16633 rtx op0, op1;
16634
16635 if (COMMUTATIVE_ARITH_P (operands[2]))
16636 op0 = operands[0], op1 = operands[1];
16637 else
16638 op0 = operands[1], op1 = operands[0];
16639
16640 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16641 GET_MODE (operands[2]),
16642 op0, op1);
16643 })
16644
16645 ;; Conditional addition patterns
16646 (define_expand "add<mode>cc"
16647 [(match_operand:SWI 0 "register_operand")
16648 (match_operand 1 "ordered_comparison_operator")
16649 (match_operand:SWI 2 "register_operand")
16650 (match_operand:SWI 3 "const_int_operand")]
16651 ""
16652 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16653 \f
16654 ;; Misc patterns (?)
16655
16656 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16657 ;; Otherwise there will be nothing to keep
16658 ;;
16659 ;; [(set (reg ebp) (reg esp))]
16660 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16661 ;; (clobber (eflags)]
16662 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16663 ;;
16664 ;; in proper program order.
16665
16666 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16667 [(set (match_operand:P 0 "register_operand" "=r,r")
16668 (plus:P (match_operand:P 1 "register_operand" "0,r")
16669 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16670 (clobber (reg:CC FLAGS_REG))
16671 (clobber (mem:BLK (scratch)))]
16672 ""
16673 {
16674 switch (get_attr_type (insn))
16675 {
16676 case TYPE_IMOV:
16677 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16678
16679 case TYPE_ALU:
16680 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16681 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16682 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16683
16684 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16685
16686 default:
16687 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16688 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16689 }
16690 }
16691 [(set (attr "type")
16692 (cond [(and (eq_attr "alternative" "0")
16693 (not (match_test "TARGET_OPT_AGU")))
16694 (const_string "alu")
16695 (match_operand:<MODE> 2 "const0_operand")
16696 (const_string "imov")
16697 ]
16698 (const_string "lea")))
16699 (set (attr "length_immediate")
16700 (cond [(eq_attr "type" "imov")
16701 (const_string "0")
16702 (and (eq_attr "type" "alu")
16703 (match_operand 2 "const128_operand"))
16704 (const_string "1")
16705 ]
16706 (const_string "*")))
16707 (set_attr "mode" "<MODE>")])
16708
16709 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16710 [(set (match_operand:P 0 "register_operand" "=r")
16711 (minus:P (match_operand:P 1 "register_operand" "0")
16712 (match_operand:P 2 "register_operand" "r")))
16713 (clobber (reg:CC FLAGS_REG))
16714 (clobber (mem:BLK (scratch)))]
16715 ""
16716 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16717 [(set_attr "type" "alu")
16718 (set_attr "mode" "<MODE>")])
16719
16720 (define_insn "allocate_stack_worker_probe_<mode>"
16721 [(set (match_operand:P 0 "register_operand" "=a")
16722 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16723 UNSPECV_STACK_PROBE))
16724 (clobber (reg:CC FLAGS_REG))]
16725 "ix86_target_stack_probe ()"
16726 "call\t___chkstk_ms"
16727 [(set_attr "type" "multi")
16728 (set_attr "length" "5")])
16729
16730 (define_expand "allocate_stack"
16731 [(match_operand 0 "register_operand")
16732 (match_operand 1 "general_operand")]
16733 "ix86_target_stack_probe ()"
16734 {
16735 rtx x;
16736
16737 #ifndef CHECK_STACK_LIMIT
16738 #define CHECK_STACK_LIMIT 0
16739 #endif
16740
16741 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16742 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16743 x = operands[1];
16744 else
16745 {
16746 rtx (*insn) (rtx, rtx);
16747
16748 x = copy_to_mode_reg (Pmode, operands[1]);
16749
16750 insn = (TARGET_64BIT
16751 ? gen_allocate_stack_worker_probe_di
16752 : gen_allocate_stack_worker_probe_si);
16753
16754 emit_insn (insn (x, x));
16755 }
16756
16757 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16758 stack_pointer_rtx, 0, OPTAB_DIRECT);
16759
16760 if (x != stack_pointer_rtx)
16761 emit_move_insn (stack_pointer_rtx, x);
16762
16763 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16764 DONE;
16765 })
16766
16767 ;; Use IOR for stack probes, this is shorter.
16768 (define_expand "probe_stack"
16769 [(match_operand 0 "memory_operand")]
16770 ""
16771 {
16772 rtx (*gen_ior3) (rtx, rtx, rtx);
16773
16774 gen_ior3 = (GET_MODE (operands[0]) == DImode
16775 ? gen_iordi3 : gen_iorsi3);
16776
16777 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16778 DONE;
16779 })
16780
16781 (define_insn "adjust_stack_and_probe<mode>"
16782 [(set (match_operand:P 0 "register_operand" "=r")
16783 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16784 UNSPECV_PROBE_STACK_RANGE))
16785 (set (reg:P SP_REG)
16786 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16787 (clobber (reg:CC FLAGS_REG))
16788 (clobber (mem:BLK (scratch)))]
16789 ""
16790 "* return output_adjust_stack_and_probe (operands[0]);"
16791 [(set_attr "type" "multi")])
16792
16793 (define_insn "probe_stack_range<mode>"
16794 [(set (match_operand:P 0 "register_operand" "=r")
16795 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16796 (match_operand:P 2 "const_int_operand" "n")]
16797 UNSPECV_PROBE_STACK_RANGE))
16798 (clobber (reg:CC FLAGS_REG))]
16799 ""
16800 "* return output_probe_stack_range (operands[0], operands[2]);"
16801 [(set_attr "type" "multi")])
16802
16803 (define_expand "builtin_setjmp_receiver"
16804 [(label_ref (match_operand 0))]
16805 "!TARGET_64BIT && flag_pic"
16806 {
16807 #if TARGET_MACHO
16808 if (TARGET_MACHO)
16809 {
16810 rtx xops[3];
16811 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16812 rtx label_rtx = gen_label_rtx ();
16813 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16814 xops[0] = xops[1] = picreg;
16815 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16816 ix86_expand_binary_operator (MINUS, SImode, xops);
16817 }
16818 else
16819 #endif
16820 emit_insn (gen_set_got (pic_offset_table_rtx));
16821 DONE;
16822 })
16823 \f
16824 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16825
16826 (define_split
16827 [(set (match_operand 0 "register_operand")
16828 (match_operator 3 "promotable_binary_operator"
16829 [(match_operand 1 "register_operand")
16830 (match_operand 2 "aligned_operand")]))
16831 (clobber (reg:CC FLAGS_REG))]
16832 "! TARGET_PARTIAL_REG_STALL && reload_completed
16833 && ((GET_MODE (operands[0]) == HImode
16834 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16835 /* ??? next two lines just !satisfies_constraint_K (...) */
16836 || !CONST_INT_P (operands[2])
16837 || satisfies_constraint_K (operands[2])))
16838 || (GET_MODE (operands[0]) == QImode
16839 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16840 [(parallel [(set (match_dup 0)
16841 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16842 (clobber (reg:CC FLAGS_REG))])]
16843 {
16844 operands[0] = gen_lowpart (SImode, operands[0]);
16845 operands[1] = gen_lowpart (SImode, operands[1]);
16846 if (GET_CODE (operands[3]) != ASHIFT)
16847 operands[2] = gen_lowpart (SImode, operands[2]);
16848 PUT_MODE (operands[3], SImode);
16849 })
16850
16851 ; Promote the QImode tests, as i386 has encoding of the AND
16852 ; instruction with 32-bit sign-extended immediate and thus the
16853 ; instruction size is unchanged, except in the %eax case for
16854 ; which it is increased by one byte, hence the ! optimize_size.
16855 (define_split
16856 [(set (match_operand 0 "flags_reg_operand")
16857 (match_operator 2 "compare_operator"
16858 [(and (match_operand 3 "aligned_operand")
16859 (match_operand 4 "const_int_operand"))
16860 (const_int 0)]))
16861 (set (match_operand 1 "register_operand")
16862 (and (match_dup 3) (match_dup 4)))]
16863 "! TARGET_PARTIAL_REG_STALL && reload_completed
16864 && optimize_insn_for_speed_p ()
16865 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16866 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16867 /* Ensure that the operand will remain sign-extended immediate. */
16868 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16869 [(parallel [(set (match_dup 0)
16870 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16871 (const_int 0)]))
16872 (set (match_dup 1)
16873 (and:SI (match_dup 3) (match_dup 4)))])]
16874 {
16875 operands[4]
16876 = gen_int_mode (INTVAL (operands[4])
16877 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16878 operands[1] = gen_lowpart (SImode, operands[1]);
16879 operands[3] = gen_lowpart (SImode, operands[3]);
16880 })
16881
16882 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16883 ; the TEST instruction with 32-bit sign-extended immediate and thus
16884 ; the instruction size would at least double, which is not what we
16885 ; want even with ! optimize_size.
16886 (define_split
16887 [(set (match_operand 0 "flags_reg_operand")
16888 (match_operator 1 "compare_operator"
16889 [(and (match_operand:HI 2 "aligned_operand")
16890 (match_operand:HI 3 "const_int_operand"))
16891 (const_int 0)]))]
16892 "! TARGET_PARTIAL_REG_STALL && reload_completed
16893 && ! TARGET_FAST_PREFIX
16894 && optimize_insn_for_speed_p ()
16895 /* Ensure that the operand will remain sign-extended immediate. */
16896 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16897 [(set (match_dup 0)
16898 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16899 (const_int 0)]))]
16900 {
16901 operands[3]
16902 = gen_int_mode (INTVAL (operands[3])
16903 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16904 operands[2] = gen_lowpart (SImode, operands[2]);
16905 })
16906
16907 (define_split
16908 [(set (match_operand 0 "register_operand")
16909 (neg (match_operand 1 "register_operand")))
16910 (clobber (reg:CC FLAGS_REG))]
16911 "! TARGET_PARTIAL_REG_STALL && reload_completed
16912 && (GET_MODE (operands[0]) == HImode
16913 || (GET_MODE (operands[0]) == QImode
16914 && (TARGET_PROMOTE_QImode
16915 || optimize_insn_for_size_p ())))"
16916 [(parallel [(set (match_dup 0)
16917 (neg:SI (match_dup 1)))
16918 (clobber (reg:CC FLAGS_REG))])]
16919 {
16920 operands[0] = gen_lowpart (SImode, operands[0]);
16921 operands[1] = gen_lowpart (SImode, operands[1]);
16922 })
16923
16924 (define_split
16925 [(set (match_operand 0 "register_operand")
16926 (not (match_operand 1 "register_operand")))]
16927 "! TARGET_PARTIAL_REG_STALL && reload_completed
16928 && (GET_MODE (operands[0]) == HImode
16929 || (GET_MODE (operands[0]) == QImode
16930 && (TARGET_PROMOTE_QImode
16931 || optimize_insn_for_size_p ())))"
16932 [(set (match_dup 0)
16933 (not:SI (match_dup 1)))]
16934 {
16935 operands[0] = gen_lowpart (SImode, operands[0]);
16936 operands[1] = gen_lowpart (SImode, operands[1]);
16937 })
16938 \f
16939 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16940 ;; transform a complex memory operation into two memory to register operations.
16941
16942 ;; Don't push memory operands
16943 (define_peephole2
16944 [(set (match_operand:SWI 0 "push_operand")
16945 (match_operand:SWI 1 "memory_operand"))
16946 (match_scratch:SWI 2 "<r>")]
16947 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16948 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16949 [(set (match_dup 2) (match_dup 1))
16950 (set (match_dup 0) (match_dup 2))])
16951
16952 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16953 ;; SImode pushes.
16954 (define_peephole2
16955 [(set (match_operand:SF 0 "push_operand")
16956 (match_operand:SF 1 "memory_operand"))
16957 (match_scratch:SF 2 "r")]
16958 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16959 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16960 [(set (match_dup 2) (match_dup 1))
16961 (set (match_dup 0) (match_dup 2))])
16962
16963 ;; Don't move an immediate directly to memory when the instruction
16964 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16965 (define_peephole2
16966 [(match_scratch:SWI124 1 "<r>")
16967 (set (match_operand:SWI124 0 "memory_operand")
16968 (const_int 0))]
16969 "optimize_insn_for_speed_p ()
16970 && ((<MODE>mode == HImode
16971 && TARGET_LCP_STALL)
16972 || (!TARGET_USE_MOV0
16973 && TARGET_SPLIT_LONG_MOVES
16974 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16975 && peep2_regno_dead_p (0, FLAGS_REG)"
16976 [(parallel [(set (match_dup 2) (const_int 0))
16977 (clobber (reg:CC FLAGS_REG))])
16978 (set (match_dup 0) (match_dup 1))]
16979 "operands[2] = gen_lowpart (SImode, operands[1]);")
16980
16981 (define_peephole2
16982 [(match_scratch:SWI124 2 "<r>")
16983 (set (match_operand:SWI124 0 "memory_operand")
16984 (match_operand:SWI124 1 "immediate_operand"))]
16985 "optimize_insn_for_speed_p ()
16986 && ((<MODE>mode == HImode
16987 && TARGET_LCP_STALL)
16988 || (TARGET_SPLIT_LONG_MOVES
16989 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16990 [(set (match_dup 2) (match_dup 1))
16991 (set (match_dup 0) (match_dup 2))])
16992
16993 ;; Don't compare memory with zero, load and use a test instead.
16994 (define_peephole2
16995 [(set (match_operand 0 "flags_reg_operand")
16996 (match_operator 1 "compare_operator"
16997 [(match_operand:SI 2 "memory_operand")
16998 (const_int 0)]))
16999 (match_scratch:SI 3 "r")]
17000 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17001 [(set (match_dup 3) (match_dup 2))
17002 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17003
17004 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17005 ;; Don't split NOTs with a displacement operand, because resulting XOR
17006 ;; will not be pairable anyway.
17007 ;;
17008 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17009 ;; represented using a modRM byte. The XOR replacement is long decoded,
17010 ;; so this split helps here as well.
17011 ;;
17012 ;; Note: Can't do this as a regular split because we can't get proper
17013 ;; lifetime information then.
17014
17015 (define_peephole2
17016 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17017 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17018 "optimize_insn_for_speed_p ()
17019 && ((TARGET_NOT_UNPAIRABLE
17020 && (!MEM_P (operands[0])
17021 || !memory_displacement_operand (operands[0], <MODE>mode)))
17022 || (TARGET_NOT_VECTORMODE
17023 && long_memory_operand (operands[0], <MODE>mode)))
17024 && peep2_regno_dead_p (0, FLAGS_REG)"
17025 [(parallel [(set (match_dup 0)
17026 (xor:SWI124 (match_dup 1) (const_int -1)))
17027 (clobber (reg:CC FLAGS_REG))])])
17028
17029 ;; Non pairable "test imm, reg" instructions can be translated to
17030 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17031 ;; byte opcode instead of two, have a short form for byte operands),
17032 ;; so do it for other CPUs as well. Given that the value was dead,
17033 ;; this should not create any new dependencies. Pass on the sub-word
17034 ;; versions if we're concerned about partial register stalls.
17035
17036 (define_peephole2
17037 [(set (match_operand 0 "flags_reg_operand")
17038 (match_operator 1 "compare_operator"
17039 [(and:SI (match_operand:SI 2 "register_operand")
17040 (match_operand:SI 3 "immediate_operand"))
17041 (const_int 0)]))]
17042 "ix86_match_ccmode (insn, CCNOmode)
17043 && (true_regnum (operands[2]) != AX_REG
17044 || satisfies_constraint_K (operands[3]))
17045 && peep2_reg_dead_p (1, operands[2])"
17046 [(parallel
17047 [(set (match_dup 0)
17048 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17049 (const_int 0)]))
17050 (set (match_dup 2)
17051 (and:SI (match_dup 2) (match_dup 3)))])])
17052
17053 ;; We don't need to handle HImode case, because it will be promoted to SImode
17054 ;; on ! TARGET_PARTIAL_REG_STALL
17055
17056 (define_peephole2
17057 [(set (match_operand 0 "flags_reg_operand")
17058 (match_operator 1 "compare_operator"
17059 [(and:QI (match_operand:QI 2 "register_operand")
17060 (match_operand:QI 3 "immediate_operand"))
17061 (const_int 0)]))]
17062 "! TARGET_PARTIAL_REG_STALL
17063 && ix86_match_ccmode (insn, CCNOmode)
17064 && true_regnum (operands[2]) != AX_REG
17065 && peep2_reg_dead_p (1, operands[2])"
17066 [(parallel
17067 [(set (match_dup 0)
17068 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17069 (const_int 0)]))
17070 (set (match_dup 2)
17071 (and:QI (match_dup 2) (match_dup 3)))])])
17072
17073 (define_peephole2
17074 [(set (match_operand 0 "flags_reg_operand")
17075 (match_operator 1 "compare_operator"
17076 [(and:SI
17077 (zero_extract:SI
17078 (match_operand 2 "ext_register_operand")
17079 (const_int 8)
17080 (const_int 8))
17081 (match_operand 3 "const_int_operand"))
17082 (const_int 0)]))]
17083 "! TARGET_PARTIAL_REG_STALL
17084 && ix86_match_ccmode (insn, CCNOmode)
17085 && true_regnum (operands[2]) != AX_REG
17086 && peep2_reg_dead_p (1, operands[2])"
17087 [(parallel [(set (match_dup 0)
17088 (match_op_dup 1
17089 [(and:SI
17090 (zero_extract:SI
17091 (match_dup 2)
17092 (const_int 8)
17093 (const_int 8))
17094 (match_dup 3))
17095 (const_int 0)]))
17096 (set (zero_extract:SI (match_dup 2)
17097 (const_int 8)
17098 (const_int 8))
17099 (and:SI
17100 (zero_extract:SI
17101 (match_dup 2)
17102 (const_int 8)
17103 (const_int 8))
17104 (match_dup 3)))])])
17105
17106 ;; Don't do logical operations with memory inputs.
17107 (define_peephole2
17108 [(match_scratch:SI 2 "r")
17109 (parallel [(set (match_operand:SI 0 "register_operand")
17110 (match_operator:SI 3 "arith_or_logical_operator"
17111 [(match_dup 0)
17112 (match_operand:SI 1 "memory_operand")]))
17113 (clobber (reg:CC FLAGS_REG))])]
17114 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17115 [(set (match_dup 2) (match_dup 1))
17116 (parallel [(set (match_dup 0)
17117 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17118 (clobber (reg:CC FLAGS_REG))])])
17119
17120 (define_peephole2
17121 [(match_scratch:SI 2 "r")
17122 (parallel [(set (match_operand:SI 0 "register_operand")
17123 (match_operator:SI 3 "arith_or_logical_operator"
17124 [(match_operand:SI 1 "memory_operand")
17125 (match_dup 0)]))
17126 (clobber (reg:CC FLAGS_REG))])]
17127 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17128 [(set (match_dup 2) (match_dup 1))
17129 (parallel [(set (match_dup 0)
17130 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17131 (clobber (reg:CC FLAGS_REG))])])
17132
17133 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17134 ;; refers to the destination of the load!
17135
17136 (define_peephole2
17137 [(set (match_operand:SI 0 "register_operand")
17138 (match_operand:SI 1 "register_operand"))
17139 (parallel [(set (match_dup 0)
17140 (match_operator:SI 3 "commutative_operator"
17141 [(match_dup 0)
17142 (match_operand:SI 2 "memory_operand")]))
17143 (clobber (reg:CC FLAGS_REG))])]
17144 "REGNO (operands[0]) != REGNO (operands[1])
17145 && GENERAL_REGNO_P (REGNO (operands[0]))
17146 && GENERAL_REGNO_P (REGNO (operands[1]))"
17147 [(set (match_dup 0) (match_dup 4))
17148 (parallel [(set (match_dup 0)
17149 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17150 (clobber (reg:CC FLAGS_REG))])]
17151 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17152
17153 (define_peephole2
17154 [(set (match_operand 0 "register_operand")
17155 (match_operand 1 "register_operand"))
17156 (set (match_dup 0)
17157 (match_operator 3 "commutative_operator"
17158 [(match_dup 0)
17159 (match_operand 2 "memory_operand")]))]
17160 "REGNO (operands[0]) != REGNO (operands[1])
17161 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17162 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17163 [(set (match_dup 0) (match_dup 2))
17164 (set (match_dup 0)
17165 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17166
17167 ; Don't do logical operations with memory outputs
17168 ;
17169 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17170 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17171 ; the same decoder scheduling characteristics as the original.
17172
17173 (define_peephole2
17174 [(match_scratch:SI 2 "r")
17175 (parallel [(set (match_operand:SI 0 "memory_operand")
17176 (match_operator:SI 3 "arith_or_logical_operator"
17177 [(match_dup 0)
17178 (match_operand:SI 1 "nonmemory_operand")]))
17179 (clobber (reg:CC FLAGS_REG))])]
17180 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17181 /* Do not split stack checking probes. */
17182 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17183 [(set (match_dup 2) (match_dup 0))
17184 (parallel [(set (match_dup 2)
17185 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17186 (clobber (reg:CC FLAGS_REG))])
17187 (set (match_dup 0) (match_dup 2))])
17188
17189 (define_peephole2
17190 [(match_scratch:SI 2 "r")
17191 (parallel [(set (match_operand:SI 0 "memory_operand")
17192 (match_operator:SI 3 "arith_or_logical_operator"
17193 [(match_operand:SI 1 "nonmemory_operand")
17194 (match_dup 0)]))
17195 (clobber (reg:CC FLAGS_REG))])]
17196 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17197 /* Do not split stack checking probes. */
17198 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17199 [(set (match_dup 2) (match_dup 0))
17200 (parallel [(set (match_dup 2)
17201 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17202 (clobber (reg:CC FLAGS_REG))])
17203 (set (match_dup 0) (match_dup 2))])
17204
17205 ;; Attempt to use arith or logical operations with memory outputs with
17206 ;; setting of flags.
17207 (define_peephole2
17208 [(set (match_operand:SWI 0 "register_operand")
17209 (match_operand:SWI 1 "memory_operand"))
17210 (parallel [(set (match_dup 0)
17211 (match_operator:SWI 3 "plusminuslogic_operator"
17212 [(match_dup 0)
17213 (match_operand:SWI 2 "<nonmemory_operand>")]))
17214 (clobber (reg:CC FLAGS_REG))])
17215 (set (match_dup 1) (match_dup 0))
17216 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17217 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17218 && peep2_reg_dead_p (4, operands[0])
17219 && !reg_overlap_mentioned_p (operands[0], operands[1])
17220 && (<MODE>mode != QImode
17221 || immediate_operand (operands[2], QImode)
17222 || q_regs_operand (operands[2], QImode))
17223 && ix86_match_ccmode (peep2_next_insn (3),
17224 (GET_CODE (operands[3]) == PLUS
17225 || GET_CODE (operands[3]) == MINUS)
17226 ? CCGOCmode : CCNOmode)"
17227 [(parallel [(set (match_dup 4) (match_dup 5))
17228 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17229 (match_dup 2)]))])]
17230 {
17231 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17232 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17233 copy_rtx (operands[1]),
17234 copy_rtx (operands[2]));
17235 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17236 operands[5], const0_rtx);
17237 })
17238
17239 (define_peephole2
17240 [(parallel [(set (match_operand:SWI 0 "register_operand")
17241 (match_operator:SWI 2 "plusminuslogic_operator"
17242 [(match_dup 0)
17243 (match_operand:SWI 1 "memory_operand")]))
17244 (clobber (reg:CC FLAGS_REG))])
17245 (set (match_dup 1) (match_dup 0))
17246 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17247 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17248 && GET_CODE (operands[2]) != MINUS
17249 && peep2_reg_dead_p (3, operands[0])
17250 && !reg_overlap_mentioned_p (operands[0], operands[1])
17251 && ix86_match_ccmode (peep2_next_insn (2),
17252 GET_CODE (operands[2]) == PLUS
17253 ? CCGOCmode : CCNOmode)"
17254 [(parallel [(set (match_dup 3) (match_dup 4))
17255 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17256 (match_dup 0)]))])]
17257 {
17258 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17259 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17260 copy_rtx (operands[1]),
17261 copy_rtx (operands[0]));
17262 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17263 operands[4], const0_rtx);
17264 })
17265
17266 (define_peephole2
17267 [(set (match_operand:SWI12 0 "register_operand")
17268 (match_operand:SWI12 1 "memory_operand"))
17269 (parallel [(set (match_operand:SI 4 "register_operand")
17270 (match_operator:SI 3 "plusminuslogic_operator"
17271 [(match_dup 4)
17272 (match_operand:SI 2 "nonmemory_operand")]))
17273 (clobber (reg:CC FLAGS_REG))])
17274 (set (match_dup 1) (match_dup 0))
17275 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17276 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17277 && REG_P (operands[0]) && REG_P (operands[4])
17278 && REGNO (operands[0]) == REGNO (operands[4])
17279 && peep2_reg_dead_p (4, operands[0])
17280 && (<MODE>mode != QImode
17281 || immediate_operand (operands[2], SImode)
17282 || q_regs_operand (operands[2], SImode))
17283 && !reg_overlap_mentioned_p (operands[0], operands[1])
17284 && ix86_match_ccmode (peep2_next_insn (3),
17285 (GET_CODE (operands[3]) == PLUS
17286 || GET_CODE (operands[3]) == MINUS)
17287 ? CCGOCmode : CCNOmode)"
17288 [(parallel [(set (match_dup 4) (match_dup 5))
17289 (set (match_dup 1) (match_dup 6))])]
17290 {
17291 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17292 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17293 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17294 copy_rtx (operands[1]), operands[2]);
17295 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17296 operands[5], const0_rtx);
17297 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17298 copy_rtx (operands[1]),
17299 copy_rtx (operands[2]));
17300 })
17301
17302 ;; Attempt to always use XOR for zeroing registers.
17303 (define_peephole2
17304 [(set (match_operand 0 "register_operand")
17305 (match_operand 1 "const0_operand"))]
17306 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17307 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17308 && GENERAL_REG_P (operands[0])
17309 && peep2_regno_dead_p (0, FLAGS_REG)"
17310 [(parallel [(set (match_dup 0) (const_int 0))
17311 (clobber (reg:CC FLAGS_REG))])]
17312 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17313
17314 (define_peephole2
17315 [(set (strict_low_part (match_operand 0 "register_operand"))
17316 (const_int 0))]
17317 "(GET_MODE (operands[0]) == QImode
17318 || GET_MODE (operands[0]) == HImode)
17319 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17320 && peep2_regno_dead_p (0, FLAGS_REG)"
17321 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17322 (clobber (reg:CC FLAGS_REG))])])
17323
17324 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17325 (define_peephole2
17326 [(set (match_operand:SWI248 0 "register_operand")
17327 (const_int -1))]
17328 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17329 && peep2_regno_dead_p (0, FLAGS_REG)"
17330 [(parallel [(set (match_dup 0) (const_int -1))
17331 (clobber (reg:CC FLAGS_REG))])]
17332 {
17333 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17334 operands[0] = gen_lowpart (SImode, operands[0]);
17335 })
17336
17337 ;; Attempt to convert simple lea to add/shift.
17338 ;; These can be created by move expanders.
17339 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17340 ;; relevant lea instructions were already split.
17341
17342 (define_peephole2
17343 [(set (match_operand:SWI48 0 "register_operand")
17344 (plus:SWI48 (match_dup 0)
17345 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17346 "!TARGET_OPT_AGU
17347 && peep2_regno_dead_p (0, FLAGS_REG)"
17348 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17349 (clobber (reg:CC FLAGS_REG))])])
17350
17351 (define_peephole2
17352 [(set (match_operand:SWI48 0 "register_operand")
17353 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17354 (match_dup 0)))]
17355 "!TARGET_OPT_AGU
17356 && peep2_regno_dead_p (0, FLAGS_REG)"
17357 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17358 (clobber (reg:CC FLAGS_REG))])])
17359
17360 (define_peephole2
17361 [(set (match_operand:DI 0 "register_operand")
17362 (zero_extend:DI
17363 (plus:SI (match_operand:SI 1 "register_operand")
17364 (match_operand:SI 2 "nonmemory_operand"))))]
17365 "TARGET_64BIT && !TARGET_OPT_AGU
17366 && REGNO (operands[0]) == REGNO (operands[1])
17367 && peep2_regno_dead_p (0, FLAGS_REG)"
17368 [(parallel [(set (match_dup 0)
17369 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17370 (clobber (reg:CC FLAGS_REG))])])
17371
17372 (define_peephole2
17373 [(set (match_operand:DI 0 "register_operand")
17374 (zero_extend:DI
17375 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17376 (match_operand:SI 2 "register_operand"))))]
17377 "TARGET_64BIT && !TARGET_OPT_AGU
17378 && REGNO (operands[0]) == REGNO (operands[2])
17379 && peep2_regno_dead_p (0, FLAGS_REG)"
17380 [(parallel [(set (match_dup 0)
17381 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17382 (clobber (reg:CC FLAGS_REG))])])
17383
17384 (define_peephole2
17385 [(set (match_operand:SWI48 0 "register_operand")
17386 (mult:SWI48 (match_dup 0)
17387 (match_operand:SWI48 1 "const_int_operand")))]
17388 "exact_log2 (INTVAL (operands[1])) >= 0
17389 && peep2_regno_dead_p (0, FLAGS_REG)"
17390 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17391 (clobber (reg:CC FLAGS_REG))])]
17392 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17393
17394 (define_peephole2
17395 [(set (match_operand:DI 0 "register_operand")
17396 (zero_extend:DI
17397 (mult:SI (match_operand:SI 1 "register_operand")
17398 (match_operand:SI 2 "const_int_operand"))))]
17399 "TARGET_64BIT
17400 && exact_log2 (INTVAL (operands[2])) >= 0
17401 && REGNO (operands[0]) == REGNO (operands[1])
17402 && peep2_regno_dead_p (0, FLAGS_REG)"
17403 [(parallel [(set (match_dup 0)
17404 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
17405 (clobber (reg:CC FLAGS_REG))])]
17406 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17407
17408 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17409 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17410 ;; On many CPUs it is also faster, since special hardware to avoid esp
17411 ;; dependencies is present.
17412
17413 ;; While some of these conversions may be done using splitters, we use
17414 ;; peepholes in order to allow combine_stack_adjustments pass to see
17415 ;; nonobfuscated RTL.
17416
17417 ;; Convert prologue esp subtractions to push.
17418 ;; We need register to push. In order to keep verify_flow_info happy we have
17419 ;; two choices
17420 ;; - use scratch and clobber it in order to avoid dependencies
17421 ;; - use already live register
17422 ;; We can't use the second way right now, since there is no reliable way how to
17423 ;; verify that given register is live. First choice will also most likely in
17424 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17425 ;; call clobbered registers are dead. We may want to use base pointer as an
17426 ;; alternative when no register is available later.
17427
17428 (define_peephole2
17429 [(match_scratch:W 1 "r")
17430 (parallel [(set (reg:P SP_REG)
17431 (plus:P (reg:P SP_REG)
17432 (match_operand:P 0 "const_int_operand")))
17433 (clobber (reg:CC FLAGS_REG))
17434 (clobber (mem:BLK (scratch)))])]
17435 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17436 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17437 [(clobber (match_dup 1))
17438 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17439 (clobber (mem:BLK (scratch)))])])
17440
17441 (define_peephole2
17442 [(match_scratch:W 1 "r")
17443 (parallel [(set (reg:P SP_REG)
17444 (plus:P (reg:P SP_REG)
17445 (match_operand:P 0 "const_int_operand")))
17446 (clobber (reg:CC FLAGS_REG))
17447 (clobber (mem:BLK (scratch)))])]
17448 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17449 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17450 [(clobber (match_dup 1))
17451 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17452 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17453 (clobber (mem:BLK (scratch)))])])
17454
17455 ;; Convert esp subtractions to push.
17456 (define_peephole2
17457 [(match_scratch:W 1 "r")
17458 (parallel [(set (reg:P SP_REG)
17459 (plus:P (reg:P SP_REG)
17460 (match_operand:P 0 "const_int_operand")))
17461 (clobber (reg:CC FLAGS_REG))])]
17462 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17463 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17464 [(clobber (match_dup 1))
17465 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17466
17467 (define_peephole2
17468 [(match_scratch:W 1 "r")
17469 (parallel [(set (reg:P SP_REG)
17470 (plus:P (reg:P SP_REG)
17471 (match_operand:P 0 "const_int_operand")))
17472 (clobber (reg:CC FLAGS_REG))])]
17473 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17474 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17475 [(clobber (match_dup 1))
17476 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17477 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17478
17479 ;; Convert epilogue deallocator to pop.
17480 (define_peephole2
17481 [(match_scratch:W 1 "r")
17482 (parallel [(set (reg:P SP_REG)
17483 (plus:P (reg:P SP_REG)
17484 (match_operand:P 0 "const_int_operand")))
17485 (clobber (reg:CC FLAGS_REG))
17486 (clobber (mem:BLK (scratch)))])]
17487 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17488 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17489 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17490 (clobber (mem:BLK (scratch)))])])
17491
17492 ;; Two pops case is tricky, since pop causes dependency
17493 ;; on destination register. We use two registers if available.
17494 (define_peephole2
17495 [(match_scratch:W 1 "r")
17496 (match_scratch:W 2 "r")
17497 (parallel [(set (reg:P SP_REG)
17498 (plus:P (reg:P SP_REG)
17499 (match_operand:P 0 "const_int_operand")))
17500 (clobber (reg:CC FLAGS_REG))
17501 (clobber (mem:BLK (scratch)))])]
17502 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17503 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17504 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17505 (clobber (mem:BLK (scratch)))])
17506 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17507
17508 (define_peephole2
17509 [(match_scratch:W 1 "r")
17510 (parallel [(set (reg:P SP_REG)
17511 (plus:P (reg:P SP_REG)
17512 (match_operand:P 0 "const_int_operand")))
17513 (clobber (reg:CC FLAGS_REG))
17514 (clobber (mem:BLK (scratch)))])]
17515 "optimize_insn_for_size_p ()
17516 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17517 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17518 (clobber (mem:BLK (scratch)))])
17519 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17520
17521 ;; Convert esp additions to pop.
17522 (define_peephole2
17523 [(match_scratch:W 1 "r")
17524 (parallel [(set (reg:P SP_REG)
17525 (plus:P (reg:P SP_REG)
17526 (match_operand:P 0 "const_int_operand")))
17527 (clobber (reg:CC FLAGS_REG))])]
17528 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17529 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17530
17531 ;; Two pops case is tricky, since pop causes dependency
17532 ;; on destination register. We use two registers if available.
17533 (define_peephole2
17534 [(match_scratch:W 1 "r")
17535 (match_scratch:W 2 "r")
17536 (parallel [(set (reg:P SP_REG)
17537 (plus:P (reg:P SP_REG)
17538 (match_operand:P 0 "const_int_operand")))
17539 (clobber (reg:CC FLAGS_REG))])]
17540 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17541 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17542 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17543
17544 (define_peephole2
17545 [(match_scratch:W 1 "r")
17546 (parallel [(set (reg:P SP_REG)
17547 (plus:P (reg:P SP_REG)
17548 (match_operand:P 0 "const_int_operand")))
17549 (clobber (reg:CC FLAGS_REG))])]
17550 "optimize_insn_for_size_p ()
17551 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17552 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17553 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17554 \f
17555 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17556 ;; required and register dies. Similarly for 128 to -128.
17557 (define_peephole2
17558 [(set (match_operand 0 "flags_reg_operand")
17559 (match_operator 1 "compare_operator"
17560 [(match_operand 2 "register_operand")
17561 (match_operand 3 "const_int_operand")]))]
17562 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17563 && incdec_operand (operands[3], GET_MODE (operands[3])))
17564 || (!TARGET_FUSE_CMP_AND_BRANCH
17565 && INTVAL (operands[3]) == 128))
17566 && ix86_match_ccmode (insn, CCGCmode)
17567 && peep2_reg_dead_p (1, operands[2])"
17568 [(parallel [(set (match_dup 0)
17569 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17570 (clobber (match_dup 2))])])
17571 \f
17572 ;; Convert imul by three, five and nine into lea
17573 (define_peephole2
17574 [(parallel
17575 [(set (match_operand:SWI48 0 "register_operand")
17576 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17577 (match_operand:SWI48 2 "const359_operand")))
17578 (clobber (reg:CC FLAGS_REG))])]
17579 "!TARGET_PARTIAL_REG_STALL
17580 || <MODE>mode == SImode
17581 || optimize_function_for_size_p (cfun)"
17582 [(set (match_dup 0)
17583 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17584 (match_dup 1)))]
17585 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17586
17587 (define_peephole2
17588 [(parallel
17589 [(set (match_operand:SWI48 0 "register_operand")
17590 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17591 (match_operand:SWI48 2 "const359_operand")))
17592 (clobber (reg:CC FLAGS_REG))])]
17593 "optimize_insn_for_speed_p ()
17594 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17595 [(set (match_dup 0) (match_dup 1))
17596 (set (match_dup 0)
17597 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17598 (match_dup 0)))]
17599 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17600
17601 ;; imul $32bit_imm, mem, reg is vector decoded, while
17602 ;; imul $32bit_imm, reg, reg is direct decoded.
17603 (define_peephole2
17604 [(match_scratch:SWI48 3 "r")
17605 (parallel [(set (match_operand:SWI48 0 "register_operand")
17606 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17607 (match_operand:SWI48 2 "immediate_operand")))
17608 (clobber (reg:CC FLAGS_REG))])]
17609 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17610 && !satisfies_constraint_K (operands[2])"
17611 [(set (match_dup 3) (match_dup 1))
17612 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17613 (clobber (reg:CC FLAGS_REG))])])
17614
17615 (define_peephole2
17616 [(match_scratch:SI 3 "r")
17617 (parallel [(set (match_operand:DI 0 "register_operand")
17618 (zero_extend:DI
17619 (mult:SI (match_operand:SI 1 "memory_operand")
17620 (match_operand:SI 2 "immediate_operand"))))
17621 (clobber (reg:CC FLAGS_REG))])]
17622 "TARGET_64BIT
17623 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17624 && !satisfies_constraint_K (operands[2])"
17625 [(set (match_dup 3) (match_dup 1))
17626 (parallel [(set (match_dup 0)
17627 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17628 (clobber (reg:CC FLAGS_REG))])])
17629
17630 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17631 ;; Convert it into imul reg, reg
17632 ;; It would be better to force assembler to encode instruction using long
17633 ;; immediate, but there is apparently no way to do so.
17634 (define_peephole2
17635 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17636 (mult:SWI248
17637 (match_operand:SWI248 1 "nonimmediate_operand")
17638 (match_operand:SWI248 2 "const_int_operand")))
17639 (clobber (reg:CC FLAGS_REG))])
17640 (match_scratch:SWI248 3 "r")]
17641 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17642 && satisfies_constraint_K (operands[2])"
17643 [(set (match_dup 3) (match_dup 2))
17644 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17645 (clobber (reg:CC FLAGS_REG))])]
17646 {
17647 if (!rtx_equal_p (operands[0], operands[1]))
17648 emit_move_insn (operands[0], operands[1]);
17649 })
17650
17651 ;; After splitting up read-modify operations, array accesses with memory
17652 ;; operands might end up in form:
17653 ;; sall $2, %eax
17654 ;; movl 4(%esp), %edx
17655 ;; addl %edx, %eax
17656 ;; instead of pre-splitting:
17657 ;; sall $2, %eax
17658 ;; addl 4(%esp), %eax
17659 ;; Turn it into:
17660 ;; movl 4(%esp), %edx
17661 ;; leal (%edx,%eax,4), %eax
17662
17663 (define_peephole2
17664 [(match_scratch:W 5 "r")
17665 (parallel [(set (match_operand 0 "register_operand")
17666 (ashift (match_operand 1 "register_operand")
17667 (match_operand 2 "const_int_operand")))
17668 (clobber (reg:CC FLAGS_REG))])
17669 (parallel [(set (match_operand 3 "register_operand")
17670 (plus (match_dup 0)
17671 (match_operand 4 "x86_64_general_operand")))
17672 (clobber (reg:CC FLAGS_REG))])]
17673 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17674 /* Validate MODE for lea. */
17675 && ((!TARGET_PARTIAL_REG_STALL
17676 && (GET_MODE (operands[0]) == QImode
17677 || GET_MODE (operands[0]) == HImode))
17678 || GET_MODE (operands[0]) == SImode
17679 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17680 && (rtx_equal_p (operands[0], operands[3])
17681 || peep2_reg_dead_p (2, operands[0]))
17682 /* We reorder load and the shift. */
17683 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17684 [(set (match_dup 5) (match_dup 4))
17685 (set (match_dup 0) (match_dup 1))]
17686 {
17687 enum machine_mode op1mode = GET_MODE (operands[1]);
17688 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17689 int scale = 1 << INTVAL (operands[2]);
17690 rtx index = gen_lowpart (word_mode, operands[1]);
17691 rtx base = gen_lowpart (word_mode, operands[5]);
17692 rtx dest = gen_lowpart (mode, operands[3]);
17693
17694 operands[1] = gen_rtx_PLUS (word_mode, base,
17695 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17696 operands[5] = base;
17697 if (mode != word_mode)
17698 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17699 if (op1mode != word_mode)
17700 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17701 operands[0] = dest;
17702 })
17703 \f
17704 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17705 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17706 ;; caught for use by garbage collectors and the like. Using an insn that
17707 ;; maps to SIGILL makes it more likely the program will rightfully die.
17708 ;; Keeping with tradition, "6" is in honor of #UD.
17709 (define_insn "trap"
17710 [(trap_if (const_int 1) (const_int 6))]
17711 ""
17712 { return ASM_SHORT "0x0b0f"; }
17713 [(set_attr "length" "2")])
17714
17715 (define_expand "prefetch"
17716 [(prefetch (match_operand 0 "address_operand")
17717 (match_operand:SI 1 "const_int_operand")
17718 (match_operand:SI 2 "const_int_operand"))]
17719 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17720 {
17721 int rw = INTVAL (operands[1]);
17722 int locality = INTVAL (operands[2]);
17723
17724 gcc_assert (rw == 0 || rw == 1);
17725 gcc_assert (IN_RANGE (locality, 0, 3));
17726
17727 if (TARGET_PRFCHW && rw)
17728 operands[2] = GEN_INT (3);
17729 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17730 supported by SSE counterpart or the SSE prefetch is not available
17731 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17732 of locality. */
17733 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17734 operands[2] = GEN_INT (3);
17735 else
17736 operands[1] = const0_rtx;
17737 })
17738
17739 (define_insn "*prefetch_sse"
17740 [(prefetch (match_operand 0 "address_operand" "p")
17741 (const_int 0)
17742 (match_operand:SI 1 "const_int_operand"))]
17743 "TARGET_PREFETCH_SSE"
17744 {
17745 static const char * const patterns[4] = {
17746 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17747 };
17748
17749 int locality = INTVAL (operands[1]);
17750 gcc_assert (IN_RANGE (locality, 0, 3));
17751
17752 return patterns[locality];
17753 }
17754 [(set_attr "type" "sse")
17755 (set_attr "atom_sse_attr" "prefetch")
17756 (set (attr "length_address")
17757 (symbol_ref "memory_address_length (operands[0], false)"))
17758 (set_attr "memory" "none")])
17759
17760 (define_insn "*prefetch_3dnow"
17761 [(prefetch (match_operand 0 "address_operand" "p")
17762 (match_operand:SI 1 "const_int_operand" "n")
17763 (const_int 3))]
17764 "TARGET_3DNOW || TARGET_PRFCHW"
17765 {
17766 if (INTVAL (operands[1]) == 0)
17767 return "prefetch\t%a0";
17768 else
17769 return "prefetchw\t%a0";
17770 }
17771 [(set_attr "type" "mmx")
17772 (set (attr "length_address")
17773 (symbol_ref "memory_address_length (operands[0], false)"))
17774 (set_attr "memory" "none")])
17775
17776 (define_expand "stack_protect_set"
17777 [(match_operand 0 "memory_operand")
17778 (match_operand 1 "memory_operand")]
17779 "!TARGET_HAS_BIONIC"
17780 {
17781 rtx (*insn)(rtx, rtx);
17782
17783 #ifdef TARGET_THREAD_SSP_OFFSET
17784 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17785 insn = (TARGET_LP64
17786 ? gen_stack_tls_protect_set_di
17787 : gen_stack_tls_protect_set_si);
17788 #else
17789 insn = (TARGET_LP64
17790 ? gen_stack_protect_set_di
17791 : gen_stack_protect_set_si);
17792 #endif
17793
17794 emit_insn (insn (operands[0], operands[1]));
17795 DONE;
17796 })
17797
17798 (define_insn "stack_protect_set_<mode>"
17799 [(set (match_operand:PTR 0 "memory_operand" "=m")
17800 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17801 UNSPEC_SP_SET))
17802 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17803 (clobber (reg:CC FLAGS_REG))]
17804 "!TARGET_HAS_BIONIC"
17805 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17806 [(set_attr "type" "multi")])
17807
17808 (define_insn "stack_tls_protect_set_<mode>"
17809 [(set (match_operand:PTR 0 "memory_operand" "=m")
17810 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17811 UNSPEC_SP_TLS_SET))
17812 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17813 (clobber (reg:CC FLAGS_REG))]
17814 ""
17815 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17816 [(set_attr "type" "multi")])
17817
17818 (define_expand "stack_protect_test"
17819 [(match_operand 0 "memory_operand")
17820 (match_operand 1 "memory_operand")
17821 (match_operand 2)]
17822 "!TARGET_HAS_BIONIC"
17823 {
17824 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17825
17826 rtx (*insn)(rtx, rtx, rtx);
17827
17828 #ifdef TARGET_THREAD_SSP_OFFSET
17829 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17830 insn = (TARGET_LP64
17831 ? gen_stack_tls_protect_test_di
17832 : gen_stack_tls_protect_test_si);
17833 #else
17834 insn = (TARGET_LP64
17835 ? gen_stack_protect_test_di
17836 : gen_stack_protect_test_si);
17837 #endif
17838
17839 emit_insn (insn (flags, operands[0], operands[1]));
17840
17841 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17842 flags, const0_rtx, operands[2]));
17843 DONE;
17844 })
17845
17846 (define_insn "stack_protect_test_<mode>"
17847 [(set (match_operand:CCZ 0 "flags_reg_operand")
17848 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17849 (match_operand:PTR 2 "memory_operand" "m")]
17850 UNSPEC_SP_TEST))
17851 (clobber (match_scratch:PTR 3 "=&r"))]
17852 "!TARGET_HAS_BIONIC"
17853 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17854 [(set_attr "type" "multi")])
17855
17856 (define_insn "stack_tls_protect_test_<mode>"
17857 [(set (match_operand:CCZ 0 "flags_reg_operand")
17858 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17859 (match_operand:PTR 2 "const_int_operand" "i")]
17860 UNSPEC_SP_TLS_TEST))
17861 (clobber (match_scratch:PTR 3 "=r"))]
17862 ""
17863 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17864 [(set_attr "type" "multi")])
17865
17866 (define_insn "sse4_2_crc32<mode>"
17867 [(set (match_operand:SI 0 "register_operand" "=r")
17868 (unspec:SI
17869 [(match_operand:SI 1 "register_operand" "0")
17870 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17871 UNSPEC_CRC32))]
17872 "TARGET_SSE4_2 || TARGET_CRC32"
17873 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17874 [(set_attr "type" "sselog1")
17875 (set_attr "prefix_rep" "1")
17876 (set_attr "prefix_extra" "1")
17877 (set (attr "prefix_data16")
17878 (if_then_else (match_operand:HI 2)
17879 (const_string "1")
17880 (const_string "*")))
17881 (set (attr "prefix_rex")
17882 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17883 (const_string "1")
17884 (const_string "*")))
17885 (set_attr "mode" "SI")])
17886
17887 (define_insn "sse4_2_crc32di"
17888 [(set (match_operand:DI 0 "register_operand" "=r")
17889 (unspec:DI
17890 [(match_operand:DI 1 "register_operand" "0")
17891 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17892 UNSPEC_CRC32))]
17893 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17894 "crc32{q}\t{%2, %0|%0, %2}"
17895 [(set_attr "type" "sselog1")
17896 (set_attr "prefix_rep" "1")
17897 (set_attr "prefix_extra" "1")
17898 (set_attr "mode" "DI")])
17899
17900 (define_insn "rdpmc"
17901 [(set (match_operand:DI 0 "register_operand" "=A")
17902 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17903 UNSPECV_RDPMC))]
17904 "!TARGET_64BIT"
17905 "rdpmc"
17906 [(set_attr "type" "other")
17907 (set_attr "length" "2")])
17908
17909 (define_insn "rdpmc_rex64"
17910 [(set (match_operand:DI 0 "register_operand" "=a")
17911 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17912 UNSPECV_RDPMC))
17913 (set (match_operand:DI 1 "register_operand" "=d")
17914 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17915 "TARGET_64BIT"
17916 "rdpmc"
17917 [(set_attr "type" "other")
17918 (set_attr "length" "2")])
17919
17920 (define_insn "rdtsc"
17921 [(set (match_operand:DI 0 "register_operand" "=A")
17922 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17923 "!TARGET_64BIT"
17924 "rdtsc"
17925 [(set_attr "type" "other")
17926 (set_attr "length" "2")])
17927
17928 (define_insn "rdtsc_rex64"
17929 [(set (match_operand:DI 0 "register_operand" "=a")
17930 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17931 (set (match_operand:DI 1 "register_operand" "=d")
17932 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17933 "TARGET_64BIT"
17934 "rdtsc"
17935 [(set_attr "type" "other")
17936 (set_attr "length" "2")])
17937
17938 (define_insn "rdtscp"
17939 [(set (match_operand:DI 0 "register_operand" "=A")
17940 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17941 (set (match_operand:SI 1 "register_operand" "=c")
17942 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17943 "!TARGET_64BIT"
17944 "rdtscp"
17945 [(set_attr "type" "other")
17946 (set_attr "length" "3")])
17947
17948 (define_insn "rdtscp_rex64"
17949 [(set (match_operand:DI 0 "register_operand" "=a")
17950 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17951 (set (match_operand:DI 1 "register_operand" "=d")
17952 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17953 (set (match_operand:SI 2 "register_operand" "=c")
17954 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17955 "TARGET_64BIT"
17956 "rdtscp"
17957 [(set_attr "type" "other")
17958 (set_attr "length" "3")])
17959
17960 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17961 ;;
17962 ;; FXSR, XSAVE and XSAVEOPT instructions
17963 ;;
17964 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17965
17966 (define_insn "fxsave"
17967 [(set (match_operand:BLK 0 "memory_operand" "=m")
17968 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17969 "TARGET_FXSR"
17970 "fxsave\t%0"
17971 [(set_attr "type" "other")
17972 (set_attr "memory" "store")
17973 (set (attr "length")
17974 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17975
17976 (define_insn "fxsave64"
17977 [(set (match_operand:BLK 0 "memory_operand" "=m")
17978 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17979 "TARGET_64BIT && TARGET_FXSR"
17980 "fxsave64\t%0"
17981 [(set_attr "type" "other")
17982 (set_attr "memory" "store")
17983 (set (attr "length")
17984 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17985
17986 (define_insn "fxrstor"
17987 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17988 UNSPECV_FXRSTOR)]
17989 "TARGET_FXSR"
17990 "fxrstor\t%0"
17991 [(set_attr "type" "other")
17992 (set_attr "memory" "load")
17993 (set (attr "length")
17994 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17995
17996 (define_insn "fxrstor64"
17997 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17998 UNSPECV_FXRSTOR64)]
17999 "TARGET_64BIT && TARGET_FXSR"
18000 "fxrstor64\t%0"
18001 [(set_attr "type" "other")
18002 (set_attr "memory" "load")
18003 (set (attr "length")
18004 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18005
18006 (define_int_iterator ANY_XSAVE
18007 [UNSPECV_XSAVE
18008 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
18009
18010 (define_int_iterator ANY_XSAVE64
18011 [UNSPECV_XSAVE64
18012 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
18013
18014 (define_int_attr xsave
18015 [(UNSPECV_XSAVE "xsave")
18016 (UNSPECV_XSAVE64 "xsave64")
18017 (UNSPECV_XSAVEOPT "xsaveopt")
18018 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
18019
18020 (define_insn "<xsave>"
18021 [(set (match_operand:BLK 0 "memory_operand" "=m")
18022 (unspec_volatile:BLK
18023 [(match_operand:DI 1 "register_operand" "A")]
18024 ANY_XSAVE))]
18025 "!TARGET_64BIT && TARGET_XSAVE"
18026 "<xsave>\t%0"
18027 [(set_attr "type" "other")
18028 (set_attr "memory" "store")
18029 (set (attr "length")
18030 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18031
18032 (define_insn "<xsave>_rex64"
18033 [(set (match_operand:BLK 0 "memory_operand" "=m")
18034 (unspec_volatile:BLK
18035 [(match_operand:SI 1 "register_operand" "a")
18036 (match_operand:SI 2 "register_operand" "d")]
18037 ANY_XSAVE))]
18038 "TARGET_64BIT && TARGET_XSAVE"
18039 "<xsave>\t%0"
18040 [(set_attr "type" "other")
18041 (set_attr "memory" "store")
18042 (set (attr "length")
18043 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18044
18045 (define_insn "<xsave>"
18046 [(set (match_operand:BLK 0 "memory_operand" "=m")
18047 (unspec_volatile:BLK
18048 [(match_operand:SI 1 "register_operand" "a")
18049 (match_operand:SI 2 "register_operand" "d")]
18050 ANY_XSAVE64))]
18051 "TARGET_64BIT && TARGET_XSAVE"
18052 "<xsave>\t%0"
18053 [(set_attr "type" "other")
18054 (set_attr "memory" "store")
18055 (set (attr "length")
18056 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18057
18058 (define_insn "xrstor"
18059 [(unspec_volatile:BLK
18060 [(match_operand:BLK 0 "memory_operand" "m")
18061 (match_operand:DI 1 "register_operand" "A")]
18062 UNSPECV_XRSTOR)]
18063 "!TARGET_64BIT && TARGET_XSAVE"
18064 "xrstor\t%0"
18065 [(set_attr "type" "other")
18066 (set_attr "memory" "load")
18067 (set (attr "length")
18068 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18069
18070 (define_insn "xrstor_rex64"
18071 [(unspec_volatile:BLK
18072 [(match_operand:BLK 0 "memory_operand" "m")
18073 (match_operand:SI 1 "register_operand" "a")
18074 (match_operand:SI 2 "register_operand" "d")]
18075 UNSPECV_XRSTOR)]
18076 "TARGET_64BIT && TARGET_XSAVE"
18077 "xrstor\t%0"
18078 [(set_attr "type" "other")
18079 (set_attr "memory" "load")
18080 (set (attr "length")
18081 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18082
18083 (define_insn "xrstor64"
18084 [(unspec_volatile:BLK
18085 [(match_operand:BLK 0 "memory_operand" "m")
18086 (match_operand:SI 1 "register_operand" "a")
18087 (match_operand:SI 2 "register_operand" "d")]
18088 UNSPECV_XRSTOR64)]
18089 "TARGET_64BIT && TARGET_XSAVE"
18090 "xrstor64\t%0"
18091 [(set_attr "type" "other")
18092 (set_attr "memory" "load")
18093 (set (attr "length")
18094 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18095
18096 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18097 ;;
18098 ;; LWP instructions
18099 ;;
18100 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18101
18102 (define_expand "lwp_llwpcb"
18103 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18104 UNSPECV_LLWP_INTRINSIC)]
18105 "TARGET_LWP")
18106
18107 (define_insn "*lwp_llwpcb<mode>1"
18108 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18109 UNSPECV_LLWP_INTRINSIC)]
18110 "TARGET_LWP"
18111 "llwpcb\t%0"
18112 [(set_attr "type" "lwp")
18113 (set_attr "mode" "<MODE>")
18114 (set_attr "length" "5")])
18115
18116 (define_expand "lwp_slwpcb"
18117 [(set (match_operand 0 "register_operand" "=r")
18118 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18119 "TARGET_LWP"
18120 {
18121 rtx (*insn)(rtx);
18122
18123 insn = (Pmode == DImode
18124 ? gen_lwp_slwpcbdi
18125 : gen_lwp_slwpcbsi);
18126
18127 emit_insn (insn (operands[0]));
18128 DONE;
18129 })
18130
18131 (define_insn "lwp_slwpcb<mode>"
18132 [(set (match_operand:P 0 "register_operand" "=r")
18133 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18134 "TARGET_LWP"
18135 "slwpcb\t%0"
18136 [(set_attr "type" "lwp")
18137 (set_attr "mode" "<MODE>")
18138 (set_attr "length" "5")])
18139
18140 (define_expand "lwp_lwpval<mode>3"
18141 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18142 (match_operand:SI 2 "nonimmediate_operand" "rm")
18143 (match_operand:SI 3 "const_int_operand" "i")]
18144 UNSPECV_LWPVAL_INTRINSIC)]
18145 "TARGET_LWP"
18146 ;; Avoid unused variable warning.
18147 "(void) operands[0];")
18148
18149 (define_insn "*lwp_lwpval<mode>3_1"
18150 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18151 (match_operand:SI 1 "nonimmediate_operand" "rm")
18152 (match_operand:SI 2 "const_int_operand" "i")]
18153 UNSPECV_LWPVAL_INTRINSIC)]
18154 "TARGET_LWP"
18155 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18156 [(set_attr "type" "lwp")
18157 (set_attr "mode" "<MODE>")
18158 (set (attr "length")
18159 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18160
18161 (define_expand "lwp_lwpins<mode>3"
18162 [(set (reg:CCC FLAGS_REG)
18163 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18164 (match_operand:SI 2 "nonimmediate_operand" "rm")
18165 (match_operand:SI 3 "const_int_operand" "i")]
18166 UNSPECV_LWPINS_INTRINSIC))
18167 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18168 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18169 "TARGET_LWP")
18170
18171 (define_insn "*lwp_lwpins<mode>3_1"
18172 [(set (reg:CCC FLAGS_REG)
18173 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18174 (match_operand:SI 1 "nonimmediate_operand" "rm")
18175 (match_operand:SI 2 "const_int_operand" "i")]
18176 UNSPECV_LWPINS_INTRINSIC))]
18177 "TARGET_LWP"
18178 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18179 [(set_attr "type" "lwp")
18180 (set_attr "mode" "<MODE>")
18181 (set (attr "length")
18182 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18183
18184 (define_int_iterator RDFSGSBASE
18185 [UNSPECV_RDFSBASE
18186 UNSPECV_RDGSBASE])
18187
18188 (define_int_iterator WRFSGSBASE
18189 [UNSPECV_WRFSBASE
18190 UNSPECV_WRGSBASE])
18191
18192 (define_int_attr fsgs
18193 [(UNSPECV_RDFSBASE "fs")
18194 (UNSPECV_RDGSBASE "gs")
18195 (UNSPECV_WRFSBASE "fs")
18196 (UNSPECV_WRGSBASE "gs")])
18197
18198 (define_insn "rd<fsgs>base<mode>"
18199 [(set (match_operand:SWI48 0 "register_operand" "=r")
18200 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18201 "TARGET_64BIT && TARGET_FSGSBASE"
18202 "rd<fsgs>base\t%0"
18203 [(set_attr "type" "other")
18204 (set_attr "prefix_extra" "2")])
18205
18206 (define_insn "wr<fsgs>base<mode>"
18207 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18208 WRFSGSBASE)]
18209 "TARGET_64BIT && TARGET_FSGSBASE"
18210 "wr<fsgs>base\t%0"
18211 [(set_attr "type" "other")
18212 (set_attr "prefix_extra" "2")])
18213
18214 (define_insn "rdrand<mode>_1"
18215 [(set (match_operand:SWI248 0 "register_operand" "=r")
18216 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18217 (set (reg:CCC FLAGS_REG)
18218 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18219 "TARGET_RDRND"
18220 "rdrand\t%0"
18221 [(set_attr "type" "other")
18222 (set_attr "prefix_extra" "1")])
18223
18224 (define_insn "rdseed<mode>_1"
18225 [(set (match_operand:SWI248 0 "register_operand" "=r")
18226 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18227 (set (reg:CCC FLAGS_REG)
18228 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18229 "TARGET_RDSEED"
18230 "rdseed\t%0"
18231 [(set_attr "type" "other")
18232 (set_attr "prefix_extra" "1")])
18233
18234 (define_expand "pause"
18235 [(set (match_dup 0)
18236 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18237 ""
18238 {
18239 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18240 MEM_VOLATILE_P (operands[0]) = 1;
18241 })
18242
18243 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18244 ;; They have the same encoding.
18245 (define_insn "*pause"
18246 [(set (match_operand:BLK 0)
18247 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18248 ""
18249 "rep%; nop"
18250 [(set_attr "length" "2")
18251 (set_attr "memory" "unknown")])
18252
18253 (define_expand "xbegin"
18254 [(set (match_operand:SI 0 "register_operand")
18255 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18256 "TARGET_RTM"
18257 {
18258 rtx label = gen_label_rtx ();
18259
18260 operands[1] = force_reg (SImode, constm1_rtx);
18261
18262 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18263
18264 emit_label (label);
18265 LABEL_NUSES (label) = 1;
18266
18267 emit_move_insn (operands[0], operands[1]);
18268
18269 DONE;
18270 })
18271
18272 (define_insn "xbegin_1"
18273 [(set (pc)
18274 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18275 (const_int 0))
18276 (label_ref (match_operand 1))
18277 (pc)))
18278 (set (match_operand:SI 0 "register_operand" "+a")
18279 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18280 "TARGET_RTM"
18281 "xbegin\t%l1"
18282 [(set_attr "type" "other")
18283 (set_attr "length" "6")])
18284
18285 (define_insn "xend"
18286 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18287 "TARGET_RTM"
18288 "xend"
18289 [(set_attr "type" "other")
18290 (set_attr "length" "3")])
18291
18292 (define_insn "xabort"
18293 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18294 UNSPECV_XABORT)]
18295 "TARGET_RTM"
18296 "xabort\t%0"
18297 [(set_attr "type" "other")
18298 (set_attr "length" "3")])
18299
18300 (define_expand "xtest"
18301 [(set (match_operand:QI 0 "register_operand")
18302 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18303 "TARGET_RTM"
18304 {
18305 emit_insn (gen_xtest_1 ());
18306
18307 ix86_expand_setcc (operands[0], NE,
18308 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18309 DONE;
18310 })
18311
18312 (define_insn "xtest_1"
18313 [(set (reg:CCZ FLAGS_REG)
18314 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18315 "TARGET_RTM"
18316 "xtest"
18317 [(set_attr "type" "other")
18318 (set_attr "length" "3")])
18319
18320 (include "mmx.md")
18321 (include "sse.md")
18322 (include "sync.md")